mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 06:36:54 +00:00
206 lines
5.8 KiB
C++
206 lines
5.8 KiB
C++
//====== 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
|