cobengine.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 231 行
CPP
231 行
#include "StdAfx.h"
#include "CobEngine.h"
#include "CobThread.h"
#include "CobInstance.h"
#include "CobFile.h"
#include "LogOutput.h"
#include "FileSystem/FileHandler.h"
#include "Platform/errorhandler.h"
#include "mmgr.h"
#ifndef _CONSOLE
#include "TimeProfiler.h"
#endif
#ifdef _CONSOLE
#define START_TIME_PROFILE(a) {}
#define END_TIME_PROFILE(a) {}
#define SCOPED_TIMER(a) {}
#endif
CCobEngine GCobEngine;
int GCurrentTime;
CCobEngine::CCobEngine(void) :
curThread(NULL)
{
GCurrentTime = 0;
}
CCobEngine::~CCobEngine(void)
{
//Should delete all things that the scheduler knows
for (list<CCobThread *>::iterator i = running.begin(); i != running.end(); ++i) {
delete *i;
}
for (list<CCobThread *>::iterator i = wantToRun.begin(); i != wantToRun.end(); ++i) {
delete *i;
}
while (sleeping.size() > 0) {
CCobThread *tmp;
tmp = sleeping.top();
sleeping.pop();
delete tmp;
}
//Free all cobfiles
for (map<string, CCobFile *>::iterator i = cobFiles.begin(); i != cobFiles.end(); ++i) {
delete i->second;
}
}
//A thread wants to continue running at a later time, and adds itself to the scheduler
void CCobEngine::AddThread(CCobThread *thread)
{
switch (thread->state) {
case CCobThread::Run:
wantToRun.push_front(thread);
break;
case CCobThread::Sleep:
sleeping.push(thread);
break;
default:
logOutput.Print("CobError: thread added to scheduler with unknown state (%d)", thread->state);
break;
}
}
void CCobEngine::AddInstance(CCobInstance *instance)
{
// Error checking
/* int found = 0;
for (list<CCobInstance *>::iterator i = animating.begin(); i != animating.end(); ++i) {
if (*i == instance)
found++;
}
if (found > 0)
logOutput.Print("Warning: Addinstance already found %d", found); */
animating.push_front(instance);
}
void CCobEngine::RemoveInstance(CCobInstance *instance)
{
// Error checking
/* int found = 0;
for (list<CCobInstance *>::iterator i = animating.begin(); i != animating.end(); ++i) {
if (*i == instance)
found++;
}
if (found > 1)
logOutput.Print("Warning: Removeinstance found duplicates %d", found); */
//This is slow. would be better if instance was a hashlist perhaps
animating.remove(instance);
}
void CCobEngine::Tick(int deltaTime)
{
SCOPED_TIMER("Scripts");
GCurrentTime += deltaTime;
#if COB_DEBUG > 0
logOutput.Print("----");
#endif
//Advance all running threads
for (list<CCobThread *>::iterator i = running.begin(); i != running.end(); ++i) {
//logOutput.Print("Now 1running %d: %s", GCurrentTime, (*i)->GetName().c_str());
#ifdef _CONSOLE
printf("----\n");
#endif
int res = (*i)->Tick(deltaTime);
(*i)->CommitAnims(deltaTime);
if (res == -1) {
delete *i;
}
}
//A thread can never go from running->running, so clear the list
//note: if preemption was to be added, this would no longer hold
//however, ta scripts can not run preemptively anyway since there isn't any synchronization methods available
running.clear();
//The threads that just ran may have added new threads that should run next tick
for (list<CCobThread *>::iterator i = wantToRun.begin(); i != wantToRun.end(); ++i) {
running.push_front(*i);
}
wantToRun.clear();
//Check on the sleeping threads
if (sleeping.size() > 0) {
CCobThread *cur = sleeping.top();
while ((cur != NULL) && (cur->GetWakeTime() < GCurrentTime)) {
// Start with removing the executing thread from the queue
sleeping.pop();
//Run forward again. This can quite possibly readd the thread to the sleeping array again
//But it will not interfere since it is guaranteed to sleep > 0 ms
//logOutput.Print("Now 2running %d: %s", GCurrentTime, cur->GetName().c_str());
#ifdef _CONSOLE
printf("+++\n");
#endif
if (cur->state == CCobThread::Sleep) {
cur->state = CCobThread::Run;
int res = cur->Tick(deltaTime);
cur->CommitAnims(deltaTime);
if (res == -1)
delete cur;
} else if (cur->state == CCobThread::Dead) {
delete cur;
} else {
logOutput.Print("CobError: Sleeping thread strange state %d", cur->state);
}
if (sleeping.size() > 0)
cur = sleeping.top();
else
cur = NULL;
}
}
//Tick all instances that have registered themselves as animating
list<CCobInstance *>::iterator it = animating.begin();
list<CCobInstance *>::iterator curit;
while (it != animating.end()) {
curit = it++;
if ((*curit)->Tick(deltaTime) == -1)
animating.erase(curit);
}
}
// Threads call this when they start executing in Tick
void CCobEngine::SetCurThread(CCobThread *cur)
{
curThread = cur;
}
void CCobEngine::ShowScriptError(const string& msg)
{
if (curThread)
curThread->ShowError(msg);
else
logOutput.Print("ScriptError: %s outside script execution", msg.c_str());
}
CCobFile& CCobEngine::GetCobFile(const string& name)
{
//Already known?
map<string, CCobFile *>::iterator i;
if ((i = cobFiles.find(name)) != cobFiles.end()) {
return *(i->second);
}
CFileHandler f(name);
if (!f.FileExists()) {
handleerror(0,"No cob-file",name.c_str(),0);
//Need to return something maybe.. this is pretty fatal though
}
CCobFile *cf = SAFE_NEW CCobFile(f, name);
cobFiles[name] = cf;
return *cf;
}
CCobFile& CCobEngine::ReloadCobFile(const string& name)
{
map<string, CCobFile *>::iterator it = cobFiles.find(name);
if (it == cobFiles.end()) {
return GetCobFile(name);
}
delete it->second;
cobFiles.erase(it);
return GetCobFile(name);
}
const CCobFile* CCobEngine::GetScriptAddr(const string& name) const
{
map<string, CCobFile *>::const_iterator it = cobFiles.find(name);
if (it != cobFiles.end()) {
return it->second;
}
return NULL;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?