--- /dev/null
+#include <config.h>
+
+#include "script_interpreter.h"
+
+#include <stdarg.h>
+#include <stdexcept>
+#include <sstream>
+#include <sqstdio.h>
+#include <sqstdaux.h>
+#include <sqstdblob.h>
+#include <sqstdsystem.h>
+#include <sqstdmath.h>
+#include <sqstdstring.h>
+
+#include "wrapper.h"
+#include "wrapper_util.h"
+
+static void printfunc(HSQUIRRELVM, const char* str, ...)
+{
+ va_list arglist;
+ va_start(arglist, str);
+ vprintf(str, arglist);
+ va_end(arglist);
+}
+
+ScriptInterpreter* ScriptInterpreter::_current = 0;
+
+ScriptInterpreter::ScriptInterpreter()
+{
+ v = sq_open(1024);
+ if(v == 0)
+ throw std::runtime_error("Couldn't initialize squirrel vm");
+
+ // register default error handlers
+ sqstd_seterrorhandlers(v);
+ // register squirrel libs
+ sq_pushroottable(v);
+ if(sqstd_register_bloblib(v) < 0)
+ throw SquirrelError(v, "Couldn't register blob lib");
+ if(sqstd_register_iolib(v) < 0)
+ throw SquirrelError(v, "Couldn't register io lib");
+ if(sqstd_register_systemlib(v) < 0)
+ throw SquirrelError(v, "Couldn't register system lib");
+ if(sqstd_register_mathlib(v) < 0)
+ throw SquirrelError(v, "Couldn't register math lib");
+ if(sqstd_register_stringlib(v) < 0)
+ throw SquirrelError(v, "Couldn't register string lib");
+
+ // register print function
+ sq_setprintfunc(v, printfunc);
+
+ // register supertux API
+ register_functions(v, supertux_global_functions);
+ register_classes(v, supertux_classes);
+}
+
+ScriptInterpreter::~ScriptInterpreter()
+{
+}
+
+static SQInteger squirrel_read_char(SQUserPointer file)
+{
+ std::istream* in = reinterpret_cast<std::istream*> (file);
+ char c = in->get();
+ if(in->eof())
+ return 0;
+ return c;
+}
+
+
+void
+ScriptInterpreter::load_script(std::istream& in, const std::string& sourcename)
+{
+ if(sq_compile(v, squirrel_read_char, &in, sourcename.c_str(), true) < 0)
+ throw SquirrelError(v, "Couldn't parse script");
+}
+
+void
+ScriptInterpreter::run_script()
+{
+ _current = this;
+ sq_push(v, -2);
+ if(sq_call(v, 1, false) < 0)
+ throw SquirrelError(v, "Couldn't start script");
+ _current = 0;
+}
+
+void
+ScriptInterpreter::expose_object(void* object, const std::string& name,
+ const std::string& type)
+{
+ // part1 of registration of the instance in the root table
+ sq_pushroottable(v);
+ sq_pushstring(v, name.c_str(), -1);
+
+ // resolve class name
+ sq_pushroottable(v);
+ sq_pushstring(v, type.c_str(), -1);
+ if(sq_get(v, -2) < 0) {
+ std::ostringstream msg;
+ msg << "Couldn't resolve squirrel type '" << type << "'.";
+ throw std::runtime_error(msg.str());
+ }
+ sq_remove(v, -2); // remove roottable
+
+ // create an instance and set pointer to c++ object
+ if(sq_createinstance(v, -1) < 0 || sq_setinstanceup(v, -1, object)) {
+ std::ostringstream msg;
+ msg << "Couldn't setup squirrel instance for object '"
+ << name << "' of type '" << type << "'.";
+ throw SquirrelError(v, msg.str());
+ }
+
+ sq_remove(v, -2); // remove class from stack
+
+ // part2 of registration of the instance in the root table
+ if(sq_createslot(v, -3) < 0)
+ throw SquirrelError(v, "Couldn't register object in squirrel root table"); sq_pop(v, 1);
+}
+
+void
+ScriptInterpreter::suspend(float seconds)
+{
+ resume_timer.start(seconds);
+ //sq_suspendvm(v);
+}
+
+void
+ScriptInterpreter::update()
+{
+ if(resume_timer.check()) {
+ _current = this;
+ if(sq_wakeupvm(v, false, false) < 0)
+ throw SquirrelError(v, "Couldn't resume script");
+ _current = 0;
+ }
+}
if(type(temp) == OT_NULL) {
SQClassMember m;
m.val = val;
- _members->NewSlot(key,SQObjectPtr((SQUserPointer)_methods.size()));
+ _members->NewSlot(key, SQObjectPtr((SQUserPointer)_methods.size()));
_methods.push_back(m);
}
else {
- _methods[(int)_userpointer(temp)].val = val;
+ _methods[_integer(temp)].val = val;
}
}
return true;
int idx = _members->Next(refpos,outkey,oval);
if(idx != -1) {
if(type(oval) != OT_INTEGER) {
- outval = _methods[(int)_userpointer(oval)].val;
+ outval = _methods[_integer(oval)].val;
}
else {
outval = _defaultvalues[_integer(oval)].val;
if(type(idx) == OT_INTEGER)
_defaultvalues[_integer(idx)].attrs = val;
else
- _methods[(int)_userpointer(idx)].attrs = val;
+ _methods[_integer(idx)].attrs = val;
return true;
}
return false;