📄 loadbalance.cpp
字号:
/*********************************************************************\
*
* Copyright Stormfront Studios, Inc. Confidential.
*
* This source code is proprietary and confidential under
* appropriate laws. No duplication is allowed without the
* express written permission of Stormfront Studios, Inc.
* All Rights Reserved.
*
*
* $Workfile: AIUpdate.cpp $
*
* $Modtime: 7/02/01 4:05p $
*
* $Author: Balexander $
*
*
* Description:
*
* This source file contains the AI update module class.
*
*
\*********************************************************************/
#include <stdio.h>
#include <float.h>
#include "LoadBalance.h"
///////////////////////////////////////////////////////////////////////
// The AI Update Module
ExecutionModule gAIExecutionModule;
///////////////////////////////////////////////////////////////////////
// AI Update Module Profiling
#ifdef _DEBUG
#define PROFILE_INIT(data) \
{ \
data.TotalTime = 0; \
data.MinTime = FLT_MAX; \
data.MaxTime = -FLT_MAX; \
data.Count = 0; \
data.Name = NULL; \
}
#define PROFILE_RELEASE(data) ((void)0)
#define PROFILE_START(data) // TBD - Record system ticks
#define PROFILE_END(data) \
{ \
float ExecTime = 0; /* Get system ticks */ \
data.TotalTime += ExecTime; \
if (ExecTime < data.MinTime) data.MinTime = ExecTime; \
if (ExecTime > data.MaxTime) data.MaxTime = ExecTime; \
data.Count++; \
}
#define PROFILE_GROUP_INIT(data) \
{ \
data.TotalTime = 0; \
data.MaxTime = -FLT_MAX; \
data.FrameCount = 0; \
data.LastFrame = ~0; \
data.LastFrameTotalTime = 0; \
}
#define PROFILE_GROUP_RELEASE(data) ((void)0)
#define PROFILE_GROUP_FRAME_START(data) \
{ \
data.FrameTaskCount = 0; \
}
#define PROFILE_GROUP_FRAME_END(data) ((void)0)
#define PROFILE_GROUP_START(data) \
{ \
if (data.LastFrame != gAIExecutionModule.GetFrames()) \
{ \
data.LastFrame = gAIExecutionModule.GetFrames(); \
data.LastFrameTotalTime = data.TotalTime; \
data.FrameCount++; \
} \
/* Record system ticks */ \
}
#define PROFILE_GROUP_END(data) \
{ \
float ExecTime = 0; /* Get system ticks */ \
data.TotalTime += ExecTime; \
data.FrameTaskCount++; \
ExecTime = data.TotalTime - data.LastFrameTotalTime; \
if (ExecTime > data.MaxTime) data.MaxTime = ExecTime; \
}
void PROFILE_INIT_MODULE( void )
{
// Add code here
}
void PROFILE_RELEASE_MODULE( void )
{
// Add code here
}
#else
#define PROFILE_INIT_MODULE() ((void)0)
#define PROFILE_RELEASE_MODULE() ((void)0)
#define PROFILE_INIT(data) ((void)0)
#define PROFILE_RELEASE(data) ((void)0)
#define PROFILE_START(data) ((void)0)
#define PROFILE_END(data) ((void)0)
#define PROFILE_GROUP_INIT(data) ((void)0)
#define PROFILE_GROUP_RELEASE(data) ((void)0)
#define PROFILE_GROUP_FRAME_START(data) ((void)0)
#define PROFILE_GROUP_FRAME_END(data) ((void)0)
#define PROFILE_GROUP_START(data) ((void)0)
#define PROFILE_GROUP_END(data) ((void)0)
#endif
///////////////////////////////////////////////////////////////////////
// AI update module class
//
// Construction
//
//
// This function handles AI update initialization.
//
bool ExecutionModule::Init( void )
{
mTime = 0;
mTicks = 0;
mFrames = 0;
mpScheduledTasks = NULL;
mpExecutingTask = NULL;
// Init profiling
PROFILE_INIT_MODULE();
PROFILE_INIT( GetProfileData() );
AI_UPDATE_SET_PROFILE_NAME( *this, "AI Update Module" );
return( true );
}
//
// This function handles AI update release.
//
bool ExecutionModule::Release( void )
{
// Clear Task schedule
while (mpScheduledTasks != NULL)
{
UnscheduleTask( mpScheduledTasks );
}
// Remove all groups
while (mpFirstGroup != NULL)
{
DetachGroup( mpFirstGroup );
}
PROFILE_RELEASE( GetProfileData() );
PROFILE_RELEASE_MODULE();
return( true );
}
//
// Update
//
void ExecutionModule::Update( unsigned long dt )
{
PROFILE_START( GetProfileData() );
if (dt)
{
float fdt = (float)dt/1000.0f;
mTime += fdt;
mTicks += dt;
mFrames++;
#ifdef _DEBUG
{
for (SchedulingGroup * group = mpFirstGroup; group != NULL; group = group->GetNext())
{
PROFILE_GROUP_FRAME_START( group->GetGroupProfileData() );
}
}
#endif
// Run all expired scheduled Tasks
while ( (mpScheduledTasks != NULL)
&& (mpScheduledTasks->GetTime() < mTime) )
{
// Remove Task from queue
mpExecutingTask = mpScheduledTasks;
mpScheduledTasks = mpScheduledTasks->mpScheduledNext;
mpExecutingTask->mScheduled = false;
SchedulingGroup * executingGroup = mpExecutingTask->GetGroup();
if (executingGroup != NULL)
{
PROFILE_GROUP_START( executingGroup->GetGroupProfileData() );
}
PROFILE_START( mpExecutingTask->GetProfileData() );
mpExecutingTask->Run( (mpExecutingTask->mLastTime != 0) ? (mTime - mpExecutingTask->mLastTime) : 0 );
PROFILE_END( mpExecutingTask->GetProfileData() );
if (executingGroup != NULL)
{
PROFILE_GROUP_END( executingGroup->GetGroupProfileData() );
}
// If the Task has not gone away, remove it from the schedule.
mpExecutingTask->mLastTime = mTime;
mpExecutingTask = NULL; // JIC
}
// Run all groups to rescedule Tasks.
for (SchedulingGroup * group = mpFirstGroup; group != NULL; group = group->GetNext())
{
PROFILE_START( group->GetProfileData() );
group->Schedule( this );
PROFILE_END( group->GetProfileData() );
PROFILE_GROUP_FRAME_END( group->GetProfileData() );
}
}
PROFILE_END( GetProfileData() );
}
//
// Attach/Detach groups
//
bool ExecutionModule::AttachGroup( SchedulingGroup * group )
{
for (SchedulingGroup * curGroup = mpFirstGroup; curGroup != NULL; curGroup = curGroup->mpNext)
{
if (curGroup == group)
{
// Already in the group.
return false;
}
}
// Add to front of list.
group->mpNext = mpFirstGroup;
mpFirstGroup = group;
return true;
}
bool ExecutionModule::DetachGroup( SchedulingGroup * group )
{
for (SchedulingGroup ** DelAt = &mpFirstGroup; *DelAt != NULL; DelAt = &((*DelAt)->mpNext))
{
if (*DelAt == group)
{
*DelAt = group->mpNext;
group->mpNext = NULL;
return true;
}
}
return false;
}
//
// Schedule a Task
//
bool ExecutionModule::ScheduleTask( Task * task )
{
// Insert sort the task by time.
if (task->IsScheduled())
{
return false;
}
for (Task ** AddAt = &mpScheduledTasks; *AddAt != NULL; AddAt = &((*AddAt)->mpScheduledNext))
{
if ((*AddAt)->GetTime() > task->GetTime())
{
break;
}
}
// Add at location found.
task->mpScheduledNext = *AddAt;
*AddAt = task;
task->mScheduled = true;
return true;
}
//
// Unschedule a previously scheduled Task
//
bool ExecutionModule::UnscheduleTask( Task * task )
{
if (!task->IsScheduled())
{
return false;
}
for (Task ** DelAt = &mpScheduledTasks; *DelAt != NULL; DelAt = &((*DelAt)->mpScheduledNext))
{
if (*DelAt == task)
{
*DelAt = task->mpScheduledNext;
task->mpScheduledNext = NULL;
task->mScheduled = false;
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////
// Scheduling Group Class
// initialization/release
bool SchedulingGroup::Init( void )
{
PROFILE_INIT( GetProfileData() );
PROFILE_GROUP_INIT( GetGroupProfileData() );
mpFirstTask = NULL;
mTaskCount = 0;
return true;
}
bool SchedulingGroup::Release( void )
{
gAIExecutionModule.DetachGroup( this );
while (mpFirstTask != NULL)
{
DetachTask( mpFirstTask );
}
PROFILE_GROUP_RELEASE( GetGroupProfileData() );
PROFILE_RELEASE( GetProfileData() );
return true;
}
bool SchedulingGroup::AttachTask( Task * task )
{
for (Task * curTask = mpFirstTask; curTask != NULL; curTask = curTask->mpGroupNext)
{
if (curTask == task)
{
// Already in the group.
return false;
}
}
// Add to front of list.
task->mpGroupNext = mpFirstTask;
mpFirstTask = task;
task->mpGroup = this;
mTaskCount++;
return true;
}
bool SchedulingGroup::DetachTask( Task * task )
{
for (Task ** DelAt = &mpFirstTask; *DelAt != NULL; DelAt = &((*DelAt)->mpGroupNext))
{
if (*DelAt == task)
{
*DelAt = task->mpGroupNext;
task->mpGroupNext = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -