• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "timer_manager.h"
17 
18 namespace OHOS {
19 namespace MMI {
AddTimer(int32_t intervalMs,int32_t repeatCount,std::function<void ()> callback)20 int32_t TimerManager::AddTimer(int32_t intervalMs, int32_t repeatCount, std::function<void()> callback)
21 {
22     return AddTimerInternal(intervalMs, repeatCount, callback);
23 }
24 
RemoveTimer(int32_t timerId)25 int32_t TimerManager::RemoveTimer(int32_t timerId)
26 {
27     return RemoveTimerInternal(timerId);
28 }
29 
ResetTimer(int32_t timerId)30 int32_t TimerManager::ResetTimer(int32_t timerId)
31 {
32     return ResetTimerInternal(timerId);
33 }
34 
IsExist(int32_t timerId)35 bool TimerManager::IsExist(int32_t timerId)
36 {
37     return IsExistInternal(timerId);
38 }
39 
CalcNextDelay()40 int32_t TimerManager::CalcNextDelay()
41 {
42     return CalcNextDelayInternal();
43 }
44 
ProcessTimers()45 void TimerManager::ProcessTimers()
46 {
47     ProcessTimersInternal();
48 }
49 
TakeNextTimerId()50 int32_t TimerManager::TakeNextTimerId()
51 {
52     uint64_t timerSlot = 0;
53     uint64_t one = 1;
54 
55     for (const auto &timer : timers_) {
56         timerSlot |= (one << timer->id);
57     }
58 
59     for (int32_t i = 0; i < MAX_TIMER_COUNT; i++) {
60         if ((timerSlot & (one << i)) == 0) {
61             return i;
62         }
63     }
64     return NONEXISTENT_ID;
65 }
66 
AddTimerInternal(int32_t intervalMs,int32_t repeatCount,std::function<void ()> callback)67 int32_t TimerManager::AddTimerInternal(int32_t intervalMs, int32_t repeatCount, std::function<void()> callback)
68 {
69     if (intervalMs < MIN_INTERVAL) {
70         intervalMs = MIN_INTERVAL;
71     } else if (intervalMs > MAX_INTERVAL) {
72         intervalMs = MAX_INTERVAL;
73     }
74     if (!callback) {
75         return NONEXISTENT_ID;
76     }
77     int32_t timerId = TakeNextTimerId();
78     if (timerId < 0) {
79         return NONEXISTENT_ID;
80     }
81     auto timer = std::make_unique<TimerItem>();
82     timer->id = timerId;
83     timer->intervalMs = intervalMs;
84     timer->repeatCount = repeatCount;
85     timer->callbackCount = 0;
86     timer->nextCallTime = GetMillisTime() + intervalMs;
87     timer->callback = callback;
88     InsertTimerInternal(timer);
89     return timerId;
90 }
91 
RemoveTimerInternal(int32_t timerId)92 int32_t TimerManager::RemoveTimerInternal(int32_t timerId)
93 {
94     for (auto it = timers_.begin(); it != timers_.end(); ++it) {
95         if ((*it)->id == timerId) {
96             timers_.erase(it);
97             return RET_OK;
98         }
99     }
100     return RET_ERR;
101 }
102 
ResetTimerInternal(int32_t timerId)103 int32_t TimerManager::ResetTimerInternal(int32_t timerId)
104 {
105     for (auto it = timers_.begin(); it != timers_.end(); ++it) {
106         if ((*it)->id == timerId) {
107             auto timer = std::move(*it);
108             timers_.erase(it);
109             auto nowTime = GetMillisTime();
110             timer->nextCallTime = nowTime + timer->intervalMs;
111             timer->callbackCount = 0;
112             InsertTimerInternal(timer);
113             return RET_OK;
114         }
115     }
116     return RET_ERR;
117 }
118 
IsExistInternal(int32_t timerId)119 bool TimerManager::IsExistInternal(int32_t timerId)
120 {
121     for (auto it = timers_.begin(); it != timers_.end(); ++it) {
122         if ((*it)->id == timerId) {
123             return true;
124         }
125     }
126     return false;
127 }
128 
InsertTimerInternal(std::unique_ptr<TimerItem> & timer)129 std::unique_ptr<TimerManager::TimerItem>& TimerManager::InsertTimerInternal(std::unique_ptr<TimerItem>& timer)
130 {
131     for (auto it = timers_.begin(); it != timers_.end(); ++it) {
132         if ((*it)->nextCallTime > timer->nextCallTime) {
133             return *(timers_.insert(it, std::move(timer)));
134         }
135     }
136     timers_.push_back(std::move(timer));
137     return *timers_.rbegin();
138 }
139 
CalcNextDelayInternal()140 int32_t TimerManager::CalcNextDelayInternal()
141 {
142     auto delay = MIN_DELAY;
143     auto nowTime = GetMillisTime();
144     for (const auto& timer : timers_) {
145         if (nowTime < timer->nextCallTime) {
146             delay = timer->nextCallTime - nowTime;
147             if (delay < MIN_DELAY) {
148                 delay = MIN_DELAY;
149                 break;
150             }
151         }
152     }
153     return delay;
154 }
155 
ProcessTimersInternal()156 void TimerManager::ProcessTimersInternal()
157 {
158     if (timers_.empty()) {
159         return;
160     }
161     auto nowTime = GetMillisTime();
162     for (;;) {
163         auto it = timers_.begin();
164         if (it == timers_.end()) {
165             break;
166         }
167         if ((*it)->nextCallTime > nowTime) {
168             break;
169         }
170         auto curTimer = std::move(*it);
171         timers_.erase(it);
172         ++curTimer->callbackCount;
173         if ((curTimer->repeatCount >= 1) && (curTimer->callbackCount >= curTimer->repeatCount)) {
174             curTimer->callback();
175             continue;
176         }
177         curTimer->nextCallTime = nowTime + curTimer->intervalMs;
178         const auto& timer = InsertTimerInternal(curTimer);
179         timer->callback();
180     }
181 }
182 } // namespace MMI
183 } // namespace OHOS
184