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 -> TimeValue
90 return system_clock::now();
94 auto isTimeout (
const TimeValue&, uInt64) -> 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 -> FTimerList*
118 return globalTimerList().get();
122 template <
typename CallbackT>
123 auto processTimerEvent (CallbackT) -> uInt;
127 static auto globalTimerList() ->
const FTimerListUniquePtr&;
135 auto getNextId() -> int;
139 template <
typename ObjectT>
144 const auto& now = getCurrentTime();
149 const auto diff = now - time;
150 const auto& diff_usec = uInt64(duration_cast<microseconds>(diff).count());
151 return diff_usec > timeout;
155 template <
typename ObjectT>
161 std::lock_guard<std::shared_timed_mutex> lock_guard(internal::timer_var::mutex);
162 auto& timer_list = globalTimerList();
163 int id = getNextId();
164 const auto time_interval = milliseconds(interval);
165 const auto timeout = getCurrentTime() + time_interval;
166 FTimerData timedata{ id, time_interval, timeout,
object };
169 timer_list->insert( std::lower_bound( timer_list->cbegin()
172 , [] (
const auto& a,
const auto& b)
174 return a.timeout < b.timeout;
182 template <
typename ObjectT>
190 std::lock_guard<std::shared_timed_mutex> lock_guard(internal::timer_var::mutex);
191 auto& timer_list = globalTimerList();
193 if ( ! timer_list || timer_list->empty() )
196 auto iter = std::find_if ( timer_list->cbegin()
198 , [id] (
const auto& timer)
200 return timer.id == id;
204 if ( iter == timer_list->cend() )
207 timer_list->erase(iter);
212 template <
typename ObjectT>
217 std::lock_guard<std::shared_timed_mutex> lock_guard(internal::timer_var::mutex);
218 auto& timer_list = globalTimerList();
220 if ( ! timer_list || timer_list->empty() )
223 timer_list->erase ( std::remove_if( timer_list->begin()
225 , [&object] (
const auto& timer)
227 return timer.object == object;
230 , timer_list->end() );
235 template <
typename ObjectT>
240 std::lock_guard<std::shared_timed_mutex> lock_guard(internal::timer_var::mutex);
241 auto& timer_list = globalTimerList();
243 if ( ! timer_list || timer_list->empty() )
247 timer_list->shrink_to_fit();
253 template <
typename ObjectT>
254 template <
typename CallbackT>
258 std::shared_lock<std::shared_timed_mutex> lock ( internal::timer_var::mutex
261 if ( ! lock.try_lock() )
264 auto& timer_list = globalTimerList();
266 if ( ! timer_list || timer_list->empty() )
269 const auto& currentTime = getCurrentTime();
271 for (
auto&& timer : *timer_list)
275 || currentTime < timer.timeout )
278 timer.timeout += timer.interval;
280 if ( timer.timeout < currentTime )
281 timer.timeout = currentTime + timer.interval;
283 if ( timer.interval > microseconds(0) )
288 callback (timer.object, &t_ev);
297 template <
typename ObjectT>
300 static const auto& timer_list = std::make_unique<FTimerList>();
324 inline virtual auto getClassName()
const ->
FString 326 return "FObjectTimer";
329 static inline auto getCurrentTime() -> TimeValue
331 return timer->getCurrentTime();
335 static auto isTimeout (
const TimeValue& time, uInt64 timeout) ->
bool 337 return timer->isTimeout(time, timeout);
341 auto addTimer (
int interval) ->
int 343 return timer->addTimer(selfPointer<FObject*>(), interval);
346 auto delTimer (
int id)
const ->
bool 348 return timer->delTimer(
id);
351 auto delOwnTimers()
const ->
bool 353 return timer->delOwnTimers(selfPointer<const FObject*>());
356 auto delAllTimers()
const ->
bool 358 return timer->delAllTimers();
362 auto getTimerList()
const -> FTimer<FObject>::FTimerList*
364 return timer->globalTimerList().get();
368 auto processTimerEvent() -> uInt
370 return timer->processTimerEvent ( [
this] (
FObject* receiver,
FEvent* event)
372 performTimerAction(receiver, event);
381 template <
typename T>
382 inline auto selfPointer() -> T
387 template <
typename T>
388 inline auto selfPointer()
const -> T
Definition: class_template.cpp:25