summaryrefslogtreecommitdiff
path: root/public/gcsdk/scheduledfunction.h
diff options
context:
space:
mode:
Diffstat (limited to 'public/gcsdk/scheduledfunction.h')
-rw-r--r--public/gcsdk/scheduledfunction.h205
1 files changed, 205 insertions, 0 deletions
diff --git a/public/gcsdk/scheduledfunction.h b/public/gcsdk/scheduledfunction.h
new file mode 100644
index 0000000..1522de7
--- /dev/null
+++ b/public/gcsdk/scheduledfunction.h
@@ -0,0 +1,205 @@
+//====== Copyright (c), Valve Corporation, All rights reserved. =======
+//
+// Purpose: Provides a scheduled function manager that will bucket events into
+// time chunks and execute them as time elapses
+//
+//=============================================================================
+
+#ifndef SCHEDULEDFUNCTION_H
+#define SCHEDULEDFUNCTION_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace GCSDK
+{
+
+//interface for events that can be scheduled to run on the GC base
+class IGCScheduledFunction
+{
+public:
+ IGCScheduledFunction() : m_nAbsScheduleBucket( knInvalidBucket ) {}
+ virtual ~IGCScheduledFunction();
+ //called in response to our event time elapsing
+ virtual void OnEvent() = 0;
+
+ bool BIsScheduled() const { return m_nAbsScheduleBucket != IGCScheduledFunction::knInvalidBucket; }
+
+private:
+ //the absolute bucket that we were scheduled in (or invalid). Used to enable deregistering
+ friend class CScheduledFunctionMgr;
+ uint32 m_nAbsScheduleBucket;
+ uint32 m_nLLIndex;
+ static const uint32 knInvalidBucket = ( uint32 )-1;
+};
+
+//utility for scheduling a global function
+class CGlobalScheduledFunction :
+ public IGCScheduledFunction
+{
+public:
+
+ CGlobalScheduledFunction();
+
+ typedef void ( *func_t )();
+
+ void ScheduleMS( func_t pfn, uint32 nDelayMS );
+ void ScheduleSecond( func_t pfn, uint32 nDelaySecond );
+ void ScheduleMinute( func_t pfn, uint32 nDelayMinute );
+ void Cancel();
+
+ virtual void OnEvent() OVERRIDE;
+
+private:
+ func_t m_pfn;
+};
+
+//the same as the above, but automatically deletes the object once the event is fired
+class CGlobalScheduledFunctionAutoDelete :
+ public CGlobalScheduledFunction
+{
+public:
+ CGlobalScheduledFunctionAutoDelete() {}
+
+ virtual void OnEvent() OVERRIDE
+ {
+ CGlobalScheduledFunction::OnEvent();
+ delete this;
+ }
+};
+
+//utility for scheduling a member function
+template< class T >
+class CScheduledFunction :
+ public IGCScheduledFunction
+{
+public:
+ CScheduledFunction() : m_pObj( NULL ), m_pfn( NULL ) {}
+
+ typedef void ( T::*func_t )();
+
+ void ScheduleMS( T* pObj, func_t pfn, uint32 nDelayMS )
+ {
+ m_pObj = pObj;
+ m_pfn = pfn;
+ GScheduledFunctionMgr().ScheduleMS( this, nDelayMS );
+ }
+
+ void ScheduleSecond( T* pObj, func_t pfn, uint32 nDelaySecond )
+ {
+ m_pObj = pObj;
+ m_pfn = pfn;
+ GScheduledFunctionMgr().ScheduleSecond( this, nDelaySecond );
+ }
+
+ void ScheduleMinute( T* pObj, func_t pfn, uint32 nDelayMinute )
+ {
+ m_pObj = pObj;
+ m_pfn = pfn;
+ GScheduledFunctionMgr().ScheduleMinute( this, nDelayMinute );
+ }
+
+
+ void Cancel()
+ {
+ GScheduledFunctionMgr().Cancel( this );
+ }
+
+ virtual void OnEvent() OVERRIDE
+ {
+ ( m_pObj->*m_pfn )();
+ }
+
+private:
+ T* m_pObj;
+ func_t m_pfn;
+};
+
+//similar to the above, but auto deletes once the event is fired
+template< class T >
+class CScheduledFunctionAutoDelete :
+ public CScheduledFunction< T >
+{
+public:
+ typedef void ( T::*func_t )();
+
+ CScheduledFunctionAutoDelete() {}
+ CScheduledFunctionAutoDelete( T* pObj, func_t pfn, uint32 nDelayMS ) { Schedule( pObj, pfn, nDelayMS ); }
+ virtual void OnEvent() OVERRIDE
+ {
+ CScheduledFunction< T >::OnEvent();
+ delete this;
+ }
+};
+
+
+class CScheduledFunctionMgr
+{
+public:
+
+ CScheduledFunctionMgr();
+
+ //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
+ //to the run function
+ void InitStartingTime();
+
+ //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
+ //will unregister from any previously registered time slot
+ void ScheduleMS( IGCScheduledFunction* pEvent, uint32 nMSDelay );
+ //similar to the above, but instead of having frame resolution, this has second level resolution, and should be used for low granularity tasks
+ void ScheduleSecond( IGCScheduledFunction* pEvent, uint32 nSDelay );
+ //similar to the above but has minute level resolution which should be used for very low resolution tasks
+ void ScheduleMinute( IGCScheduledFunction* pEvent, uint32 nMinuteDelay );
+
+ //deregisters a previously registered event
+ void Cancel( IGCScheduledFunction* pEvent );
+
+ //called to run registered functions
+ void RunFunctions();
+
+private:
+
+ //called internally by the other schedule functions to schedule the event at the specified resolution in our resolution array
+ void InternalSchedule( uint32 nResolution, IGCScheduledFunction* pEvent, uint32 nMSDelay );
+
+ //the list type that we store all of the entries in. We use a single list to avoid the overhead of so many lists
+ typedef CUtlLinkedList< IGCScheduledFunction*, uint32 > TScheduleList;
+
+ //all information tied to a specific resolution, including the time hash buckets, number of buckets, and which buckets it has executed
+ class CScheduleBucket
+ {
+ public:
+ CScheduleBucket();
+ ~CScheduleBucket();
+ void Init( TScheduleList& MasterList, uint32 nNumBuckets, uint32 nMicroSPerBucket );
+
+ //maps a micro second time to a bucket time
+ uint32 GetAbsScheduleBucketIndex( uint64 nMicroSTime ) const { return ( uint32 )( nMicroSTime / m_nMicroSPerBucket ); }
+
+ //called to run registered functions
+ void RunFunctions( TScheduleList& MasterList, uint64 nMicroSTime );
+
+ //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
+ uint32* m_pBuckets;
+ //the number of buckets that we have
+ uint32 m_nNumBuckets;
+ //how many micro seconds each bucket represents
+ uint32 m_nMicroSPerBucket;
+ //the last bucket that we had executed
+ uint32 m_nAbsLastScheduleBucket;
+ };
+
+ //the list of all of our entries. We store bucket starts within here, and then insert the events in between them
+ TScheduleList m_ScheduleList;
+
+ //the list of resolutions that we have
+ CScheduleBucket m_Resolutions[ 3 ];
+};
+
+//global singleton access
+CScheduledFunctionMgr& GScheduledFunctionMgr();
+
+
+} //namespace GCSDK
+
+#endif