35 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) 36 #error "Only <final/final.h> can be included directly." 42 #include <shared_mutex> 45 #include "final/fevent.h" 46 #include "final/util/fstring.h" 56 static std::shared_timed_mutex mutex;
61 using std::chrono::duration_cast;
62 using std::chrono::seconds;
63 using std::chrono::milliseconds;
64 using std::chrono::microseconds;
65 using std::chrono::system_clock;
66 using std::chrono::time_point;
75 template <
typename ObjectT>
80 virtual ~
FTimer() =
default;
83 inline virtual auto getClassName()
const ->
FString 88 inline auto getCurrentTime()
const noexcept -> TimeValue
90 return system_clock::now();
94 auto isTimeout (
const TimeValue&, uInt64)
const noexcept -> bool;
97 auto addTimer (ObjectT*,
int) -> int;
98 auto delTimer (
int)
const -> bool;
99 auto delOwnTimers (
const ObjectT*)
const -> bool;
100 auto delAllTimers()
const -> bool;
106 milliseconds interval;
112 using FTimerList = std::vector<FTimerData>;
113 using FTimerListUniquePtr = std::unique_ptr<FTimerList>;
116 auto getTimerList()
const noexcept -> FTimerList*
118 return globalTimerList().get();
122 template <
typename CallbackT>
123 auto processTimerEvent (CallbackT) -> uInt;
127 static auto globalTimerList() noexcept ->
const FTimerListUniquePtr&;
135 auto getNextId() -> int;
139 template <
typename ObjectT>
141 , uInt64 timeout_us )
const noexcept ->
bool 145 const auto now = getCurrentTime();
150 const auto diff = now - time;
151 const auto diff_us = uInt64(duration_cast<microseconds>(diff).count());
152 return diff_us > timeout_us;
156 template <
typename ObjectT>
162 const std::lock_guard<std::shared_timed_mutex> lock_guard(internal::timer_var::mutex);
163 auto& timer_list = globalTimerList();
164 const int id = getNextId();
165 const auto time_interval = milliseconds(interval);
166 const auto timeout = getCurrentTime() + time_interval;
167 const FTimerData timedata{ id, time_interval, timeout,
object };
170 timer_list->insert( std::lower_bound( timer_list->cbegin()
173 , [] (
const auto& a,
const auto& b) noexcept
175 return a.timeout < b.timeout;
183 template <
typename ObjectT>
191 const std::lock_guard<std::shared_timed_mutex> lock_guard(internal::timer_var::mutex);
192 const auto& timer_list = globalTimerList();
194 if ( ! timer_list || timer_list->empty() )
197 const auto iter = std::find_if ( timer_list->cbegin()
199 , [id] (
const auto& timer) noexcept
201 return timer.id == id;
205 if ( iter == timer_list->cend() )
208 timer_list->erase(iter);
213 template <
typename ObjectT>
218 const std::lock_guard<std::shared_timed_mutex> lock_guard(internal::timer_var::mutex);
219 const auto& timer_list = globalTimerList();
221 if ( ! timer_list || timer_list->empty() )
224 timer_list->erase ( std::remove_if( timer_list->begin()
226 , [object] (
const auto& timer) noexcept
228 return timer.object == object;
231 , timer_list->end() );
236 template <
typename ObjectT>
241 const std::lock_guard<std::shared_timed_mutex> lock_guard(internal::timer_var::mutex);
242 const auto& timer_list = globalTimerList();
244 if ( ! timer_list || timer_list->empty() )
248 timer_list->shrink_to_fit();
254 template <
typename ObjectT>
255 template <
typename CallbackT>
259 std::shared_lock<std::shared_timed_mutex> lock ( internal::timer_var::mutex
262 if ( ! lock.try_lock() )
265 const auto& timer_list = globalTimerList();
267 if ( ! timer_list || timer_list->empty() )
270 const auto currentTime = getCurrentTime();
272 for (
auto& timer : *timer_list)
276 || currentTime < timer.timeout )
279 timer.timeout += timer.interval;
281 if ( timer.timeout < currentTime )
282 timer.timeout = currentTime + timer.interval;
284 if ( timer.interval > microseconds(0) )
289 callback (timer.object, &t_ev);
298 template <
typename ObjectT>
301 static const auto& timer_list = std::make_unique<FTimerList>();
325 inline virtual auto getClassName()
const ->
FString 327 return "FObjectTimer";
330 static inline auto getCurrentTime() noexcept -> TimeValue
332 return timer->getCurrentTime();
336 static auto isTimeout (
const TimeValue& time, uInt64 timeout) noexcept ->
bool 338 return timer->isTimeout(time, timeout);
342 auto addTimer (
int interval) ->
int 344 return timer->addTimer(selfPointer<FObject*>(), interval);
347 auto delTimer (
int id)
const ->
bool 349 return timer->delTimer(
id);
352 auto delOwnTimers()
const ->
bool 354 return timer->delOwnTimers(selfPointer<const FObject*>());
357 auto delAllTimers()
const ->
bool 359 return timer->delAllTimers();
363 auto getTimerList()
const noexcept -> FTimer<FObject>::FTimerList*
365 return timer->globalTimerList().get();
369 auto processTimerEvent() -> uInt
371 return timer->processTimerEvent ( [
this] (
FObject* receiver,
FEvent* event)
373 performTimerAction(receiver, event);
382 template <
typename T>
383 inline auto selfPointer() -> T
388 template <
typename T>
389 inline auto selfPointer()
const noexcept -> T
Definition: class_template.cpp:25