diff -r 7791ceeea57b -r 04bd925b9069 src/ai/squirrel/squirrel.cpp --- a/src/ai/squirrel/squirrel.cpp Wed Mar 14 23:01:30 2007 +0000 +++ b/src/ai/squirrel/squirrel.cpp Thu Mar 15 00:01:33 2007 +0000 @@ -5,7 +5,6 @@ #include "squirrel.hpp" #include #include -#include #include "../../debug.h" #define SQUIRREL_CLASS @@ -16,48 +15,6 @@ #include "../core/ai_map.hpp" #include "../core/ai_town.hpp" -/** - * Here we handle errors that come from squirrel. - */ -static void Squirrel_CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column) -{ -#ifdef _SQ64 - printf("Error %s:%ld/%ld: %s\n", source, line, column, desc); -#else - printf("Error %s:%d/%d: %s\n", source, line, column, desc); -#endif -} - -/** - * Here we handle run-time errors that come from squirrel. - */ -static SQInteger Squirrel_RunError(HSQUIRRELVM vm) -{ - const SQChar *sErr = 0; - - if (sq_gettop(vm) >= 1) { - if (SQ_SUCCEEDED(sq_getstring(vm, -1, &sErr))) { - printf("%s\n", sErr); - } else { - printf("Unknown error\n"); - } - } - - return 0; -} - -/** - * Here we handle 'print' command within squirrel script. - */ -static void Squirrel_PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...) -{ - va_list arglist; - va_start(arglist, s); - vprintf(s, arglist); - va_end(arglist); - printf("\n"); -} - SQInteger Squirrel::SQDestructor(SQUserPointer p, SQInteger size) { return 1; @@ -71,52 +28,18 @@ SQInteger Squirrel::SQGetTick(HSQUIRRELVM vm) { - SQUserPointer ptr; + SQUserPointer self; - /* Find the 'self' pointer */ - if (SQ_FAILED(sq_getinstanceup(vm, 1, &ptr, 0))) { - DEBUG(ai, 0, "[squirrel] Failed to find the instance-pointer"); + if (!SquirrelCore::GetInstance(vm, &self)) { + DEBUG(ai, 0, "[squirrel] Failed to find instance pointer"); return SQ_ERROR; } /* Return the value */ - sq_pushinteger(vm, ((Squirrel *)ptr)->GetTick()); + sq_pushinteger(vm, ((Squirrel *)self)->GetTick()); return 1; } -bool Squirrel::SQCreateClass(const char *classname) -{ - int oldtop = sq_gettop(this->vm); - - /* First, find the class */ - sq_pushroottable(this->vm); - sq_pushstring(this->vm, classname, -1); - sq_get(this->vm, -2); - - /* Create the instance */ - if (SQ_FAILED(sq_createinstance(this->vm, -1))) { - DEBUG(ai, 0, "[squirrel] Failed to create instance for class '%s'", classname); - sq_settop(this->vm, oldtop); - return false; - } - - /* Find our instance */ - sq_getstackobj(this->vm, -1, &this->SQ_instance); - /* Add a reference to it, so it survives for ever */ - sq_addref(this->vm, &this->SQ_instance); - /* Store it in the class */ - sq_setinstanceup(this->vm, -1, this); - /* Make sure we get called when the AI is destroyed */ - sq_setreleasehook(this->vm, -1, &Squirrel::SQDestructor); - - /* Reset the top */ - sq_settop(this->vm, oldtop); - - DEBUG(ai, 1, "[squirrel] Created an instance of class '%s' with pointer '%p'", classname, this->SQ_instance._unVal.pUserPointer); - - return true; -} - SQInteger Squirrel::SQRegisterAI(HSQUIRRELVM vm) { const SQChar *classname = NULL; @@ -142,111 +65,56 @@ sq_setforeignptr(vm, NULL); /* Create the new class */ - if (!self->SQCreateClass(classname)) { + if (!self->core->CreateClassInstance(classname, self, &self->SQ_instance)) { return SQ_ERROR; } return 0; } -inline void Squirrel::SQAddMethod(const char *name, SQFUNCTION proc, uint nparam, const char *params) -{ - sq_pushstring(this->vm, name, -1); - sq_newclosure(this->vm, proc, 0); - sq_setparamscheck(this->vm, nparam, params); - sq_setnativeclosurename(this->vm, -1, name); - sq_createslot(this->vm, -3); -} - void Squirrel::RegisterClasses() { - SQInteger top = sq_gettop(this->vm); + HSQUIRRELVM vm = this->core->GetVM(); + SQInteger top = sq_gettop(vm); /* Store 'this' so we can find it back later on */ - sq_setforeignptr(this->vm, this); + sq_setforeignptr(vm, this); - /* Create AIController class (the 'main' of it all) */ - sq_pushroottable(this->vm); - sq_pushstring(this->vm, "AIController", -1); - sq_newclass(this->vm, SQFalse); + this->core->AddClassBegin("AIController"); /* Create a constructor, so we can assign the right 'this' */ - this->SQAddMethod("constructor", &Squirrel::SQConstructor, 1, "x"); + this->core->AddMethod("constructor", &Squirrel::SQConstructor, 1, "x"); /* Assign other functions as AIController won't be done via the normal way */ - this->SQAddMethod("GetTick", &Squirrel::SQGetTick, 1, "x"); + this->core->AddMethod("GetTick", &Squirrel::SQGetTick, 1, "x"); - /* Finally really create the class */ - sq_createslot(this->vm, -3); + this->core->AddClassEnd(); /* Register the 'RegisterAI()' function */ - sq_pushroottable(this->vm); - this->SQAddMethod("RegisterAI", &Squirrel::SQRegisterAI, 2, "ts"); + sq_pushroottable(vm); + this->core->AddMethod("RegisterAI", &Squirrel::SQRegisterAI, 2, "ts"); - SQAIBaseRegister(this->vm); - SQAICompanyRegister(this->vm); - SQAIMapRegister(this->vm); - SQAITownRegister(this->vm); + SQAIBaseRegister(vm); + SQAICompanyRegister(vm); + SQAIMapRegister(vm); + SQAITownRegister(vm); /* Reset top */ - sq_settop(this->vm, top); + sq_settop(vm, top); } -Squirrel::Squirrel(const char *script_dir) +Squirrel::Squirrel(const char *script) { - char filename[1024]; - - this->vm = sq_open(1024); - - /* Handle compile-errors ourself, so we can display it nicely */ - sq_setcompilererrorhandler(this->vm, Squirrel_CompileError); - sq_notifyallexceptions(this->vm, SQTrue); - /* Set a good print-function */ - sq_setprintfunc(this->vm, Squirrel_PrintFunc); - /* Handle runtime-errors ourself, so we can display it nicely */ - sq_newclosure(this->vm, &Squirrel_RunError, 0); - sq_seterrorhandler(this->vm); - - /* TODO -- This is ugly! */ - strcpy(filename, "ai/"); - strcat(filename, script_dir); - strcat(filename, PATHSEP); - strcat(filename, "main.nut"); - - DEBUG(ai, 1, "[squirrel] Starting AI with script in '%s'", filename); - - sq_pushroottable(this->vm); + this->core = new SquirrelCore(); this->RegisterClasses(); - - /* Load and run the script */ - if (SQ_FAILED(sqstd_dofile(this->vm, filename, SQFalse, SQTrue))) { - DEBUG(ai, 0, "[squirrel] Failed to compile '%s'", filename); - return; - } + this->core->LoadScript(script); } Squirrel::~Squirrel() { - /* Clean up the stuff */ - sq_pop(this->vm, 1); - sq_close(this->vm); + delete this->core; } /* virtual */ void Squirrel::GameLoop() { - /* Store the current top */ - int top = sq_gettop(this->vm); - /* Go to the instance-root */ - sq_pushobject(this->vm, this->SQ_instance); - /* Find the function-name inside the script */ - sq_pushstring(this->vm, "GameLoop", -1); - if (SQ_FAILED(sq_get(this->vm, -2))) { - DEBUG(ai, 0, "[squirrel] Could not find 'GameLoop' in the AIController class"); - sq_settop(this->vm, top); - return; - } - /* Call the method */ - sq_pushobject(this->vm, this->SQ_instance); - sq_call(this->vm, 1, 0, 0); - /* Reset the top */ - sq_settop(this->vm, top); + this->core->CallMethod(this->SQ_instance, "GameLoop"); }