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