--- a/source.list Thu Mar 15 19:26:11 2007 +0000
+++ b/source.list Thu Mar 15 19:33:07 2007 +0000
@@ -67,6 +67,7 @@
station.cpp
string.cpp
strings.cpp
+squirrel.cpp
texteff.cpp
tgp.cpp
thread.cpp
@@ -160,6 +161,7 @@
saveload.h
screenshot.h
sound/sdl_s.h
+squirrel.hpp
video/sdl_v.h
settings.h
signs.h
@@ -293,8 +295,6 @@
# AIs
ai/squirrel/convert.cpp
ai/squirrel/convert.hpp
-ai/squirrel/engine.cpp
-ai/squirrel/engine.hpp
ai/squirrel/squirrel.cpp
ai/squirrel/squirrel.hpp
ai/squirrel/squirrel_class.hpp
--- a/src/ai/core/ai_base.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/core/ai_base.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -40,7 +40,7 @@
};
#ifdef SQUIRREL_CLASS
-void SQAIBaseRegister(SquirrelEngine *engine) {
+void SQAIBaseRegister(Squirrel *engine) {
DefSQClass <AIBase> SQAIBase("AIBase");
SQAIBase.PreRegister(engine);
SQAIBase.AddConstructor(engine);
--- a/src/ai/core/ai_cargo.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/core/ai_cargo.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -36,7 +36,7 @@
};
#ifdef SQUIRREL_CLASS
-void SQAICargoRegister(SquirrelEngine *engine) {
+void SQAICargoRegister(Squirrel *engine) {
DefSQClass <AICargo> SQAICargo("AICargo");
SQAICargo.PreRegister(engine);
SQAICargo.AddConstructor(engine);
--- a/src/ai/core/ai_company.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/core/ai_company.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -72,7 +72,7 @@
};
#ifdef SQUIRREL_CLASS
-void SQAICompanyRegister(SquirrelEngine *engine) {
+void SQAICompanyRegister(Squirrel *engine) {
DefSQClass <AICompany> SQAICompany("AICompany");
SQAICompany.PreRegister(engine);
SQAICompany.AddConstructor(engine);
--- a/src/ai/core/ai_controller.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/core/ai_controller.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -37,7 +37,7 @@
#endif /* AI_CONTROLLER_HPP */
#ifdef SQUIRREL_CLASS
-void SQAIControllerRegister(SquirrelEngine *engine) {
+void SQAIControllerRegister(Squirrel *engine) {
DefSQClass <AIControllerSquirrel> SQAIController("AIController");
SQAIController.PreRegister(engine);
SQAIController.DefSQFunction(engine, &AIControllerSquirrel::GetTick, "GetTick");
--- a/src/ai/core/ai_industry.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/core/ai_industry.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -50,7 +50,7 @@
};
#ifdef SQUIRREL_CLASS
-void SQAIIndustryRegister(SquirrelEngine *engine) {
+void SQAIIndustryRegister(Squirrel *engine) {
DefSQClass <AIIndustry> SQAIIndustry("AIIndustry");
SQAIIndustry.PreRegister(engine);
SQAIIndustry.AddConstructor(engine);
--- a/src/ai/core/ai_map.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/core/ai_map.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -57,7 +57,7 @@
};
#ifdef SQUIRREL_CLASS
-void SQAIMapRegister(SquirrelEngine *engine) {
+void SQAIMapRegister(Squirrel *engine) {
DefSQClass <AIMap> SQAIMap("AIMap");
SQAIMap.PreRegister(engine);
SQAIMap.AddConstructor(engine);
--- a/src/ai/core/ai_town.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/core/ai_town.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -59,7 +59,7 @@
};
#ifdef SQUIRREL_CLASS
-void SQAITownRegister(SquirrelEngine *engine) {
+void SQAITownRegister(Squirrel *engine) {
DefSQClass <AITown> SQAITown("AITown");
SQAITown.PreRegister(engine);
SQAITown.AddConstructor(engine);
--- a/src/ai/squirrel/engine.cpp Thu Mar 15 19:26:11 2007 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/* $Id$ */
-
-/** @file engine.cpp the implementation of the SquirrelEngine class. It handles all Squirrel-stuff and gives a nice API back to work with. */
-
-#ifdef _UNICODE
-/* Disable unicode for squirrel to allow compilation with MINGW
- * and simplify coding for WIN32 (squirrel headers miss a lot of "string" functions)
- */
-#undef _UNICODE
-#endif
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <stdarg.h>
-#include "../../stdafx.h"
-#include "../../debug.h"
-#include "engine.hpp"
-
-void SquirrelEngine::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
-}
-
-void SquirrelEngine::RunError(HSQUIRRELVM vm, const char *error)
-{
- printf("%s\n", error);
-}
-
-SQInteger SquirrelEngine::_RunError(HSQUIRRELVM vm)
-{
- const SQChar *sErr = 0;
-
- if (sq_gettop(vm) >= 1) {
- if (SQ_SUCCEEDED(sq_getstring(vm, -1, &sErr))) {
- SquirrelEngine::RunError(vm, sErr);
- }
- }
-
- SquirrelEngine::RunError(vm, "Unknown error");
- return 0;
-}
-
-void SquirrelEngine::PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...)
-{
- va_list arglist;
- va_start(arglist, s);
- vprintf(s, arglist);
- va_end(arglist);
- printf("\n");
-}
-
-void SquirrelEngine::AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, const char *params)
-{
- sq_pushstring(this->vm, method_name, -1);
- sq_newclosure(this->vm, proc, 0);
- sq_setparamscheck(this->vm, nparam, params);
- sq_setnativeclosurename(this->vm, -1, method_name);
- sq_createslot(this->vm, -3);
-}
-
-void SquirrelEngine::AddMethod(const char *method_name, SQFUNCTION proc)
-{
- sq_pushstring(this->vm, method_name, -1);
- sq_newclosure(this->vm, proc, 0);
- sq_setnativeclosurename(this->vm, -1, method_name);
- sq_createslot(this->vm, -3);
-}
-
-void SquirrelEngine::AddMethod(const char *method_name, SQFUNCTION proc, void *userdata, int size)
-{
- sq_pushstring(this->vm, method_name, -1);
-
- void *ptr;
- ptr = sq_newuserdata(vm, size);
- memcpy(ptr, userdata, size);
-
- sq_newclosure(this->vm, proc, 1);
- sq_setnativeclosurename(this->vm, -1, method_name);
- sq_createslot(this->vm, -3);
-}
-
-void SquirrelEngine::AddClassBegin(const char *class_name)
-{
- sq_pushroottable(this->vm);
- sq_pushstring(this->vm, class_name, -1);
- sq_newclass(this->vm, SQFalse);
-}
-
-void SquirrelEngine::AddClassEnd()
-{
- sq_createslot(vm, -3);
-}
-
-bool SquirrelEngine::MethodExists(HSQOBJECT instance, const char *method_name)
-{
- int top = sq_gettop(this->vm);
- /* Go to the instance-root */
- sq_pushobject(this->vm, instance);
- /* Find the function-name inside the script */
- sq_pushstring(this->vm, method_name, -1);
- if (SQ_FAILED(sq_get(this->vm, -2))) {
- sq_settop(this->vm, top);
- return false;
- }
- sq_settop(this->vm, top);
- return true;
-}
-
-void SquirrelEngine::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret)
-{
- /* Store the current top */
- int top = sq_gettop(this->vm);
- /* Go to the instance-root */
- sq_pushobject(this->vm, instance);
- /* Find the function-name inside the script */
- sq_pushstring(this->vm, method_name, -1);
- if (SQ_FAILED(sq_get(this->vm, -2))) {
- DEBUG(misc, 0, "[squirrel] Could not find '%s' in the class", method_name);
- sq_settop(this->vm, top);
- return;
- }
- /* Call the method */
- sq_pushobject(this->vm, instance);
- sq_call(this->vm, 1, ret == NULL ? SQFalse : SQTrue, SQFalse);
- if (ret != NULL) sq_getstackobj(vm, -1, ret);
- /* Reset the top */
- sq_settop(this->vm, top);
-}
-
-bool SquirrelEngine::CreateClassInstance(const char *class_name, void *real_instance, HSQOBJECT *instance)
-{
- int oldtop = sq_gettop(this->vm);
-
- /* First, find the class */
- sq_pushroottable(this->vm);
- sq_pushstring(this->vm, class_name, -1);
- if (SQ_FAILED(sq_get(this->vm, -2))) {
- DEBUG(misc, 0, "[squirrel] Failed to find class by the name '%s'", class_name);
- sq_settop(this->vm, oldtop);
- return false;
- }
-
- /* Create the instance */
- if (SQ_FAILED(sq_createinstance(this->vm, -1))) {
- DEBUG(misc, 0, "[squirrel] Failed to create instance for class '%s'", class_name);
- sq_settop(this->vm, oldtop);
- return false;
- }
-
- if (instance != NULL) {
- /* Find our instance */
- sq_getstackobj(this->vm, -1, instance);
- /* Add a reference to it, so it survives for ever */
- sq_addref(this->vm, instance);
- }
- /* Store it in the class */
- sq_setinstanceup(this->vm, -1, real_instance);
-
- /* Reset the top */
- sq_settop(this->vm, oldtop);
-
- return true;
-}
-
-SquirrelEngine::SquirrelEngine()
-{
- this->vm = sq_open(1024);
-
- /* Handle compile-errors ourself, so we can display it nicely */
- sq_setcompilererrorhandler(this->vm, &SquirrelEngine::CompileError);
- sq_notifyallexceptions(this->vm, SQTrue);
- /* Set a good print-function */
- sq_setprintfunc(this->vm, &SquirrelEngine::PrintFunc);
- /* Handle runtime-errors ourself, so we can display it nicely */
- sq_newclosure(this->vm, &SquirrelEngine::_RunError, 0);
- sq_seterrorhandler(this->vm);
-
- sq_pushroottable(this->vm);
-}
-
-bool SquirrelEngine::LoadScript(const char *script)
-{
- /* Load and run the script */
- if (SQ_FAILED(sqstd_dofile(this->vm, script, SQFalse, SQTrue))) {
- DEBUG(misc, 0, "[squirrel] Failed to compile '%s'", script);
- return false;
- }
-
- return true;
-}
-
-SquirrelEngine::~SquirrelEngine()
-{
- /* Clean up the stuff */
- sq_pop(this->vm, 1);
- sq_close(this->vm);
-}
--- a/src/ai/squirrel/engine.hpp Thu Mar 15 19:26:11 2007 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/* $Id$ */
-
-/** @file engine.hpp defines the SquirrelEngine class */
-
-#ifndef SQUIRREL_CORE_HPP
-#define SQUIRREL_CORE_HPP
-
-class SquirrelEngine {
-private:
- HSQUIRRELVM vm; ///< The VirtualMachine instnace for squirrel
-
- /**
- * The internal RunError handler. It looks up the real error and calls RunError with it.
- */
- static SQInteger _RunError(HSQUIRRELVM vm);
-
-protected:
- /**
- * The CompileError handler.
- */
- static void CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column);
-
- /**
- * The RunError handler.
- */
- static void RunError(HSQUIRRELVM vm, const char *error);
-
- /**
- * If a user runs 'print' inside a script, this function gets the params.
- */
- static void PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...);
-
-public:
- SquirrelEngine();
- ~SquirrelEngine();
-
- /**
- * Load a script.
- * @param script The full script-name to load.
- * @return False if loading failed.
- */
- bool LoadScript(const char *script);
-
- /**
- * Adds a function to the stack. Depending on the current state this means
- * either a method or a global function.
- */
- void AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, const char *params);
- void AddMethod(const char *method_name, SQFUNCTION proc);
- void AddMethod(const char *method_name, SQFUNCTION proc, void *userdata, int size);
-
- /**
- * Adds a class to the global scope. Make sure to call AddClassEnd when you
- * are done adding methods.
- */
- void AddClassBegin(const char *class_name);
-
- /**
- * Finishes adding a class to the global scope. If this isn't called, no
- * class is really created.
- */
- void AddClassEnd();
-
- /**
- * Call a method of an instance, in various flavors.
- */
- void CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret);
- void CallMethod(HSQOBJECT instance, const char *method_name) { this->CallMethod(instance, method_name, NULL); }
- const char *CallStringMethod(HSQOBJECT instance, const char *method_name) { HSQOBJECT ret; this->CallMethod(instance, method_name, &ret); return ObjectToString(&ret); }
- int CallIntegerMethod(HSQOBJECT instance, const char *method_name) { HSQOBJECT ret; this->CallMethod(instance, method_name, &ret); return ObjectToInteger(&ret); }
-
- /**
- * Check if a method exists in an instance.
- */
- bool MethodExists(HSQOBJECT instance, const char *method_name);
-
- /**
- * Creates a class instance.
- * @param class_name The name of the class of which we create an instance.
- * @param real_instance The instance to the real class, if it represents a real class.
- * @param instance Returning value with the pointer to the instance.
- * @return False if creating failed.
- */
- bool CreateClassInstance(const char *class_name, void *real_instance, HSQOBJECT *instance);
-
- /**
- * Get the real-instance pointer.
- * @note This will only work just after a function-call from within Squirrel
- * to your C++ function.
- */
- static bool GetRealInstance(HSQUIRRELVM vm, SQUserPointer *ptr) { return SQ_SUCCEEDED(sq_getinstanceup(vm, 1, ptr, 0)); }
-
- /**
- * Get the Squirrel-instance pointer.
- * @note This will only work just after a function-call from within Squirrel
- * to your C++ function.
- */
- static bool GetInstance(HSQUIRRELVM vm, HSQOBJECT *ptr) { sq_getclass(vm, 1); sq_getstackobj(vm, 1, ptr); return true; }
-
- /**
- * Convert a Squirrel-object to a string.
- */
- static const char *ObjectToString(HSQOBJECT *ptr) { return sq_objtostring(ptr); }
-
- /**
- * Convert a Squirrel-object to an integer.
- */
- static int ObjectToInteger(HSQOBJECT *ptr) { return sq_objtointeger(ptr); }
-
- /**
- * Sets a pointer in the VM that is reasable from where ever you are, what
- * ever your state is. Useful to keep track of the main instance.
- */
- void SetGlobalPointer(void *ptr) { sq_setforeignptr(this->vm, ptr); }
-
- /**
- * Get the pointer as set by SetGlobalPointer.
- */
- static void *GetGlobalPointer(HSQUIRRELVM vm) { return sq_getforeignptr(vm); }
-
- /**
- * Throw a Squirrel error that will be nicely displayed to the user.
- */
- void ThrowError(const char *error) { sq_throwerror(this->vm, error); }
-};
-
-#endif /* SQUIRREL_CORE_HPP */
--- a/src/ai/squirrel/squirrel.cpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/squirrel/squirrel.cpp Thu Mar 15 19:33:07 2007 +0000
@@ -28,7 +28,7 @@
*/
class AIFactorySquirrel: public AIFactoryBase {
public:
- SquirrelEngine *engine;
+ Squirrel *engine;
HSQOBJECT SQ_instance;
char *script_name;
@@ -72,8 +72,8 @@
AIFactorySquirrel *fbase = new AIFactorySquirrel();
SQInteger res = 0;
- SquirrelEngine::GetInstance(vm, &fbase->SQ_instance);
- fbase->engine = ((FSquirrel *)SquirrelEngine::GetGlobalPointer(vm))->engine;
+ Squirrel::GetInstance(vm, &fbase->SQ_instance);
+ fbase->engine = ((FSquirrel *)Squirrel::GetGlobalPointer(vm))->engine;
/* Check if all needed fields are there */
fbase->CheckMethods(fbase, &res, "GetAuthor");
@@ -87,7 +87,7 @@
if (res != 0) return res;
fbase->RegisterSquirrel();
- fbase->script_name = strdup(((FSquirrel *)SquirrelEngine::GetGlobalPointer(vm))->current_script);
+ fbase->script_name = strdup(((FSquirrel *)Squirrel::GetGlobalPointer(vm))->current_script);
return 0;
}
@@ -134,7 +134,7 @@
void FSquirrel::Initializer()
{
- this->engine = new SquirrelEngine();
+ this->engine = new Squirrel();
/* Create the AIFactory class, and bind the constructor */
this->engine->AddClassBegin("AIFactory");
@@ -184,7 +184,7 @@
AIControllerSquirrel::AIControllerSquirrel(const char *script, const char *class_name)
{
- this->engine = new SquirrelEngine();
+ this->engine = new Squirrel();
this->RegisterClasses();
this->engine->LoadScript(script);
/* Create the main-class */
--- a/src/ai/squirrel/squirrel.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/squirrel/squirrel.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -2,8 +2,8 @@
/** @file squirrel.hpp declarations of the class for squirrel loader */
-#ifndef SQUIRREL_HPP
-#define SQUIRREL_HPP
+#ifndef AI_SQUIRREL_HPP
+#define AI_SQUIRREL_HPP
#ifdef _UNICODE
/* Disable unicode for squirrel to allow compilation with MINGW
@@ -14,11 +14,11 @@
#include <squirrel.h>
#include "../core/ai_controller.hpp"
#include "../core/ai_factory.hpp"
-#include "engine.hpp"
+#include "../../squirrel.hpp"
class AIControllerSquirrel: public AIController {
private:
- SquirrelEngine *engine; ///< The SquirrelEngine
+ Squirrel *engine; ///< The Squirrel engine
HSQOBJECT SQ_instance; ///< The internal instance of squirrel
/**
@@ -37,7 +37,7 @@
class FSquirrel: public AIFactory<FSquirrel> {
private:
- SquirrelEngine *engine; ///< The SquirrelEngine
+ Squirrel *engine; ///< The Squirrel engine
const char *current_script; ///< Temporary variable to know which script defines which class
/**
@@ -64,4 +64,4 @@
/* virtual */ void Initializer();
};
-#endif /* SQUIRREL_HPP */
+#endif /* AI_SQUIRREL_HPP */
--- a/src/ai/squirrel/squirrel_class.hpp Thu Mar 15 19:26:11 2007 +0000
+++ b/src/ai/squirrel/squirrel_class.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -46,22 +46,22 @@
* This defines a method inside a class for Squirrel.
*/
template <typename Func>
- void DefSQFunction(SquirrelEngine *engine, Func function_proc, const char *function_name)
+ void DefSQFunction(Squirrel *engine, Func function_proc, const char *function_name)
{
engine->AddMethod(function_name, SQConvert::DefSQCallback<CL, Func>, &function_proc, sizeof(function_proc));
}
- void PreRegister(SquirrelEngine *engine)
+ void PreRegister(Squirrel *engine)
{
engine->AddClassBegin(this->classname);
}
- void AddConstructor(SquirrelEngine *engine)
+ void AddConstructor(Squirrel *engine)
{
engine->AddMethod("constructor", &DefSQClass::Constructor);
}
- void PostRegister(SquirrelEngine *engine)
+ void PostRegister(Squirrel *engine)
{
engine->AddClassEnd();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/squirrel.cpp Thu Mar 15 19:33:07 2007 +0000
@@ -0,0 +1,200 @@
+/* $Id$ */
+
+/** @file squirrel.cpp the implementation of the Squirrel class. It handles all Squirrel-stuff and gives a nice API back to work with. */
+
+#ifdef _UNICODE
+/* Disable unicode for squirrel to allow compilation with MINGW
+ * and simplify coding for WIN32 (squirrel headers miss a lot of "string" functions)
+ */
+#undef _UNICODE
+#endif
+#include <squirrel.h>
+#include <sqstdio.h>
+#include <stdarg.h>
+#include "stdafx.h"
+#include "debug.h"
+#include "squirrel.hpp"
+
+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
+}
+
+void Squirrel::RunError(HSQUIRRELVM vm, const char *error)
+{
+ printf("%s\n", error);
+}
+
+SQInteger Squirrel::_RunError(HSQUIRRELVM vm)
+{
+ const SQChar *sErr = 0;
+
+ if (sq_gettop(vm) >= 1) {
+ if (SQ_SUCCEEDED(sq_getstring(vm, -1, &sErr))) {
+ Squirrel::RunError(vm, sErr);
+ }
+ }
+
+ Squirrel::RunError(vm, "Unknown error");
+ return 0;
+}
+
+void Squirrel::PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...)
+{
+ va_list arglist;
+ va_start(arglist, s);
+ vprintf(s, arglist);
+ va_end(arglist);
+ printf("\n");
+}
+
+void Squirrel::AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, const char *params)
+{
+ sq_pushstring(this->vm, method_name, -1);
+ sq_newclosure(this->vm, proc, 0);
+ sq_setparamscheck(this->vm, nparam, params);
+ sq_setnativeclosurename(this->vm, -1, method_name);
+ sq_createslot(this->vm, -3);
+}
+
+void Squirrel::AddMethod(const char *method_name, SQFUNCTION proc)
+{
+ sq_pushstring(this->vm, method_name, -1);
+ sq_newclosure(this->vm, proc, 0);
+ sq_setnativeclosurename(this->vm, -1, method_name);
+ sq_createslot(this->vm, -3);
+}
+
+void Squirrel::AddMethod(const char *method_name, SQFUNCTION proc, void *userdata, int size)
+{
+ sq_pushstring(this->vm, method_name, -1);
+
+ void *ptr;
+ ptr = sq_newuserdata(vm, size);
+ memcpy(ptr, userdata, size);
+
+ sq_newclosure(this->vm, proc, 1);
+ sq_setnativeclosurename(this->vm, -1, method_name);
+ sq_createslot(this->vm, -3);
+}
+
+void Squirrel::AddClassBegin(const char *class_name)
+{
+ sq_pushroottable(this->vm);
+ sq_pushstring(this->vm, class_name, -1);
+ sq_newclass(this->vm, SQFalse);
+}
+
+void Squirrel::AddClassEnd()
+{
+ sq_createslot(vm, -3);
+}
+
+bool Squirrel::MethodExists(HSQOBJECT instance, const char *method_name)
+{
+ int top = sq_gettop(this->vm);
+ /* Go to the instance-root */
+ sq_pushobject(this->vm, instance);
+ /* Find the function-name inside the script */
+ sq_pushstring(this->vm, method_name, -1);
+ if (SQ_FAILED(sq_get(this->vm, -2))) {
+ sq_settop(this->vm, top);
+ return false;
+ }
+ sq_settop(this->vm, top);
+ return true;
+}
+
+void Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret)
+{
+ /* Store the current top */
+ int top = sq_gettop(this->vm);
+ /* Go to the instance-root */
+ sq_pushobject(this->vm, instance);
+ /* Find the function-name inside the script */
+ sq_pushstring(this->vm, method_name, -1);
+ if (SQ_FAILED(sq_get(this->vm, -2))) {
+ DEBUG(misc, 0, "[squirrel] Could not find '%s' in the class", method_name);
+ sq_settop(this->vm, top);
+ return;
+ }
+ /* Call the method */
+ sq_pushobject(this->vm, instance);
+ sq_call(this->vm, 1, ret == NULL ? SQFalse : SQTrue, SQFalse);
+ if (ret != NULL) sq_getstackobj(vm, -1, ret);
+ /* Reset the top */
+ sq_settop(this->vm, top);
+}
+
+bool Squirrel::CreateClassInstance(const char *class_name, void *real_instance, HSQOBJECT *instance)
+{
+ int oldtop = sq_gettop(this->vm);
+
+ /* First, find the class */
+ sq_pushroottable(this->vm);
+ sq_pushstring(this->vm, class_name, -1);
+ if (SQ_FAILED(sq_get(this->vm, -2))) {
+ DEBUG(misc, 0, "[squirrel] Failed to find class by the name '%s'", class_name);
+ sq_settop(this->vm, oldtop);
+ return false;
+ }
+
+ /* Create the instance */
+ if (SQ_FAILED(sq_createinstance(this->vm, -1))) {
+ DEBUG(misc, 0, "[squirrel] Failed to create instance for class '%s'", class_name);
+ sq_settop(this->vm, oldtop);
+ return false;
+ }
+
+ if (instance != NULL) {
+ /* Find our instance */
+ sq_getstackobj(this->vm, -1, instance);
+ /* Add a reference to it, so it survives for ever */
+ sq_addref(this->vm, instance);
+ }
+ /* Store it in the class */
+ sq_setinstanceup(this->vm, -1, real_instance);
+
+ /* Reset the top */
+ sq_settop(this->vm, oldtop);
+
+ return true;
+}
+
+Squirrel::Squirrel()
+{
+ 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);
+
+ sq_pushroottable(this->vm);
+}
+
+bool Squirrel::LoadScript(const char *script)
+{
+ /* Load and run the script */
+ if (SQ_FAILED(sqstd_dofile(this->vm, script, SQFalse, SQTrue))) {
+ DEBUG(misc, 0, "[squirrel] Failed to compile '%s'", script);
+ return false;
+ }
+
+ return true;
+}
+
+Squirrel::~Squirrel()
+{
+ /* Clean up the stuff */
+ sq_pop(this->vm, 1);
+ sq_close(this->vm);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/squirrel.hpp Thu Mar 15 19:33:07 2007 +0000
@@ -0,0 +1,127 @@
+/* $Id$ */
+
+/** @file squirrel.hpp defines the Squirrel class */
+
+#ifndef SQUIRREL_HPP
+#define SQUIRREL_HPP
+
+class Squirrel {
+private:
+ HSQUIRRELVM vm; ///< The VirtualMachine instnace for squirrel
+
+ /**
+ * The internal RunError handler. It looks up the real error and calls RunError with it.
+ */
+ static SQInteger _RunError(HSQUIRRELVM vm);
+
+protected:
+ /**
+ * The CompileError handler.
+ */
+ static void CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column);
+
+ /**
+ * The RunError handler.
+ */
+ static void RunError(HSQUIRRELVM vm, const char *error);
+
+ /**
+ * If a user runs 'print' inside a script, this function gets the params.
+ */
+ static void PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...);
+
+public:
+ Squirrel();
+ ~Squirrel();
+
+ /**
+ * Load a script.
+ * @param script The full script-name to load.
+ * @return False if loading failed.
+ */
+ bool LoadScript(const char *script);
+
+ /**
+ * Adds a function to the stack. Depending on the current state this means
+ * either a method or a global function.
+ */
+ void AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, const char *params);
+ void AddMethod(const char *method_name, SQFUNCTION proc);
+ void AddMethod(const char *method_name, SQFUNCTION proc, void *userdata, int size);
+
+ /**
+ * Adds a class to the global scope. Make sure to call AddClassEnd when you
+ * are done adding methods.
+ */
+ void AddClassBegin(const char *class_name);
+
+ /**
+ * Finishes adding a class to the global scope. If this isn't called, no
+ * class is really created.
+ */
+ void AddClassEnd();
+
+ /**
+ * Call a method of an instance, in various flavors.
+ */
+ void CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret);
+ void CallMethod(HSQOBJECT instance, const char *method_name) { this->CallMethod(instance, method_name, NULL); }
+ const char *CallStringMethod(HSQOBJECT instance, const char *method_name) { HSQOBJECT ret; this->CallMethod(instance, method_name, &ret); return ObjectToString(&ret); }
+ int CallIntegerMethod(HSQOBJECT instance, const char *method_name) { HSQOBJECT ret; this->CallMethod(instance, method_name, &ret); return ObjectToInteger(&ret); }
+
+ /**
+ * Check if a method exists in an instance.
+ */
+ bool MethodExists(HSQOBJECT instance, const char *method_name);
+
+ /**
+ * Creates a class instance.
+ * @param class_name The name of the class of which we create an instance.
+ * @param real_instance The instance to the real class, if it represents a real class.
+ * @param instance Returning value with the pointer to the instance.
+ * @return False if creating failed.
+ */
+ bool CreateClassInstance(const char *class_name, void *real_instance, HSQOBJECT *instance);
+
+ /**
+ * Get the real-instance pointer.
+ * @note This will only work just after a function-call from within Squirrel
+ * to your C++ function.
+ */
+ static bool GetRealInstance(HSQUIRRELVM vm, SQUserPointer *ptr) { return SQ_SUCCEEDED(sq_getinstanceup(vm, 1, ptr, 0)); }
+
+ /**
+ * Get the Squirrel-instance pointer.
+ * @note This will only work just after a function-call from within Squirrel
+ * to your C++ function.
+ */
+ static bool GetInstance(HSQUIRRELVM vm, HSQOBJECT *ptr) { sq_getclass(vm, 1); sq_getstackobj(vm, 1, ptr); return true; }
+
+ /**
+ * Convert a Squirrel-object to a string.
+ */
+ static const char *ObjectToString(HSQOBJECT *ptr) { return sq_objtostring(ptr); }
+
+ /**
+ * Convert a Squirrel-object to an integer.
+ */
+ static int ObjectToInteger(HSQOBJECT *ptr) { return sq_objtointeger(ptr); }
+
+ /**
+ * Sets a pointer in the VM that is reasable from where ever you are, what
+ * ever your state is. Useful to keep track of the main instance.
+ */
+ void SetGlobalPointer(void *ptr) { sq_setforeignptr(this->vm, ptr); }
+
+ /**
+ * Get the pointer as set by SetGlobalPointer.
+ */
+ static void *GetGlobalPointer(HSQUIRRELVM vm) { return sq_getforeignptr(vm); }
+
+ /**
+ * Throw a Squirrel error that will be nicely displayed to the user.
+ */
+ void ThrowError(const char *error) { sq_throwerror(this->vm, error); }
+};
+
+#endif /* SQUIRREL_HPP */