📄 loadbalance.cpp
字号:
task->mpGroup = NULL;
mTaskCount--;
return true;
}
}
return false;
}
void SchedulingGroup::SetTaskTime( Task * task, float time )
{
task->mTime = time;
}
///////////////////////////////////////////////////////////////////////
// Task Class
bool Task::Init( void )
{
PROFILE_INIT( GetProfileData() );
mTime = 0;
mLastTime = 0;
mScheduled = false;
mpGroup = NULL;
mpGroupNext = NULL;
mpScheduledNext = NULL;
return true;
}
bool Task::Release( void )
{
if (mpGroup != NULL)
{
mpGroup->DetachTask( this );
}
gAIExecutionModule.UnscheduleTask( this );
PROFILE_RELEASE( GetProfileData() );
return true;
}
///////////////////////////////////////////////////////////////////////
// AI Update Every Frame
void EveryFrameGroup::Schedule( ExecutionModule * module )
{
// Schedule all Tasks, setting their fire times to 0.
// This will ensure that they are fired next Update module call.
for (Task * task = mpFirstTask; task != NULL; task = task->GetGroupNext())
{
if (!task->IsScheduled())
{
SetTaskTime( task, 0 );
module->ScheduleTask( task );
}
}
}
///////////////////////////////////////////////////////////////////////
// AI Update Count
bool CountGroup::Init( int count )
{
mCount = count;
mpCurrentTask = NULL;
return SchedulingGroup::Init();
}
bool CountGroup::Release( void )
{
mpCurrentTask = NULL;
return SchedulingGroup::Release();
}
bool CountGroup::DetachTask( Task * task )
{
// If we are detaching a
if (mpCurrentTask == task)
{
mpCurrentTask = mpCurrentTask->GetGroupNext();
if (mpCurrentTask == NULL)
{
mpCurrentTask = GetFirstTask();
}
}
return SchedulingGroup::DetachTask( task );
}
void CountGroup::Schedule( ExecutionModule * module )
{
if (GetFirstTask() != NULL)
{
if (mpCurrentTask == NULL)
{
// Initialize current Task
mpCurrentTask = GetFirstTask();
}
Task * start = mpCurrentTask;
int count = mCount;
while (count)
{
if (!mpCurrentTask->IsScheduled())
{
// NOt scheduled, so schedule it.
SetTaskTime( mpCurrentTask, 0 );
module->ScheduleTask( mpCurrentTask );
count--;
}
// Move to next Task.
mpCurrentTask = mpCurrentTask->GetGroupNext();
if (mpCurrentTask == NULL)
{
// Wrap around
mpCurrentTask = GetFirstTask();
}
if (mpCurrentTask == start)
{
// Back at start, so stop.
break;
}
}
}
}
///////////////////////////////////////////////////////////////////////
// AI Update Spread
bool SpreadGroup::Init( float period )
{
mPeriod = period;
mTime = 0;
return SchedulingGroup::Init();
}
bool SpreadGroup::AttachTask( Task * task )
{
if (SchedulingGroup::AttachTask( task ))
{
return true;
}
return false;
}
bool SpreadGroup::DetachTask( Task * task )
{
if (SchedulingGroup::DetachTask( task ))
{
return true;
}
return false;
}
void SpreadGroup::Schedule( ExecutionModule * module )
{
if (GetTaskCount() > 0)
{
float dt = mPeriod / GetTaskCount();
// Adjust time to make sure its past the current time.
mTime += (int((module->GetTime() - mTime) / dt) + 1) * dt;
for (Task * task = mpFirstTask; task != NULL; task = task->GetGroupNext())
{
if (!task->IsScheduled())
{
SetTaskTime( task, mTime );
module->ScheduleTask( task );
mTime += dt;
}
}
}
}
///////////////////////////////////////////////////////////////////////
// Timed Update Task
bool TimedTask::Init()
{
Reset();
return Task::Init();
}
//
// Reset all stats.
//
void TimedTask::Reset( void )
{
mLastTime = 0;
mTotalTime = 0;
mExecutionCount = 0;
}
//
// This Task will time the run of the Execute Task below.
//
void TimedTask::Run( float dt )
{
// Record system ticks
Execute( dt );
mLastTime = 0; // Get system ticks
mTotalTime += mLastTime;
mExecutionCount++;
}
///////////////////////////////////////////////////////////////////////
// AI Max Time Update
bool MaxTimeGroup::Init( float period )
{
mMaxTime = period;
mpCurrentTask = NULL;
return SchedulingGroup::Init();
}
bool MaxTimeGroup::Release( void )
{
mpCurrentTask = NULL;
return SchedulingGroup::Release();
}
bool MaxTimeGroup::AttachTask( TimedTask * task )
{
// Just call the protected version
return AttachTask( (Task *)task );
}
bool MaxTimeGroup::DetachTask( TimedTask * task )
{
// Just call the protected version
return DetachTask( (Task *)task );
}
bool MaxTimeGroup::AttachTask( Task * task )
{
return SchedulingGroup::AttachTask( task );
}
bool MaxTimeGroup::DetachTask( Task * task )
{
if (mpCurrentTask == task)
{
mpCurrentTask = mpCurrentTask->GetGroupNext();
if (mpCurrentTask == NULL)
{
mpCurrentTask = GetFirstTask();
}
}
return SchedulingGroup::DetachTask( task );
}
void MaxTimeGroup::Schedule( ExecutionModule * module )
{
if (GetFirstTask() != NULL)
{
float ScheduledTime = 0;
int ScheduleCount = 0;
if (mpCurrentTask == NULL)
{
// Initialize current Task
mpCurrentTask = GetFirstTask();
}
Task * start = mpCurrentTask;
while (ScheduledTime < mMaxTime)
{
if (!mpCurrentTask->IsScheduled())
{
// Not scheduled, so schedule it.
TimedTask * timedTask = (TimedTask *)mpCurrentTask;
float NewTotal = ScheduledTime + timedTask->GetLastExecutionTime();
if ( (ScheduledTime < mMaxTime) // We do not exceed the time limit.
|| (ScheduleCount == 0) ) // It's the only thing to schedule.
{
SetTaskTime( mpCurrentTask, 0 );
module->ScheduleTask( mpCurrentTask );
ScheduledTime = NewTotal;
ScheduleCount++;
}
}
// Move to next Task.
mpCurrentTask = mpCurrentTask->GetGroupNext();
if (mpCurrentTask == NULL)
{
// Wrap around
mpCurrentTask = GetFirstTask();
}
if (mpCurrentTask == start)
{
// Back at start, so stop.
break;
}
}
}
}
///////////////////////////////////////////////////////////////////////
// Variable Delay Task
bool VarDelayTask::Init()
{
mDelay = 1.0f / 4.0f; // Default delay of 1/4 of a second.
return Task::Init();
}
///////////////////////////////////////////////////////////////////////
// AI Variable Delay Update Group
bool VarDelayGroup::Init( void )
{
mTime = 0;
return SchedulingGroup::Init();
}
bool VarDelayGroup::AttachTask( VarDelayTask * task )
{
// Just call the protected version
return AttachTask( (Task *)task );
}
bool VarDelayGroup::DetachTask( VarDelayTask * task )
{
// Just call the protected version
return DetachTask( (Task *)task );
}
bool VarDelayGroup::AttachTask( Task * task )
{
return SchedulingGroup::AttachTask( task );
}
bool VarDelayGroup::DetachTask( Task * task )
{
return SchedulingGroup::DetachTask( task );
}
void VarDelayGroup::Schedule( ExecutionModule * module )
{
if (mpFirstTask != NULL)
{
const float dt = 1.0f / 30.0f;
// Adjust time to make sure its past the current time.
mTime += (int((module->GetTime() - mTime) / dt) + 1) * dt;
for (Task * task = mpFirstTask; task != NULL; task = task->GetGroupNext())
{
if (!task->IsScheduled())
{
if (task->GetTime() == 0)
{
// First time the task is scheduled.
// In order to attempt to prevent tasks from executing all on
// the same frame, use the mTime to stagger the tasks
SetTaskTime( task, mTime );
mTime += dt;
}
else
{
// Task has been schedule before, use task delay to
// reschedule.
VarDelayTask * DelayTask = (VarDelayTask *)task;
float NewTime = task->GetTime();
NewTime += (int((module->GetTime() - task->GetTime()) / DelayTask->GetDelay()) + 1) * DelayTask->GetDelay();
SetTaskTime( task, NewTime );
}
module->ScheduleTask( task );
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -