X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fscripting%2Fwrapper_util.cpp;h=a24a5acc30ccae7c96dcaed2ba634f8cdcefa37e;hb=59a0c6591fed50fac5521f17cc8c78450691ad6d;hp=f52ecbaef6b1d6e38295d4e39cc8bd3af4f6f934;hpb=4a54087f52d6a8a2e5b4c498e772685bb0885991;p=supertux.git diff --git a/src/scripting/wrapper_util.cpp b/src/scripting/wrapper_util.cpp index f52ecbaef..a24a5acc3 100644 --- a/src/scripting/wrapper_util.cpp +++ b/src/scripting/wrapper_util.cpp @@ -1,42 +1,137 @@ +// $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 distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// 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. + #include #include #include -#include "wrapper_util.h" +#include "wrapper_util.hpp" -static void register_function(HSQUIRRELVM v, SQFUNCTION func, const char* name) +namespace Scripting { - sq_pushstring(v, name, -1); - sq_newclosure(v, func, 0); //create a new function - sq_createslot(v, -3); -} -static void register_class(HSQUIRRELVM v, WrappedClass* wclass) +std::string squirrel2string(HSQUIRRELVM v, int i) { - sq_pushstring(v, wclass->name, -1); - sq_newclass(v, false); - for(WrappedFunction* func = wclass->functions; func->name != 0; ++func) { - register_function(v, func->f, func->name); + std::ostringstream os; + switch(sq_gettype(v, i)) + { + case OT_NULL: + os << ""; + break; + case OT_BOOL: { + SQBool p; + sq_getbool(v, i, &p); + if (p) + os << "true"; + else + os << "false"; + break; } - sq_createslot(v, -3); -} + case OT_INTEGER: { + int val; + sq_getinteger(v, i, &val); + os << val; + break; + } + case OT_FLOAT: { + float val; + sq_getfloat(v, i, &val); + os << val; + break; + } + case OT_STRING: { + const char* val; + sq_getstring(v, i, &val); + os << "\"" << val << "\""; + 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; -void register_functions(HSQUIRRELVM v, WrappedFunction* functions) -{ - sq_pushroottable(v); - for(WrappedFunction* func = functions; func->name != 0; ++func) { - register_function(v, func->f, func->name); + //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; } - sq_pop(v, 1); -} + case OT_ARRAY: { + bool first = true; + os << "["; + sq_pushnull(v); //null iterator + while(SQ_SUCCEEDED(sq_next(v,i-1))) + { + if (!first) { + os << ", "; + } + first = false; -void register_classes(HSQUIRRELVM v, WrappedClass* classes) -{ - sq_pushroottable(v); - for(WrappedClass* wclass = classes; wclass->name != 0; ++wclass) { - register_class(v, wclass); + //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; } - sq_pop(v, 1); + case OT_USERDATA: + os << ""; + break; + case OT_CLOSURE: + os << ""; + break; + case OT_NATIVECLOSURE: + os << ""; + break; + case OT_GENERATOR: + os << ""; + break; + case OT_USERPOINTER: + os << "userpointer"; + break; + case OT_THREAD: + os << ""; + break; + case OT_CLASS: + os << ""; + break; + case OT_INSTANCE: + os << ""; + break; + default: + os << ""; + break; + } + return os.str(); } void print_squirrel_stack(HSQUIRRELVM v) @@ -89,6 +184,9 @@ void print_squirrel_stack(HSQUIRRELVM v) case OT_USERPOINTER: printf("userpointer"); break; + case OT_THREAD: + printf("thread"); + break; case OT_CLASS: printf("class"); break; @@ -104,58 +202,37 @@ void print_squirrel_stack(HSQUIRRELVM v) printf("--------------------------------------------------------------\n"); } -void expose_object(HSQUIRRELVM v, void* object, const char* type, - const char* name) +static SQInteger squirrel_read_char(SQUserPointer file) { - // part1 of registration of the instance in the root table - sq_pushroottable(v); - sq_pushstring(v, name, -1); - - // resolve class name - sq_pushroottable(v); - sq_pushstring(v, type, -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, 2); + std::istream* in = reinterpret_cast (file); + char c = in->get(); + if(in->eof()) + return 0; + return c; } -//---------------------------------------------------------------------------- - -SquirrelError::SquirrelError(HSQUIRRELVM v, const std::string& message) throw() +void compile_script(HSQUIRRELVM vm, std::istream& in, const std::string& sourcename) { - std::ostringstream msg; - msg << "SQuirrel error: " << message << " ("; - const char* lasterr; - sq_getlasterror(v); - sq_getstring(v, -1, &lasterr); - sq_pop(v, 1); - msg << lasterr << ")"; - this->message = msg.str(); + if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in, sourcename.c_str(), true))) + throw SquirrelError(vm, "Couldn't parse script"); } -SquirrelError::~SquirrelError() throw() -{} - -const char* -SquirrelError::what() const throw() +void compile_and_run(HSQUIRRELVM vm, std::istream& in, const std::string& sourcename) { - return message.c_str(); + compile_script(vm, in, sourcename); + + int oldtop = sq_gettop(vm); + + try { + sq_pushroottable(vm); + if(SQ_FAILED(sq_call(vm, 1, false))) + throw SquirrelError(vm, "Couldn't start script"); + } catch(...) { + sq_settop(vm, oldtop); + throw; + } + + sq_settop(vm, oldtop); +} + }