mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-12 19:59:09 +00:00
1
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user