From 78724e8ddcdb94a7b691464ea9e558d0a6665aa7 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 5 May 2005 18:58:00 +0000 Subject: [PATCH] reworked miniswig a bit to support virtual functions and to only emit constructors if these are public and explicitely declared SVN-Revision: 2411 --- src/scripting/Jamfile | 2 +- src/scripting/scripted_object.h | 22 +++--- src/scripting/wrapper.cpp | 136 +++++--------------------------------- src/scripting/wrapper.interface.h | 3 +- tools/miniswig/create_wrapper.cpp | 80 +++++++++++----------- tools/miniswig/create_wrapper.h | 3 +- tools/miniswig/lexer.ll | 1 + tools/miniswig/parser.yy | 31 ++++++--- tools/miniswig/tree.h | 6 +- 9 files changed, 102 insertions(+), 182 deletions(-) diff --git a/src/scripting/Jamfile b/src/scripting/Jamfile index 9def30629..6214f7173 100644 --- a/src/scripting/Jamfile +++ b/src/scripting/Jamfile @@ -11,7 +11,7 @@ if $(MINISWIG) SEARCH on $(headerfile) = $(SOURCH_SOURCE) ; MiniSwig $(cppfile) : $(sources) ; - CPPFLAGS on $(cppfile) = $(CPPFLAGS) ; + CPPFLAGS on $(cppfile) = $(CPPFLAGS) -DSCRIPTING_API ; headerfile on $(cppfile) = $(headerfile) ; modulename on $(cppfile) = $(3) ; FLAGS on $(cppfile) = $(4) ; diff --git a/src/scripting/scripted_object.h b/src/scripting/scripted_object.h index b22fd0888..4ac8177e8 100644 --- a/src/scripting/scripted_object.h +++ b/src/scripting/scripted_object.h @@ -8,20 +8,20 @@ class ScriptedObject { public: #ifndef SCRIPTING_API - ScriptedObject(); - virtual ~ScriptedObject(); + ScriptedObject(); + virtual ~ScriptedObject(); #endif - void set_animation(const std::string& animation); - std::string get_animation(); + virtual void set_animation(const std::string& animation) = 0; + virtual std::string get_animation() = 0; - void move(float x, float y); - void set_pos(float x, float y); - float get_pos_x(); - float get_pos_y(); - void set_velocity(float x, float y); - float get_velocity_x(); - float get_velocity_y(); + virtual void move(float x, float y) = 0; + virtual void set_pos(float x, float y) = 0; + virtual float get_pos_x() = 0; + virtual float get_pos_y() = 0; + virtual void set_velocity(float x, float y) = 0; + virtual float get_velocity_x() = 0; + virtual float get_velocity_y() = 0; }; } diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index d8c475cdf..5cb15e3cf 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -12,27 +12,10 @@ using namespace Scripting; -static int Display_release_wrapper(SQUserPointer ptr, int ) -{ - Display* _this = reinterpret_cast (ptr); - delete _this; - return 0; -} - -static int Display_construct_wrapper(HSQUIRRELVM v) -{ - Display* _this = new Display(); - sq_setinstanceup(v, 1, _this); - sq_setreleasehook(v, 1, Display_release_wrapper); - - return 0; -} - static int Display_set_effect_wrapper(HSQUIRRELVM v) { - Display* _this; + Scripting::Display* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); const char* arg0; sq_getstring(v, 2, &arg0); @@ -41,27 +24,10 @@ static int Display_set_effect_wrapper(HSQUIRRELVM v) return 0; } -static int Camera_release_wrapper(SQUserPointer ptr, int ) -{ - Camera* _this = reinterpret_cast (ptr); - delete _this; - return 0; -} - -static int Camera_construct_wrapper(HSQUIRRELVM v) -{ - Camera* _this = new Camera(); - sq_setinstanceup(v, 1, _this); - sq_setreleasehook(v, 1, Camera_release_wrapper); - - return 0; -} - static int Camera_shake_wrapper(HSQUIRRELVM v) { - Camera* _this; + Scripting::Camera* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float arg0; sq_getfloat(v, 2, &arg0); float arg1; @@ -76,9 +42,8 @@ static int Camera_shake_wrapper(HSQUIRRELVM v) static int Camera_set_pos_wrapper(HSQUIRRELVM v) { - Camera* _this; + Scripting::Camera* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float arg0; sq_getfloat(v, 2, &arg0); float arg1; @@ -91,9 +56,8 @@ static int Camera_set_pos_wrapper(HSQUIRRELVM v) static int Camera_set_mode_wrapper(HSQUIRRELVM v) { - Camera* _this; + Scripting::Camera* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); const char* arg0; sq_getstring(v, 2, &arg0); @@ -102,27 +66,10 @@ static int Camera_set_mode_wrapper(HSQUIRRELVM v) return 0; } -static int Level_release_wrapper(SQUserPointer ptr, int ) -{ - Level* _this = reinterpret_cast (ptr); - delete _this; - return 0; -} - -static int Level_construct_wrapper(HSQUIRRELVM v) -{ - Level* _this = new Level(); - sq_setinstanceup(v, 1, _this); - sq_setreleasehook(v, 1, Level_release_wrapper); - - return 0; -} - static int Level_finish_wrapper(HSQUIRRELVM v) { - Level* _this; + Scripting::Level* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); _this->finish(); @@ -131,9 +78,8 @@ static int Level_finish_wrapper(HSQUIRRELVM v) static int Level_spawn_wrapper(HSQUIRRELVM v) { - Level* _this; + Scripting::Level* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); const char* arg0; sq_getstring(v, 2, &arg0); const char* arg1; @@ -144,27 +90,10 @@ static int Level_spawn_wrapper(HSQUIRRELVM v) return 0; } -static int ScriptedObject_release_wrapper(SQUserPointer ptr, int ) -{ - ScriptedObject* _this = reinterpret_cast (ptr); - delete _this; - return 0; -} - -static int ScriptedObject_construct_wrapper(HSQUIRRELVM v) -{ - ScriptedObject* _this = new ScriptedObject(); - sq_setinstanceup(v, 1, _this); - sq_setreleasehook(v, 1, ScriptedObject_release_wrapper); - - return 0; -} - static int ScriptedObject_set_animation_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); const char* arg0; sq_getstring(v, 2, &arg0); @@ -175,9 +104,8 @@ static int ScriptedObject_set_animation_wrapper(HSQUIRRELVM v) static int ScriptedObject_get_animation_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); std::string return_value = _this->get_animation(); @@ -187,9 +115,8 @@ static int ScriptedObject_get_animation_wrapper(HSQUIRRELVM v) static int ScriptedObject_move_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float arg0; sq_getfloat(v, 2, &arg0); float arg1; @@ -202,9 +129,8 @@ static int ScriptedObject_move_wrapper(HSQUIRRELVM v) static int ScriptedObject_set_pos_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float arg0; sq_getfloat(v, 2, &arg0); float arg1; @@ -217,9 +143,8 @@ static int ScriptedObject_set_pos_wrapper(HSQUIRRELVM v) static int ScriptedObject_get_pos_x_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float return_value = _this->get_pos_x(); @@ -229,9 +154,8 @@ static int ScriptedObject_get_pos_x_wrapper(HSQUIRRELVM v) static int ScriptedObject_get_pos_y_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float return_value = _this->get_pos_y(); @@ -241,9 +165,8 @@ static int ScriptedObject_get_pos_y_wrapper(HSQUIRRELVM v) static int ScriptedObject_set_velocity_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float arg0; sq_getfloat(v, 2, &arg0); float arg1; @@ -256,9 +179,8 @@ static int ScriptedObject_set_velocity_wrapper(HSQUIRRELVM v) static int ScriptedObject_get_velocity_x_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float return_value = _this->get_velocity_x(); @@ -268,9 +190,8 @@ static int ScriptedObject_get_velocity_x_wrapper(HSQUIRRELVM v) static int ScriptedObject_get_velocity_y_wrapper(HSQUIRRELVM v) { - ScriptedObject* _this; + Scripting::ScriptedObject* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); float return_value = _this->get_velocity_y(); @@ -278,27 +199,10 @@ static int ScriptedObject_get_velocity_y_wrapper(HSQUIRRELVM v) return 1; } -static int Sound_release_wrapper(SQUserPointer ptr, int ) -{ - Sound* _this = reinterpret_cast (ptr); - delete _this; - return 0; -} - -static int Sound_construct_wrapper(HSQUIRRELVM v) -{ - Sound* _this = new Sound(); - sq_setinstanceup(v, 1, _this); - sq_setreleasehook(v, 1, Sound_release_wrapper); - - return 0; -} - static int Sound_play_music_wrapper(HSQUIRRELVM v) { - Sound* _this; + Scripting::Sound* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); const char* arg0; sq_getstring(v, 2, &arg0); @@ -309,9 +213,8 @@ static int Sound_play_music_wrapper(HSQUIRRELVM v) static int Sound_play_sound_wrapper(HSQUIRRELVM v) { - Sound* _this; + Scripting::Sound* _this; sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - assert(_this != 0); const char* arg0; sq_getstring(v, 2, &arg0); @@ -336,25 +239,21 @@ WrappedFunction supertux_global_functions[] = { }; static WrappedFunction supertux_Display_methods[] = { - { "constructor", &Display_construct_wrapper }, { "set_effect", &Display_set_effect_wrapper }, }; static WrappedFunction supertux_Camera_methods[] = { - { "constructor", &Camera_construct_wrapper }, { "shake", &Camera_shake_wrapper }, { "set_pos", &Camera_set_pos_wrapper }, { "set_mode", &Camera_set_mode_wrapper }, }; static WrappedFunction supertux_Level_methods[] = { - { "constructor", &Level_construct_wrapper }, { "finish", &Level_finish_wrapper }, { "spawn", &Level_spawn_wrapper }, }; static WrappedFunction supertux_ScriptedObject_methods[] = { - { "constructor", &ScriptedObject_construct_wrapper }, { "set_animation", &ScriptedObject_set_animation_wrapper }, { "get_animation", &ScriptedObject_get_animation_wrapper }, { "move", &ScriptedObject_move_wrapper }, @@ -367,7 +266,6 @@ static WrappedFunction supertux_ScriptedObject_methods[] = { }; static WrappedFunction supertux_Sound_methods[] = { - { "constructor", &Sound_construct_wrapper }, { "play_music", &Sound_play_music_wrapper }, { "play_sound", &Sound_play_sound_wrapper }, }; diff --git a/src/scripting/wrapper.interface.h b/src/scripting/wrapper.interface.h index 0b4513dd9..fe729d6a8 100644 --- a/src/scripting/wrapper.interface.h +++ b/src/scripting/wrapper.interface.h @@ -1,9 +1,8 @@ /** This file is processes by miniswig to produce the scripting API */ -#define SCRIPTING_API - #include "display.h" #include "camera.h" #include "level.h" #include "scripted_object.h" #include "sound.h" #include "functions.h" + diff --git a/tools/miniswig/create_wrapper.cpp b/tools/miniswig/create_wrapper.cpp index f5ebbfe9e..b3223bb1c 100644 --- a/tools/miniswig/create_wrapper.cpp +++ b/tools/miniswig/create_wrapper.cpp @@ -85,15 +85,13 @@ WrapperCreator::create_wrapper(Namespace* ns) out << "static WrappedFunction " << modulename << "_" << _class->name << "_methods[] = {\n"; - out << ind << "{ \"constructor\", &" - << _class->name << "_" << "construct_wrapper },\n"; for(std::vector::iterator i = _class->members.begin(); i != _class->members.end(); ++i) { ClassMember* member = *i; if(member->visibility != ClassMember::PUBLIC) continue; Function* function = dynamic_cast (member); - if(!function || function->type != Function::FUNCTION) + if(!function || function->type == Function::DESTRUCTOR) continue; out << ind << "{ \"" << function->name << "\", &" @@ -111,11 +109,15 @@ WrapperCreator::create_wrapper(Namespace* ns) void WrapperCreator::create_function_wrapper(Class* _class, Function* function) { - if(function->type == Function::CONSTRUCTOR) - throw std::runtime_error("Constructors not supported yet"); if(function->type == Function::DESTRUCTOR) - throw std::runtime_error("Destructors not supported yet"); - + assert(false); + + std::string ns_prefix; + if(selected_namespace != "") + ns_prefix = selected_namespace + "::"; + if(function->type == Function::CONSTRUCTOR) + function->name = "constructor"; + out << "static int "; if(_class != 0) { out << _class->name << "_"; @@ -124,15 +126,15 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function) << "{\n"; // avoid warning... if(_class == 0 && function->parameters.empty() - && function->return_type.is_void()) { + && function->return_type.is_void() + && function->type != Function::CONSTRUCTOR) { out << ind << "(void) v;\n"; } - // eventually retrieve pointer to class - if(_class != 0) { - out << ind << _class->name << "* _this;\n"; + // eventually retrieve pointer to class instance + if(_class != 0 && function->type != Function::CONSTRUCTOR) { + out << ind << ns_prefix << _class->name << "* _this;\n"; out << ind << "sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);\n"; - out << ind << "assert(_this != 0);\n"; } // declare and retrieve arguments @@ -145,6 +147,7 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function) ++i; } + // call function out << ind << "\n"; out << ind; @@ -153,17 +156,30 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function) out << " return_value = "; } if(_class != 0) { - out << "_this->"; - } else if(selected_namespace != "") { - out << selected_namespace << "::"; + if(function->type == Function::CONSTRUCTOR) { + out << ns_prefix << _class->name << "* _this = new " << ns_prefix; + } else { + out << "_this->"; + } + } else { + out << ns_prefix; + } + if(function->type == Function::CONSTRUCTOR) { + out << _class->name << "("; + } else { + out << function->name << "("; } - out << function->name << "("; for(size_t i = 0; i < function->parameters.size(); ++i) { if(i != 0) out << ", "; out << "arg" << i; } out << ");\n"; + if(function->type == Function::CONSTRUCTOR) { + out << ind << "sq_setinstanceup(v, 1, _this);\n"; + out << ind << "sq_setreleasehook(v, 1, " + << _class->name << "_release_hook);\n"; + } out << ind << "\n"; // push return value back on stack and return if(function->return_type.is_void()) { @@ -230,8 +246,7 @@ WrapperCreator::push_to_stack(const Type& type, const std::string& var) void WrapperCreator::create_class_wrapper(Class* _class) { - create_class_destruct_function(_class); - create_class_construct_function(_class); + bool release_hook_created = false; for(std::vector::iterator i = _class->members.begin(); i != _class->members.end(); ++i) { ClassMember* member = *i; @@ -240,33 +255,22 @@ WrapperCreator::create_class_wrapper(Class* _class) Function* function = dynamic_cast (member); if(!function) continue; - // don't wrap constructors and destructors (for now...) - if(function->type != Function::FUNCTION) + if(function->type == Function::CONSTRUCTOR + && !release_hook_created) { + create_class_release_hook(_class); + release_hook_created = true; + } + // don't wrap destructors + if(function->type == Function::DESTRUCTOR) continue; create_function_wrapper(_class, function); } } void -WrapperCreator::create_class_construct_function(Class* _class) -{ - out << "static int " << _class->name << "_construct_wrapper(HSQUIRRELVM v)\n"; - out << "{\n"; - out << ind << _class->name << "* _this = new " - << _class->name << "();\n"; - out << ind << "sq_setinstanceup(v, 1, _this);\n"; - out << ind << "sq_setreleasehook(v, 1, " - << _class->name << "_release_wrapper);\n"; - out << "\n"; - out << ind << "return 0;\n"; - out << "}\n"; - out << "\n"; -} - -void -WrapperCreator::create_class_destruct_function(Class* _class) +WrapperCreator::create_class_release_hook(Class* _class) { - out << "static int " << _class->name << "_release_wrapper(SQUserPointer ptr, int )\n" + out << "static int " << _class->name << "_release_hook(SQUserPointer ptr, int )\n" << "{\n" << ind << _class->name << "* _this = reinterpret_cast<" << _class->name << "*> (ptr);\n" diff --git a/tools/miniswig/create_wrapper.h b/tools/miniswig/create_wrapper.h index 0b546eb94..359c1edbc 100644 --- a/tools/miniswig/create_wrapper.h +++ b/tools/miniswig/create_wrapper.h @@ -20,8 +20,7 @@ public: void create_wrapper(Namespace* ns); void create_class_wrapper(Class* _class); - void create_class_construct_function(Class* _class); - void create_class_destruct_function(Class* _class); + void create_class_release_hook(Class* _class); void create_function_wrapper(Class* _class, Function* function); void prepare_argument(const Type& type, size_t idx, const std::string& var); void push_to_stack(const Type& type, const std::string& var); diff --git a/tools/miniswig/lexer.ll b/tools/miniswig/lexer.ll index 3285ec4c4..0e6229c2a 100644 --- a/tools/miniswig/lexer.ll +++ b/tools/miniswig/lexer.ll @@ -28,6 +28,7 @@ class { return T_CLASS; } struct { return T_STRUCT; } static { return T_STATIC; } +virtual { return T_VIRTUAL; } const { return T_CONST; } unsigned { return T_UNSIGNED; } signed { return T_SIGNED; } diff --git a/tools/miniswig/parser.yy b/tools/miniswig/parser.yy index e66b58ce3..6c25c9e5d 100644 --- a/tools/miniswig/parser.yy +++ b/tools/miniswig/parser.yy @@ -66,6 +66,7 @@ private: %token T_CLASS %token T_STRUCT %token T_STATIC +%token T_VIRTUAL %token T_CONST %token T_UNSIGNED %token T_SIGNED @@ -195,35 +196,45 @@ constructor_declaration: ; destructor_declaration: - '~' T_ID '(' ')' ';' + maybe_virtual '~' T_ID '(' ')' abstract_declaration ';' { currentFunction = new Function(); currentFunction->type = Function::DESTRUCTOR; - free($2); + free($3); $$ = currentFunction; } ; +maybe_virtual: + /* empty */ + | T_VIRTUAL +; + variable_declaration: type T_ID ';' ; function_declaration: - type T_ID '(' + maybe_virtual type T_ID '(' { currentFunction = new Function(); currentFunction->type = Function::FUNCTION; - currentFunction->return_type = *($1); - delete $1; - currentFunction->name = $2; - free($2); + currentFunction->return_type = *($2); + delete $2; + currentFunction->name = $3; + free($3); } - parameter_list ')' ';' + parameter_list ')' abstract_declaration ';' { $$ = currentFunction; } ; +abstract_declaration: + /* empty */ + | '=' T_INT +; + parameter_list: /* empty */ | parameters @@ -270,9 +281,13 @@ prefix_type_modifiers: prefix_type_modifier: T_UNSIGNED + { current_type->_unsigned = true; } | T_SIGNED + { current_type->_unsigned = false; } | T_STATIC + { current_type->_static = true; } | T_CONST + { current_type->_const = true; } ; postfix_type_modifiers: diff --git a/tools/miniswig/tree.h b/tools/miniswig/tree.h index 181a9fe44..b6f855466 100644 --- a/tools/miniswig/tree.h +++ b/tools/miniswig/tree.h @@ -48,7 +48,8 @@ private: class Type { public: Type() - : atomic_type(0), _const(false), _static(false), pointer(0), ref(0) + : atomic_type(0), _unsigned(false), _const(false), _static(false), + pointer(0), ref(0) { } void write_c_type(std::ostream& out) @@ -66,12 +67,15 @@ public: bool is_void() const { + if(atomic_type == 0) + return true; if(atomic_type == &BasicType::VOID && pointer == 0) return true; return false; } AtomicType* atomic_type; + bool _unsigned; bool _const; bool _static; // number of '*' in the type declaration... -- 2.11.0