X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=tools%2Fminiswig%2Fcreate_wrapper.cpp;h=1fba6e7bc1ab3555f1b35954e97bbd96ca652eac;hb=8f82a8e619346be81a3c1bf943baf68953f1f4e7;hp=8b0305bc6f836dd7e5be8922e365fb8ec356e616;hpb=28307f87a403c3d69a5294f42ab931e3094a8e57;p=supertux.git diff --git a/tools/miniswig/create_wrapper.cpp b/tools/miniswig/create_wrapper.cpp index 8b0305bc6..1fba6e7bc 100644 --- a/tools/miniswig/create_wrapper.cpp +++ b/tools/miniswig/create_wrapper.cpp @@ -10,6 +10,11 @@ WrapperCreator::create_wrapper(Namespace* ns) { std::string fromfile = original_file != "" ? original_file : inputfile; + if(selected_namespace != "") { + ns_prefix = selected_namespace; + ns_prefix += "::"; + } + // hpp file hppout << "/**\n" @@ -21,11 +26,31 @@ WrapperCreator::create_wrapper(Namespace* ns) << "#define __" << modulename << "_WRAPPER_H__\n" << "\n" << "#include \n" + << "#include \"wrapper.interface.hpp\"\n" << "\n" - << "void register_" << modulename << "_wrapper(HSQUIRRELVM v);\n" - << "\n" - << "#endif\n" + << "namespace SquirrelWrapper\n" + << "{\n" << "\n"; + + hppout << "void register_" << modulename << "_wrapper(HSQUIRRELVM v);\n" + << "\n"; + + for(std::vector::iterator i = ns->types.begin(); + i != ns->types.end(); ++i) { + AtomicType* type = *i; + Class* _class = dynamic_cast (type); + if(_class == 0) + continue; + + hppout << "void create_squirrel_instance(HSQUIRRELVM v, " + << ns_prefix << _class->name + << "* object, bool setup_releasehook = false);\n"; + } + hppout <<"\n" + << "}\n" + << "\n" + << "#endif\n" + << "\n"; // cpp header out << "/**\n" @@ -41,12 +66,11 @@ WrapperCreator::create_wrapper(Namespace* ns) << "#include \n" << "#include \"wrapper_util.hpp\"\n" << "#include \"wrapper.interface.hpp\"\n" + << "\n" + << "namespace SquirrelWrapper\n" + << "{\n" << "\n"; - if(selected_namespace != "") { - out << "using namespace " << selected_namespace << ";\n"; - out << "\n"; - } - + for(std::vector::iterator i = ns->types.begin(); i != ns->types.end(); ++i) { AtomicType* type = *i; @@ -59,16 +83,19 @@ WrapperCreator::create_wrapper(Namespace* ns) create_function_wrapper(0, *i); } - out << "void register_" << modulename << "_wrapper(HSQUIRRELVM v)\n"; - out << "{\n"; - out << ind << "sq_pushroottable(v);\n"; + out << "void register_" << modulename << "_wrapper(HSQUIRRELVM v)\n" + << "{\n" + << ind << "sq_pushroottable(v);\n"; create_register_constants_code(ns); create_register_functions_code(ns); create_register_classes_code(ns); - out << ind << "sq_pop(v, 1);\n"; - out << "}\n"; + out << ind << "sq_pop(v, 1);\n" + << "}\n" + << "\n" + << "}\n" + << "\n"; } void @@ -120,7 +147,7 @@ WrapperCreator::create_register_class_code(Class* _class) if(_class->super_classes.size() > 0) { if(_class->super_classes.size() > 1) { - std::stringstream msg; + std::ostringstream msg; msg << "Multiple inheritance not supported (at class '" << _class->name << "')"; throw std::runtime_error(msg.str()); @@ -133,7 +160,7 @@ WrapperCreator::create_register_class_code(Class* _class) out << ind << "if(sq_newclass(v, " << (_class->super_classes.size() > 0 ? "SQTrue" : "SQFalse") << ") < 0) {\n"; - out << ind << ind << "std::stringstream msg;\n"; + out << ind << ind << "std::ostringstream msg;\n"; out << ind << ind << "msg << \"Couldn't create new class '" << _class->name << "'\";\n"; out << ind << ind << "throw SquirrelError(v, msg.str());\n"; @@ -199,7 +226,7 @@ WrapperCreator::create_register_slot_code(const std::string& what, const std::string& name) { out << ind << "if(sq_createslot(v, -3) < 0) {\n"; - out << ind << ind << "std::stringstream msg;\n"; + out << ind << ind << "std::ostringstream msg;\n"; out << ind << ind << "msg << \"Couldn't register " << what << "'" << name << "'\";\n"; out << ind << ind << "throw SquirrelError(v, msg.str());\n"; @@ -287,12 +314,16 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function) } out << ind << "\n"; // push return value back on stack and return - if(function->return_type.is_void()) { - if(function->docu_comment.find("@SUSPEND@") != std::string::npos) { - out << ind << "return sq_suspendvm(v);\n"; - } else { - out << ind << "return 0;\n"; + if(function->suspend) { + if(!function->return_type.is_void()) { + std::stringstream msg; + msg << "Function '" << function->name << "' declared as suspend" + << " but has a return value."; + throw std::runtime_error(msg.str()); } + out << ind << "return sq_suspendvm(v);\n"; + } else if(function->return_type.is_void()) { + out << ind << "return 0;\n"; } else { push_to_stack(function->return_type, "return_value"); out << ind << "return 1;\n"; @@ -355,7 +386,8 @@ WrapperCreator::push_to_stack(const Type& type, const std::string& var) void WrapperCreator::create_class_wrapper(Class* _class) { - bool release_hook_created = false; + create_class_release_hook(_class); + create_squirrel_instance(_class); for(std::vector::iterator i = _class->members.begin(); i != _class->members.end(); ++i) { ClassMember* member = *i; @@ -364,11 +396,6 @@ WrapperCreator::create_class_wrapper(Class* _class) Function* function = dynamic_cast (member); if(!function) continue; - 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; @@ -377,12 +404,44 @@ WrapperCreator::create_class_wrapper(Class* _class) } void +WrapperCreator::create_squirrel_instance(Class* _class) +{ + out << "void create_squirrel_instance(HSQUIRRELVM v, " + << ns_prefix << _class->name + << "* object, bool setup_releasehook)\n" + << "{\n" + << ind << "sq_pushstring(v, \"" << _class->name << "\", -1);\n" + << ind << "if(sq_get(v, -2) < 0) {\n" + << ind << ind << "std::ostringstream msg;\n" + << ind << ind << "msg << \"Couldn't resolved squirrel type '" + << _class->name << "'\";\n" + << ind << ind << "throw SquirrelError(v, msg.str());\n" + << ind << "}\n" + << "\n" + << ind << "if(sq_createinstance(v, -1) < 0 || " + << "sq_setinstanceup(v, -1, object) < 0) {\n" + << ind << ind << "std::ostringstream msg;\n" + << ind << ind << "msg << \"Couldn't setup squirrel instance for " + << "object of type '" << _class->name << "'\";\n" + << ind << ind << "throw SquirrelError(v, msg.str());\n" + << ind << "}\n" + << ind << "sq_remove(v, -2);\n" + << "\n" + << ind << "if(setup_releasehook) {\n" + << ind << ind << "sq_setreleasehook(v, -1, " + << _class->name << "_release_hook);\n" + << ind << "}\n" + << "}\n"; +} + +void WrapperCreator::create_class_release_hook(Class* _class) { out << "static int " << _class->name << "_release_hook(SQUserPointer ptr, int )\n" << "{\n" - << ind << _class->name - << "* _this = reinterpret_cast<" << _class->name << "*> (ptr);\n" + << ind << ns_prefix << _class->name + << "* _this = reinterpret_cast<" << ns_prefix << _class->name + << "*> (ptr);\n" << ind << "delete _this;\n" << ind << "return 0;\n" << "}\n"