Mercurial > hg > openttd
changeset 18803:4444cc87af24 draft
(svn r23651) -Feature: [NoGo] GSText now accepts string arguments as parameters to the constructor
author | yexo <yexo@openttd.org> |
---|---|
date | Wed, 21 Dec 2011 14:55:28 +0000 |
parents | 6a35af277c5e |
children | 71d835830d4c |
files | src/script/api/ai/ai_text.hpp.sq src/script/api/game/game_text.hpp.sq src/script/api/script_text.cpp src/script/api/script_text.hpp src/script/api/squirrel_export.awk src/script/squirrel_class.hpp src/script/squirrel_helper.hpp |
diffstat | 7 files changed, 76 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/script/api/ai/ai_text.hpp.sq +++ b/src/script/api/ai/ai_text.hpp.sq @@ -19,7 +19,7 @@ { DefSQClass<ScriptText, ST_AI> SQAIText("AIText"); SQAIText.PreRegister(engine); - SQAIText.AddConstructor<void (ScriptText::*)(StringID string), 2>(engine, "xi"); + SQAIText.AddSQAdvancedConstructor(engine); SQAIText.DefSQConst(engine, ScriptText::SCRIPT_TEXT_MAX_PARAMETERS, "SCRIPT_TEXT_MAX_PARAMETERS");
--- a/src/script/api/game/game_text.hpp.sq +++ b/src/script/api/game/game_text.hpp.sq @@ -19,7 +19,7 @@ { DefSQClass<ScriptText, ST_GS> SQGSText("GSText"); SQGSText.PreRegister(engine); - SQGSText.AddConstructor<void (ScriptText::*)(StringID string), 2>(engine, "xi"); + SQGSText.AddSQAdvancedConstructor(engine); SQGSText.DefSQConst(engine, ScriptText::SCRIPT_TEXT_MAX_PARAMETERS, "SCRIPT_TEXT_MAX_PARAMETERS");
--- a/src/script/api/script_text.cpp +++ b/src/script/api/script_text.cpp @@ -15,10 +15,34 @@ #include "../squirrel.hpp" #include "../../table/control_codes.h" -ScriptText::ScriptText(StringID string) : - ZeroedMemoryAllocator(), - string(string) +ScriptText::ScriptText(HSQUIRRELVM vm) : + ZeroedMemoryAllocator() { + int nparam = sq_gettop(vm) - 1; + if (nparam < 1) { + throw sq_throwerror(vm, _SC("You need to pass at least a StringID to the constructor")); + } + + /* First resolve the StringID. */ + SQInteger sqstring; + if (SQ_FAILED(sq_getinteger(vm, 2, &sqstring))) { + throw sq_throwerror(vm, _SC("First argument must be a valid StringID")); + } + this->string = sqstring; + + /* The rest of the parameters must be arguments. */ + for (int i = 0; i < nparam - 1; i++) { + /* Push the parameter to the top of the stack. */ + sq_push(vm, i + 3); + + if (SQ_FAILED(this->_SetParam(i, vm))) { + this->~ScriptText(); + throw sq_throwerror(vm, _SC("Invalid parameter")); + } + + /* Pop the parameter again. */ + sq_pop(vm, 1); + } } ScriptText::~ScriptText()
--- a/src/script/api/script_text.hpp +++ b/src/script/api/script_text.hpp @@ -59,8 +59,11 @@ * * If you use parameters in your strings, you will have to define those * parameters, for example like this: - * local text = ScriptText(ScriptText.STR_NEWS); text.AddParam(1); - * This will set the {COMPANY} to the name of Company 1. + * \code local text = ScriptText(ScriptText.STR_NEWS); + * text.AddParam(1); \endcode + * This will set the {COMPANY} to the name of Company 1. Alternatively you + * can directly give those arguments to the ScriptText constructor, like this: + * \code local text = ScriptText(ScriptText.STR_NEWS, 1); \endcode * * @api ai game */ @@ -68,12 +71,20 @@ public: static const int SCRIPT_TEXT_MAX_PARAMETERS = 20; ///< The maximum amount of parameters you can give to one object. +#ifndef DOXYGEN_API + /** + * The constructor wrapper from Squirrel. + */ + ScriptText(HSQUIRRELVM vm); +#else /** * Generate a text from string. You can set parameters to the instance which * can be required for the string. * @param string The string of the text. + * @param ... Optional arguments for this string. */ - ScriptText(StringID string); + ScriptText(StringID string, ...); +#endif ~ScriptText(); #ifndef DOXYGEN_API
--- a/src/script/api/squirrel_export.awk +++ b/src/script/api/squirrel_export.awk @@ -341,7 +341,11 @@ print " SQ" api_cls ".PreRegister(engine, \"" api_super_cls "\");" } if (virtual_class == "false" && super_cls != "ScriptEvent") { - print " SQ" api_cls ".AddConstructor<void (" cls "::*)(" cls_param[0] "), " cls_param[1]">(engine, \"" cls_param[2] "\");" + if (cls_param[2] == "v") { + print " SQ" api_cls ".AddSQAdvancedConstructor(engine);" + } else { + print " SQ" api_cls ".AddConstructor<void (" cls "::*)(" cls_param[0] "), " cls_param[1]">(engine, \"" cls_param[2] "\");" + } } print ""
--- a/src/script/squirrel_class.hpp +++ b/src/script/squirrel_class.hpp @@ -117,6 +117,12 @@ engine->AddMethod("constructor", DefSQConstructorCallback<CL, Func, Tnparam>, Tnparam, params); } + void AddSQAdvancedConstructor(Squirrel *engine) + { + using namespace SQConvert; + engine->AddMethod("constructor", DefSQAdvancedConstructorCallback<CL>, 0, NULL); + } + void PostRegister(Squirrel *engine) { engine->AddClassEnd();
--- a/src/script/squirrel_helper.hpp +++ b/src/script/squirrel_helper.hpp @@ -885,6 +885,28 @@ } } + /** + * A general template to handle creating of an instance with a complex + * constructor. + */ + template <typename Tcls> + inline SQInteger DefSQAdvancedConstructorCallback(HSQUIRRELVM vm) + { + try { + /* Find the amount of params we got */ + int nparam = sq_gettop(vm); + + /* Create the real instance */ + Tcls *instance = new Tcls(vm); + sq_setinstanceup(vm, -nparam, instance); + sq_setreleasehook(vm, -nparam, DefSQDestructorCallback<Tcls>); + instance->AddRef(); + return 0; + } catch (SQInteger e) { + return e; + } + } + } // namespace SQConvert #endif /* SQUIRREL_HELPER_HPP */