Stroika Library 3.0d18
 
Loading...
Searching...
No Matches
IdleManager.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
6#include <algorithm>
7
9
10#include "IdleManager.h"
11
12using namespace Stroika::Foundation;
13using namespace Stroika::Frameworks;
14using namespace Stroika::Frameworks::Led;
15
16/*
17 ********************************************************************************
18 ************************************ Idler *************************************
19 ********************************************************************************
20 */
21void Idler::SpendIdleTime ()
22{
23}
24
25/*
26 ********************************************************************************
27 ******************************* EnterIdler *************************************
28 ********************************************************************************
29 */
30void EnterIdler::OnEnterIdle ()
31{
32}
33
34/*
35 ********************************************************************************
36 ********************************** IdleManager *********************************
37 ********************************************************************************
38 */
39
40void IdleManager::AddIdler (Idler* idler)
41{
42 RequireNotNull (idler);
43 Require (fIdlers.find (idler) == fIdlers.end ());
44 IdlerInfo idlerInfo;
45 fIdlers.insert (map<Idler*, IdlerInfo>::value_type (idler, idlerInfo));
46}
47
48void IdleManager::RemoveIdler (Idler* idler)
49{
50 RequireNotNull (idler);
51 map<Idler*, IdlerInfo>::iterator i = fIdlers.find (idler);
52#if qBCCStaticVCLDTORLibBug
53 {
54 if (i == fIdlers.end ()) {
55 return;
56 }
57 }
58#endif
59 Require (i != fIdlers.end ());
60 Assert (i->first == idler);
61 fIdlers.erase (i);
62}
63
64void IdleManager::AddEnterIdler (EnterIdler* enterIdler)
65{
66 RequireNotNull (enterIdler);
67 Require (find (fEnterIdlers.begin (), fEnterIdlers.end (), enterIdler) == fEnterIdlers.end ());
68 fEnterIdlers.push_back (enterIdler);
69 UpdateIdleMgrImplState ();
70}
71
72void IdleManager::RemoveEnterIdler (EnterIdler* enterIdler)
73{
74 RequireNotNull (enterIdler);
75 vector<EnterIdler*>::iterator i = find (fEnterIdlers.begin (), fEnterIdlers.end (), enterIdler);
76 Require (i != fEnterIdlers.end ());
77 Assert (*i == enterIdler);
78 fEnterIdlers.erase (i);
79 UpdateIdleMgrImplState ();
80}
81
82Time::DurationSeconds IdleManager::GetIdlerFrequncy (Idler* idler)
83{
84 RequireNotNull (idler);
85 map<Idler*, IdlerInfo>::iterator i = fIdlers.find (idler);
86 Require (i != fIdlers.end ());
87 Assert (i->first == idler);
88 return i->second.fIdlerFrequency;
89}
90
91void IdleManager::SetIdlerFrequncy (Idler* idler, Time::DurationSeconds idlerFrequency)
92{
93 RequireNotNull (idler);
94 map<Idler*, IdlerInfo>::iterator i = fIdlers.find (idler);
95 Require (i != fIdlers.end ());
96 Assert (i->first == idler);
97 if (i->second.fIdlerFrequency != idlerFrequency) {
98 i->second.fIdlerFrequency = idlerFrequency;
99 UpdateIdleMgrImplState ();
100 }
101}
102
103void IdleManager::UpdateIdleMgrImplState ()
104{
105 if (fIdleManagerOSImpl != nullptr) {
106 Time::DurationSeconds idleFreq = kNeverCallIdler;
107 for (auto i = fIdlers.begin (); i != fIdlers.end (); ++i) {
108 idleFreq = min (idleFreq, i->second.fIdlerFrequency);
109 }
110 if (not fEnterIdlers.empty ()) {
111 const Time::DurationSeconds kMinEnterIdleFreqCheck = 0.5s;
112 idleFreq = min (idleFreq, kMinEnterIdleFreqCheck);
113 }
114 bool shouldNeedIdleMgr = (idleFreq != kNeverCallIdler);
115 if (shouldNeedIdleMgr != fNeedMgrIdleCalls or (shouldNeedIdleMgr and idleFreq != fIdleManagerOSImpl->GetSuggestedFrequency ())) {
116 fNeedMgrIdleCalls = shouldNeedIdleMgr;
117 if (fNeedMgrIdleCalls) {
118 fIdleManagerOSImpl->SetSuggestedFrequency (idleFreq);
119 fIdleManagerOSImpl->StartSpendTimeCalls ();
120 }
121 else {
122 fIdleManagerOSImpl->TerminateSpendTimeCalls ();
123 }
124 }
125 }
126}
127
128void IdleManager::CallSpendTime ()
129{
130 SetInIdleMode (true); // not SURE this is the best place to call this - maybe SB called from OSREP only???
131 Foundation::Time::TimePointSeconds now = Time::GetTickCount ();
132 for (auto i = fIdlers.begin (); i != fIdlers.end (); ++i) {
133 // only call SpendTime if its been requested
134 if (i->second.fLastCalledAt + i->second.fIdlerFrequency <= now) {
135 Idler* idler = i->first;
136 idler->SpendIdleTime ();
137 now = Time::GetTickCount (); // update 'now' since we could have spent alot of time in 'SpendIdleTime'
138 i->second.fLastCalledAt = now;
139 }
140 }
141}
142
143void IdleManager::CallEnterIdle ()
144{
145 for (auto i = fEnterIdlers.begin (); i != fEnterIdlers.end (); ++i) {
146 EnterIdler* enterIdler = *i;
147 AssertNotNull (enterIdler);
148 enterIdler->OnEnterIdle ();
149 }
150}
151
152void IdleManager::SetIdleManagerOSImpl (IdleManagerOSImpl* impl)
153{
154 // If they are just setting the IMPL to nullptr and sThe is nullptr, then don't bother
155 // creating it (cuz at destruction time - these destructors could get done in any order,
156 // and forcing a create here could create an artificail memory block left over that looks
157 // to the memory leak detector - like a memory leak.
158 if (impl == nullptr) {
159 Get ().fIdleManagerOSImpl = nullptr;
160 }
161 else {
162 Get ().fIdleManagerOSImpl = impl;
163 }
164}
165
166/*
167 ********************************************************************************
168 ************************** IdleManager::IdleManagerOSImpl **********************
169 ********************************************************************************
170 */
171void IdleManager::IdleManagerOSImpl::CallSpendTime ()
172{
173 IdleManager::Get ().CallSpendTime ();
174}
#define AssertNotNull(p)
Definition Assertions.h:333
#define RequireNotNull(p)
Definition Assertions.h:347
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
Definition Realtime.h:82
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Definition Realtime.h:57