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
205 lines
5.8 KiB
//====== 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
|
|
|