X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fscripting%2Fsquirrel_util.cpp;h=5fd15b42d184c30b0e1cd533954d2870575cbf9b;hb=f5ad6f69da56235de950f21de30563802c6f2e06;hp=b3cf9c17b09f503e73e117baf40fbb63af01a43b;hpb=5254e223656d8a4f9c4c7f681f96f9a92b0b5799;p=supertux.git diff --git a/src/scripting/squirrel_util.cpp b/src/scripting/squirrel_util.cpp index b3cf9c17b..5fd15b42d 100644 --- a/src/scripting/squirrel_util.cpp +++ b/src/scripting/squirrel_util.cpp @@ -1,12 +1,10 @@ -// $Id$ -// // SuperTux // Copyright (C) 2006 Matthias Braun // -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,139 +12,33 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// along with this program. If not, see . + +#include "scripting/squirrel_util.hpp" + #include -#include -#include -#include -#include -#include +#include +#include #include +#include #include -#include -#include -#include "squirrel_util.hpp" -#include "log.hpp" -#include "level.hpp" -#include "physfs/physfs_stream.hpp" -#include "../random_generator.hpp" - -#ifdef ENABLE_SQDBG -#include - -static HSQREMOTEDBG debugger = NULL; -#endif - -namespace Scripting -{ - -HSQUIRRELVM global_vm = NULL; - -static void printfunc(HSQUIRRELVM, const char* str, ...) -{ - char buf[4096]; - va_list arglist; - va_start(arglist, str); - vsprintf(buf, str, arglist); - Console::output << (const char*) buf << std::flush; - va_end(arglist); -} - -void init_squirrel(bool enable_debugger) -{ - global_vm = sq_open(64); - if(global_vm == NULL) - throw std::runtime_error("Couldn't initialize squirrel vm"); - - 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(SQ_FAILED(sqstd_register_bloblib(global_vm))) - throw SquirrelError(global_vm, "Couldn't register blob lib"); - if(SQ_FAILED(sqstd_register_mathlib(global_vm))) - throw SquirrelError(global_vm, "Couldn't register math lib"); - 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 - sq_setprintfunc(global_vm, printfunc); - // register default error handlers - sqstd_seterrorhandlers(global_vm); - - // try to load default script - try { - std::string filename = "scripts/default.nut"; - IFileStream stream(filename); - Scripting::compile_and_run(global_vm, stream, filename); - } catch(std::exception& e) { - log_warning << "Couldn't load default.nut: " << e.what() << std::endl; - } -} - -void exit_squirrel() -{ -#ifdef ENABLE_SQDBG - if(debugger != NULL) { - sq_rdbg_shutdown(debugger); - debugger = NULL; - } -#endif - - if (global_vm) - sq_close(global_vm); - - global_vm = NULL; -} +#include -void update_debugger() -{ -#ifdef ENABLE_SQDBG - if(debugger != NULL) - sq_rdbg_update(debugger); -#endif -} +namespace scripting { std::string squirrel2string(HSQUIRRELVM v, SQInteger i) { std::ostringstream os; switch(sq_gettype(v, i)) - { + { case OT_NULL: - os << ""; + os << ""; break; case OT_BOOL: { SQBool p; sq_getbool(v, i, &p); - if (p) + if (p) os << "true"; else os << "false"; @@ -168,25 +60,25 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i) const SQChar* val; sq_getstring(v, i, &val); os << "\"" << val << "\""; - break; + break; } case OT_TABLE: { bool first = true; os << "{"; sq_pushnull(v); //null iterator while(SQ_SUCCEEDED(sq_next(v,i-1))) - { - if (!first) { - os << ", "; - } - first = false; - - //here -1 is the value and -2 is the key - os << squirrel2string(v, -2) << " => " - << squirrel2string(v, -1); - - sq_pop(v,2); //pops key and val before the nex iteration + { + if (!first) { + os << ", "; } + first = false; + + //here -1 is the value and -2 is the key + os << squirrel2string(v, -2) << " => " + << squirrel2string(v, -1); + + sq_pop(v,2); //pops key and val before the nex iteration + } sq_pop(v, 1); os << "}"; break; @@ -196,18 +88,18 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i) os << "["; sq_pushnull(v); //null iterator while(SQ_SUCCEEDED(sq_next(v,i-1))) - { - if (!first) { - os << ", "; - } - first = false; - - //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 + { + if (!first) { + os << ", "; } + first = false; + + //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); os << "]"; break; @@ -215,7 +107,7 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i) case OT_USERDATA: os << ""; break; - case OT_CLOSURE: + case OT_CLOSURE: os << ""; break; case OT_NATIVECLOSURE: @@ -242,85 +134,85 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i) default: os << ""; break; - } + } return os.str(); } void print_squirrel_stack(HSQUIRRELVM v) { - printf("--------------------------------------------------------------\n"); - int count = sq_gettop(v); - for(int i = 1; i <= count; ++i) { - printf("%d: ",i); - switch(sq_gettype(v, i)) - { - case OT_NULL: - printf("null"); - break; - case OT_INTEGER: { - SQInteger val; - sq_getinteger(v, i, &val); - printf("integer (%d)", static_cast (val)); - break; - } - case OT_FLOAT: { - SQFloat val; - sq_getfloat(v, i, &val); - printf("float (%f)", val); - break; - } - case OT_STRING: { - const SQChar* val; - sq_getstring(v, i, &val); - printf("string (%s)", val); - break; - } - case OT_TABLE: - printf("table"); - break; - case OT_ARRAY: - printf("array"); - break; - case OT_USERDATA: - printf("userdata"); - break; - case OT_CLOSURE: - printf("closure(function)"); - break; - case OT_NATIVECLOSURE: - printf("native closure(C function)"); - break; - case OT_GENERATOR: - printf("generator"); - break; - case OT_USERPOINTER: - printf("userpointer"); - break; - case OT_THREAD: - printf("thread"); - break; - case OT_CLASS: - printf("class"); - break; - case OT_INSTANCE: - printf("instance"); - break; - case OT_WEAKREF: - printf("weakref"); - break; - default: - printf("unknown?!?"); - break; - } - printf("\n"); + printf("--------------------------------------------------------------\n"); + int count = sq_gettop(v); + for(int i = 1; i <= count; ++i) { + printf("%d: ",i); + switch(sq_gettype(v, i)) + { + case OT_NULL: + printf("null"); + break; + case OT_INTEGER: { + SQInteger val; + sq_getinteger(v, i, &val); + printf("integer (%d)", static_cast (val)); + break; + } + case OT_FLOAT: { + SQFloat val; + sq_getfloat(v, i, &val); + printf("float (%f)", val); + break; + } + case OT_STRING: { + const SQChar* val; + sq_getstring(v, i, &val); + printf("string (%s)", val); + break; + } + case OT_TABLE: + printf("table"); + break; + case OT_ARRAY: + printf("array"); + break; + case OT_USERDATA: + printf("userdata"); + break; + case OT_CLOSURE: + printf("closure(function)"); + break; + case OT_NATIVECLOSURE: + printf("native closure(C function)"); + break; + case OT_GENERATOR: + printf("generator"); + break; + case OT_USERPOINTER: + printf("userpointer"); + break; + case OT_THREAD: + printf("thread"); + break; + case OT_CLASS: + printf("class"); + break; + case OT_INSTANCE: + printf("instance"); + break; + case OT_WEAKREF: + printf("weakref"); + break; + default: + printf("unknown?!?"); + break; } - printf("--------------------------------------------------------------\n"); + printf("\n"); + } + printf("--------------------------------------------------------------\n"); } -static SQInteger squirrel_read_char(SQUserPointer file) +SQInteger squirrel_read_char(SQUserPointer file) { std::istream* in = reinterpret_cast (file); - char c = in->get(); + int c = in->get(); if(in->eof()) return 0; return c; @@ -329,14 +221,14 @@ static SQInteger squirrel_read_char(SQUserPointer file) 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); - + SQInteger oldtop = sq_gettop(vm); try { @@ -365,7 +257,7 @@ HSQOBJECT create_thread(HSQUIRRELVM 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; @@ -389,4 +281,169 @@ HSQUIRRELVM object_to_vm(HSQOBJECT 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 + +} + +/* EOF */