Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
5.8 KiB

  1. //====== Copyright (c), Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose: Provides a scheduled function manager that will bucket events into
  4. // time chunks and execute them as time elapses
  5. //
  6. //=============================================================================
  7. #ifndef SCHEDULEDFUNCTION_H
  8. #define SCHEDULEDFUNCTION_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. namespace GCSDK
  13. {
  14. //interface for events that can be scheduled to run on the GC base
  15. class IGCScheduledFunction
  16. {
  17. public:
  18. IGCScheduledFunction() : m_nAbsScheduleBucket( knInvalidBucket ) {}
  19. virtual ~IGCScheduledFunction();
  20. //called in response to our event time elapsing
  21. virtual void OnEvent() = 0;
  22. bool BIsScheduled() const { return m_nAbsScheduleBucket != IGCScheduledFunction::knInvalidBucket; }
  23. private:
  24. //the absolute bucket that we were scheduled in (or invalid). Used to enable deregistering
  25. friend class CScheduledFunctionMgr;
  26. uint32 m_nAbsScheduleBucket;
  27. uint32 m_nLLIndex;
  28. static const uint32 knInvalidBucket = ( uint32 )-1;
  29. };
  30. //utility for scheduling a global function
  31. class CGlobalScheduledFunction :
  32. public IGCScheduledFunction
  33. {
  34. public:
  35. CGlobalScheduledFunction();
  36. typedef void ( *func_t )();
  37. void ScheduleMS( func_t pfn, uint32 nDelayMS );
  38. void ScheduleSecond( func_t pfn, uint32 nDelaySecond );
  39. void ScheduleMinute( func_t pfn, uint32 nDelayMinute );
  40. void Cancel();
  41. virtual void OnEvent() OVERRIDE;
  42. private:
  43. func_t m_pfn;
  44. };
  45. //the same as the above, but automatically deletes the object once the event is fired
  46. class CGlobalScheduledFunctionAutoDelete :
  47. public CGlobalScheduledFunction
  48. {
  49. public:
  50. CGlobalScheduledFunctionAutoDelete() {}
  51. virtual void OnEvent() OVERRIDE
  52. {
  53. CGlobalScheduledFunction::OnEvent();
  54. delete this;
  55. }
  56. };
  57. //utility for scheduling a member function
  58. template< class T >
  59. class CScheduledFunction :
  60. public IGCScheduledFunction
  61. {
  62. public:
  63. CScheduledFunction() : m_pObj( NULL ), m_pfn( NULL ) {}
  64. typedef void ( T::*func_t )();
  65. void ScheduleMS( T* pObj, func_t pfn, uint32 nDelayMS )
  66. {
  67. m_pObj = pObj;
  68. m_pfn = pfn;
  69. GScheduledFunctionMgr().ScheduleMS( this, nDelayMS );
  70. }
  71. void ScheduleSecond( T* pObj, func_t pfn, uint32 nDelaySecond )
  72. {
  73. m_pObj = pObj;
  74. m_pfn = pfn;
  75. GScheduledFunctionMgr().ScheduleSecond( this, nDelaySecond );
  76. }
  77. void ScheduleMinute( T* pObj, func_t pfn, uint32 nDelayMinute )
  78. {
  79. m_pObj = pObj;
  80. m_pfn = pfn;
  81. GScheduledFunctionMgr().ScheduleMinute( this, nDelayMinute );
  82. }
  83. void Cancel()
  84. {
  85. GScheduledFunctionMgr().Cancel( this );
  86. }
  87. virtual void OnEvent() OVERRIDE
  88. {
  89. ( m_pObj->*m_pfn )();
  90. }
  91. private:
  92. T* m_pObj;
  93. func_t m_pfn;
  94. };
  95. //similar to the above, but auto deletes once the event is fired
  96. template< class T >
  97. class CScheduledFunctionAutoDelete :
  98. public CScheduledFunction< T >
  99. {
  100. public:
  101. typedef void ( T::*func_t )();
  102. CScheduledFunctionAutoDelete() {}
  103. CScheduledFunctionAutoDelete( T* pObj, func_t pfn, uint32 nDelayMS ) { Schedule( pObj, pfn, nDelayMS ); }
  104. virtual void OnEvent() OVERRIDE
  105. {
  106. CScheduledFunction< T >::OnEvent();
  107. delete this;
  108. }
  109. };
  110. class CScheduledFunctionMgr
  111. {
  112. public:
  113. CScheduledFunctionMgr();
  114. //called to initialize the starting time for the scheduled function manager. It doesn't need to be globally absolute, just relative to the time values provided
  115. //to the run function
  116. void InitStartingTime();
  117. //called to register a scheduled event for a certain period in the future, with the delay specified in milliseconds. This has resolution of an individual frame, and
  118. //will unregister from any previously registered time slot
  119. void ScheduleMS( IGCScheduledFunction* pEvent, uint32 nMSDelay );
  120. //similar to the above, but instead of having frame resolution, this has second level resolution, and should be used for low granularity tasks
  121. void ScheduleSecond( IGCScheduledFunction* pEvent, uint32 nSDelay );
  122. //similar to the above but has minute level resolution which should be used for very low resolution tasks
  123. void ScheduleMinute( IGCScheduledFunction* pEvent, uint32 nMinuteDelay );
  124. //deregisters a previously registered event
  125. void Cancel( IGCScheduledFunction* pEvent );
  126. //called to run registered functions
  127. void RunFunctions();
  128. private:
  129. //called internally by the other schedule functions to schedule the event at the specified resolution in our resolution array
  130. void InternalSchedule( uint32 nResolution, IGCScheduledFunction* pEvent, uint32 nMSDelay );
  131. //the list type that we store all of the entries in. We use a single list to avoid the overhead of so many lists
  132. typedef CUtlLinkedList< IGCScheduledFunction*, uint32 > TScheduleList;
  133. //all information tied to a specific resolution, including the time hash buckets, number of buckets, and which buckets it has executed
  134. class CScheduleBucket
  135. {
  136. public:
  137. CScheduleBucket();
  138. ~CScheduleBucket();
  139. void Init( TScheduleList& MasterList, uint32 nNumBuckets, uint32 nMicroSPerBucket );
  140. //maps a micro second time to a bucket time
  141. uint32 GetAbsScheduleBucketIndex( uint64 nMicroSTime ) const { return ( uint32 )( nMicroSTime / m_nMicroSPerBucket ); }
  142. //called to run registered functions
  143. void RunFunctions( TScheduleList& MasterList, uint64 nMicroSTime );
  144. //for each bucket, we insert a node into the master linked list, then our list runs from this node to the next empty node (or end) in the list
  145. uint32* m_pBuckets;
  146. //the number of buckets that we have
  147. uint32 m_nNumBuckets;
  148. //how many micro seconds each bucket represents
  149. uint32 m_nMicroSPerBucket;
  150. //the last bucket that we had executed
  151. uint32 m_nAbsLastScheduleBucket;
  152. };
  153. //the list of all of our entries. We store bucket starts within here, and then insert the events in between them
  154. TScheduleList m_ScheduleList;
  155. //the list of resolutions that we have
  156. CScheduleBucket m_Resolutions[ 3 ];
  157. };
  158. //global singleton access
  159. CScheduledFunctionMgr& GScheduledFunctionMgr();
  160. } //namespace GCSDK
  161. #endif