--- 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 <sqstdio.h>
#include <sqstdaux.h>
-#include <stdarg.h>
#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");
}