#include "log.hpp"
#include "level.hpp"
#include "physfs/physfs_stream.hpp"
+#include "../random_generator.hpp"
#ifdef ENABLE_SQDBG
#include <sqdbg/sqrdbg.h>
if(global_vm == NULL)
throw std::runtime_error("Couldn't initialize squirrel vm");
-#ifdef ENABLE_SQDBG
if(enable_debugger) {
+#ifdef ENABLE_SQDBG
sq_enabledebuginfo(global_vm, SQTrue);
debugger = sq_rdbg_init(global_vm, 1234, SQFalse);
if(debugger == NULL)
throw SquirrelError(global_vm, "Couldn't initialize squirrel debugger");
-
+
sq_enabledebuginfo(global_vm, SQTrue);
log_info << "Waiting for debug client..." << std::endl;
if(SQ_FAILED(sq_rdbg_waitforconnections(debugger)))
throw SquirrelError(global_vm, "Waiting for debug clients failed");
log_info << "debug client connected." << std::endl;
- }
#endif
+ }
sq_pushroottable(global_vm);
- if(sqstd_register_bloblib(global_vm) < 0)
+ if(SQ_FAILED(sqstd_register_bloblib(global_vm)))
throw SquirrelError(global_vm, "Couldn't register blob lib");
- if(sqstd_register_mathlib(global_vm) < 0)
+ if(SQ_FAILED(sqstd_register_mathlib(global_vm)))
throw SquirrelError(global_vm, "Couldn't register math lib");
- if(sqstd_register_stringlib(global_vm) < 0)
+ if(SQ_FAILED(sqstd_register_stringlib(global_vm)))
throw SquirrelError(global_vm, "Couldn't register string lib");
+
+ // remove rand and srand calls from sqstdmath, we'll provide our own
+ sq_pushstring(global_vm, "srand", -1);
+ sq_deleteslot(global_vm, -2, SQFalse);
+ sq_pushstring(global_vm, "rand", -1);
+ sq_deleteslot(global_vm, -2, SQFalse);
+
// register supertux API
register_supertux_wrapper(global_vm);
// TODO remove this at some point... it shoud just be functions not an object
expose_object(global_vm, -1, new Scripting::Level(), "Level", true);
-
+
sq_pop(global_vm, 1);
// register print function
debugger = NULL;
}
#endif
- sq_close(global_vm);
+
+ if (global_vm)
+ sq_close(global_vm);
+
global_vm = NULL;
}
#endif
}
-std::string squirrel2string(HSQUIRRELVM v, int i)
+std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
{
std::ostringstream os;
switch(sq_gettype(v, i))
{
case OT_NULL:
- os << "<null>";
+ os << "<null>";
break;
case OT_BOOL: {
SQBool p;
sq_getbool(v, i, &p);
- if (p)
+ if (p)
os << "true";
else
os << "false";
break;
}
case OT_INTEGER: {
- int val;
+ SQInteger val;
sq_getinteger(v, i, &val);
os << val;
break;
}
case OT_FLOAT: {
- float val;
+ SQFloat val;
sq_getfloat(v, i, &val);
os << val;
break;
}
case OT_STRING: {
- const char* val;
+ const SQChar* val;
sq_getstring(v, i, &val);
os << "\"" << val << "\"";
- break;
+ break;
}
case OT_TABLE: {
bool first = true;
first = false;
//here -1 is the value and -2 is the key
- os << squirrel2string(v, -2) << " => "
+ os << squirrel2string(v, -2) << " => "
<< squirrel2string(v, -1);
-
+
sq_pop(v,2); //pops key and val before the nex iteration
}
sq_pop(v, 1);
//here -1 is the value and -2 is the key
// we ignore the key, since that is just the index in an array
os << squirrel2string(v, -1);
-
+
sq_pop(v,2); //pops key and val before the nex iteration
}
sq_pop(v, 1);
case OT_USERDATA:
os << "<userdata>";
break;
- case OT_CLOSURE:
+ case OT_CLOSURE:
os << "<closure>";
break;
case OT_NATIVECLOSURE:
switch(sq_gettype(v, i))
{
case OT_NULL:
- printf("null");
+ printf("null");
break;
case OT_INTEGER: {
- int val;
+ SQInteger val;
sq_getinteger(v, i, &val);
- printf("integer (%d)", val);
+ printf("integer (%d)", static_cast<int> (val));
break;
}
case OT_FLOAT: {
- float val;
+ SQFloat val;
sq_getfloat(v, i, &val);
printf("float (%f)", val);
break;
}
case OT_STRING: {
- const char* val;
+ const SQChar* val;
sq_getstring(v, i, &val);
printf("string (%s)", val);
- break;
+ break;
}
case OT_TABLE:
printf("table");
case OT_USERDATA:
printf("userdata");
break;
- case OT_CLOSURE:
- printf("closure(function)");
+ case OT_CLOSURE:
+ printf("closure(function)");
break;
case OT_NATIVECLOSURE:
printf("native closure(C function)");
void compile_script(HSQUIRRELVM vm, std::istream& in, const std::string& sourcename)
{
if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in, sourcename.c_str(), true)))
- throw SquirrelError(vm, "Couldn't parse script");
+ throw SquirrelError(vm, "Couldn't parse script");
}
void compile_and_run(HSQUIRRELVM vm, std::istream& in,
const std::string& sourcename)
{
compile_script(vm, in, sourcename);
-
- int oldtop = sq_gettop(vm);
+
+ SQInteger oldtop = sq_gettop(vm);
try {
sq_pushroottable(vm);
if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
throw SquirrelError(vm, "Couldn't get squirrel thread from stack");
sq_addref(vm, &vm_object);
-
+
sq_pop(vm, 1);
return vm_object;
return object._unVal.pThread;
}
+// begin: serialization functions
+
+void store_float(HSQUIRRELVM vm, const char* name, float val)
+{
+ sq_pushstring(vm, name, -1);
+ sq_pushfloat(vm, val);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
+}
+
+void store_int(HSQUIRRELVM vm, const char* name, int val)
+{
+ sq_pushstring(vm, name, -1);
+ sq_pushinteger(vm, val);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't add int value to table");
+}
+
+void store_string(HSQUIRRELVM vm, const char* name, const std::string& val)
+{
+ sq_pushstring(vm, name, -1);
+ sq_pushstring(vm, val.c_str(), val.length());
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
+}
+
+void store_bool(HSQUIRRELVM vm, const char* name, bool val)
+{
+ sq_pushstring(vm, name, -1);
+ sq_pushbool(vm, val ? SQTrue : SQFalse);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
+}
+
+bool has_float(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if (SQ_FAILED(sq_get(vm, -2))) return false;
+ sq_pop(vm, 1);
+ return true;
+}
+
+bool has_int(HSQUIRRELVM vm, const char* name)
+{
+ return has_float(vm, name);
+}
+
+bool has_string(HSQUIRRELVM vm, const char* name)
+{
+ return has_float(vm, name);
+}
+
+bool has_bool(HSQUIRRELVM vm, const char* name)
+{
+ return has_float(vm, name);
+}
+
+float read_float(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ std::ostringstream msg;
+ msg << "Couldn't get float value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+
+ float result;
+ if(SQ_FAILED(sq_getfloat(vm, -1, &result))) {
+ std::ostringstream msg;
+ msg << "Couldn't get float value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+ sq_pop(vm, 1);
+
+ return result;
+}
+
+int read_int(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ std::ostringstream msg;
+ msg << "Couldn't get int value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+
+ SQInteger result;
+ if(SQ_FAILED(sq_getinteger(vm, -1, &result))) {
+ std::ostringstream msg;
+ msg << "Couldn't get int value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+ sq_pop(vm, 1);
+
+ return result;
+}
+
+
+std::string read_string(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ std::ostringstream msg;
+ msg << "Couldn't get string value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+
+ const char* result;
+ if(SQ_FAILED(sq_getstring(vm, -1, &result))) {
+ std::ostringstream msg;
+ msg << "Couldn't get string value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+ sq_pop(vm, 1);
+
+ return std::string(result);
+}
+
+bool read_bool(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ std::ostringstream msg;
+ msg << "Couldn't get bool value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+
+ SQBool result;
+ if(SQ_FAILED(sq_getbool(vm, -1, &result))) {
+ std::ostringstream msg;
+ msg << "Couldn't get bool value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+ sq_pop(vm, 1);
+
+ return result == SQTrue;
+}
+
+bool get_float(HSQUIRRELVM vm, const char* name, float& val) {
+ if (!has_float(vm, name)) return false;
+ val = read_float(vm, name);
+ return true;
+}
+
+bool get_int(HSQUIRRELVM vm, const char* name, int& val) {
+ if (!has_int(vm, name)) return false;
+ val = read_int(vm, name);
+ return true;
+}
+
+bool get_string(HSQUIRRELVM vm, const char* name, std::string& val) {
+ if (!has_string(vm, name)) return false;
+ val = read_string(vm, name);
+ return true;
+}
+
+bool get_bool(HSQUIRRELVM vm, const char* name, bool& val) {
+ if (!has_bool(vm, name)) return false;
+ val = read_bool(vm, name);
+ return true;
+}
+
+// end: serialization functions
+
}