diff options
author | truebrain <truebrain@openttd.org> | 2011-12-19 21:05:57 +0000 |
---|---|---|
committer | truebrain <truebrain@openttd.org> | 2011-12-19 21:05:57 +0000 |
commit | b0ac529a6ff4e087520a14d2a0169f445952e7e0 (patch) | |
tree | f545f15ff52b6c1ad6279f7e028f2a058465d672 /src/script/api | |
parent | 2ae87e72131a8e88327dbb0b5b286accddafe05d (diff) | |
download | openttd-b0ac529a6ff4e087520a14d2a0169f445952e7e0.tar.xz |
(svn r23635) -Add: introduce GSText, to allow translating GameScript text, even over network
Diffstat (limited to 'src/script/api')
-rw-r--r-- | src/script/api/game/game_text.hpp.sq | 31 | ||||
-rw-r--r-- | src/script/api/script_text.cpp | 167 | ||||
-rw-r--r-- | src/script/api/script_text.hpp | 134 | ||||
-rw-r--r-- | src/script/api/squirrel_export.awk | 15 | ||||
-rw-r--r-- | src/script/api/template/template_text.hpp.sq | 30 |
5 files changed, 376 insertions, 1 deletions
diff --git a/src/script/api/game/game_text.hpp.sq b/src/script/api/game/game_text.hpp.sq new file mode 100644 index 000000000..d43506580 --- /dev/null +++ b/src/script/api/game/game_text.hpp.sq @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */ + +#include "../script_text.hpp" +#include "../template/template_text.hpp.sq" + + +template <> const char *GetClassName<ScriptText, ST_GS>() { return "GSText"; } + +void SQGSText_Register(Squirrel *engine) +{ + DefSQClass<ScriptText, ST_GS> SQGSText("GSText"); + SQGSText.PreRegister(engine); + SQGSText.AddConstructor<void (ScriptText::*)(StringID string), 2>(engine, "xi"); + + SQGSText.DefSQConst(engine, ScriptText::SCRIPT_TEXT_MAX_PARAMETERS, "SCRIPT_TEXT_MAX_PARAMETERS"); + + SQGSText.DefSQAdvancedMethod(engine, &ScriptText::_set, "_set"); + SQGSText.DefSQAdvancedMethod(engine, &ScriptText::SetParam, "SetParam"); + SQGSText.DefSQAdvancedMethod(engine, &ScriptText::AddParam, "AddParam"); + + SQGSText.PostRegister(engine); +} diff --git a/src/script/api/script_text.cpp b/src/script/api/script_text.cpp new file mode 100644 index 000000000..10120bcde --- /dev/null +++ b/src/script/api/script_text.cpp @@ -0,0 +1,167 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file script_text.cpp Implementation of ScriptText. */ + +#include "../../stdafx.h" +#include "../../string_func.h" +#include "script_text.hpp" +#include "../squirrel.hpp" +#include "../../table/control_codes.h" + +ScriptText::ScriptText(StringID string) : + ZeroedMemoryAllocator(), + string(string) +{ +} + +ScriptText::~ScriptText() +{ + for (int i = 0; i < SCRIPT_TEXT_MAX_PARAMETERS; i++) { + free(this->params[i]); + if (this->paramt[i] != NULL) this->paramt[i]->Release(); + } +} + +SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm) +{ + if (parameter >= SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR; + + free(this->params[parameter]); + if (this->paramt[parameter] != NULL) this->paramt[parameter]->Release(); + + this->parami[parameter] = 0; + this->params[parameter] = NULL; + this->paramt[parameter] = NULL; + + switch (sq_gettype(vm, -1)) { + case OT_STRING: { + const SQChar *value; + sq_getstring(vm, -1, &value); + + this->params[parameter] = strdup(SQ2OTTD(value)); + break; + } + + case OT_INTEGER: { + SQInteger value; + sq_getinteger(vm, -1, &value); + + this->parami[parameter] = value; + break; + } + + case OT_INSTANCE: { + SQUserPointer real_instance = NULL; + HSQOBJECT instance; + + sq_getstackobj(vm, -1, &instance); + + /* Validate if it is a GSText instance */ + sq_pushroottable(vm); + sq_pushstring(vm, _SC("GSText"), -1); + sq_get(vm, -2); + sq_pushobject(vm, instance); + if (sq_instanceof(vm) != SQTrue) return SQ_ERROR; + sq_pop(vm, 3); + + /* Get the 'real' instance of this class */ + sq_getinstanceup(vm, -1, &real_instance, 0); + if (real_instance == NULL) return SQ_ERROR; + + ScriptText *value = static_cast<ScriptText *>(real_instance); + value->AddRef(); + this->paramt[parameter] = value; + break; + } + + default: return SQ_ERROR; + } + + if (this->paramc <= parameter) this->paramc = parameter + 1; + return 0; +} + +SQInteger ScriptText::SetParam(HSQUIRRELVM vm) +{ + if (sq_gettype(vm, 2) != OT_INTEGER) return SQ_ERROR; + + SQInteger k; + sq_getinteger(vm, 2, &k); + + if (k > SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR; + if (k < 1) return SQ_ERROR; + k--; + + return this->_SetParam(k, vm); +} + +SQInteger ScriptText::AddParam(HSQUIRRELVM vm) +{ + SQInteger res; + res = this->_SetParam(this->paramc, vm); + if (res != 0) return res; + + /* Push our own instance back on top of the stack */ + sq_push(vm, 1); + return 1; +} + +SQInteger ScriptText::_set(HSQUIRRELVM vm) +{ + int32 k; + + if (sq_gettype(vm, 2) == OT_STRING) { + const SQChar *key; + sq_getstring(vm, 2, &key); + const char *key_string = SQ2OTTD(key); + + if (strncmp(key_string, "param_", 6) != 0 || strlen(key_string) > 8) return SQ_ERROR; + k = atoi(key_string + 6); + } else if (sq_gettype(vm, 2) == OT_INTEGER) { + SQInteger key; + sq_getinteger(vm, 2, &key); + k = (int32)key; + } else { + return SQ_ERROR; + } + + if (k > SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR; + if (k < 1) return SQ_ERROR; + k--; + + return this->_SetParam(k, vm); +} + +const char *ScriptText::GetEncodedText() +{ + static char buf[1024]; + this->_GetEncodedText(buf, lastof(buf)); + return buf; +} + +char *ScriptText::_GetEncodedText(char *p, char *lastofp) +{ + p += Utf8Encode(p, SCC_ENCODED); + p += seprintf(p, lastofp, "%X", this->string); + for (int i = 0; i < this->paramc; i++) { + if (this->params[i] != NULL) { + p += seprintf(p, lastofp, ":\"%s\"", this->params[i]); + continue; + } + if (this->paramt[i] != NULL) { + p += seprintf(p, lastofp, ":"); + p = this->paramt[i]->_GetEncodedText(p, lastofp); + continue; + } + p += seprintf(p, lastofp,":%X", this->parami[i]); + } + + return p; +} diff --git a/src/script/api/script_text.hpp b/src/script/api/script_text.hpp new file mode 100644 index 000000000..9f994e1f3 --- /dev/null +++ b/src/script/api/script_text.hpp @@ -0,0 +1,134 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file script_text.hpp Everything to handle text which can be translated. */ + +#ifndef SCRIPT_TEXT_HPP +#define SCRIPT_TEXT_HPP + +#include "script_object.hpp" +#include "../../core/alloc_type.hpp" + +/** + * Internal parent object of all Text-like objects. + * @api -all + */ +class Text : public ScriptObject { +public: + /** + * Convert a ScriptText to a normal string. + * @return A string (in a static buffer), or NULL. + * @api -all + */ + virtual const char *GetEncodedText() = 0; +}; + +/** + * Interal used class to create a raw text in a Text object. + * @api -all + */ +class RawText : public Text { +public: + RawText(const char *text) : + text(strdup(text)) {} + ~RawText() { free(this->text); } + + /* virtual */ const char *GetEncodedText() { return this->text; } +private: + const char *text; +}; + +/** + * Class that handles all text related functions. You can define a language + * file in lang/english.txt, in the same format as OpenTTD does, including + * tags like {BLACK}, {STRING1} etc. The name given to this string is made + * available to you in ScriptText, for example: ScriptText.STR_NEWS, if your + * english.txt contains: STR_NEWS :{BLACK}Welcome {COMPANY}! + * + * In translation files like lang/dutch.txt you can then translate such + * strings, like: STR_NEWS :{BLACK}Hallo {COMPANY}! + * When the user has the dutch language selected, it will automatically use + * the translated string when available. The fallback language is always + * the english language. + * + * 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. + * + * @api game + */ +class ScriptText : public Text , public ZeroedMemoryAllocator { +public: + static const int SCRIPT_TEXT_MAX_PARAMETERS = 20; ///< The maximum amount of parameters you can give to one object. + + /** + * 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. + */ + ScriptText(StringID string); + ~ScriptText(); + +#ifndef DOXYGEN_API + /** + * Used for .param_N and [] set from Squirrel. + */ + SQInteger _set(HSQUIRRELVM vm); + + /** + * Set the parameter. + */ + SQInteger SetParam(HSQUIRRELVM vm); + + /** + * Add an parameter + */ + SQInteger AddParam(HSQUIRRELVM vm); +#else + /** + * Set the parameter to a value. + * @param parameter Which parameter t oset. + * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText. + */ + void SetParam(int parameter, Object value); + + /** + * Add a value as parameter (appending it). + * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText. + * @return The same object as on which this is called, so you can chain. + */ + ScriptText *AddParam(Object value); +#endif /* DOXYGEN_API */ + + /* virtual */ const char *GetEncodedText(); + +private: + StringID string; + char *params[SCRIPT_TEXT_MAX_PARAMETERS]; + int parami[SCRIPT_TEXT_MAX_PARAMETERS]; + ScriptText *paramt[SCRIPT_TEXT_MAX_PARAMETERS]; + int paramc; + + /** + * Internal function for recursive calling this function over multiple + * instances, while writing in the same buffer. + * @param p The current position in the buffer. + * @param lastofp The last position valid in the buffer. + * @return The new current position in the buffer. + */ + char *_GetEncodedText(char *p, char *lastofp); + + /** + * Set a parameter, where the value is the first item on the stack. + */ + SQInteger _SetParam(int k, HSQUIRRELVM vm); +}; + +#endif /* SCRIPT_TEXT_HPP */ diff --git a/src/script/api/squirrel_export.awk b/src/script/api/squirrel_export.awk index ed190deaf..cb9774db7 100644 --- a/src/script/api/squirrel_export.awk +++ b/src/script/api/squirrel_export.awk @@ -35,6 +35,17 @@ function dump_class_templates(name) print " template <> inline const " name " &GetParam(ForceType<const " name " &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(" name " *)instance; }" if (name == "ScriptEvent") { print " template <> inline int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"" realname "\", res, NULL, DefSQDestructorCallback<" name ">, true); return 1; }" + } else if (name == "ScriptText") { + print "" + print " template <> inline Text *GetParam(ForceType<Text *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) {" + print " if (sq_gettype(vm, index) == OT_INSTANCE) {" + print " return GetParam(ForceType<ScriptText *>(), vm, index, ptr);" + print " }" + print " if (sq_gettype(vm, index) == OT_STRING) {" + print " return new RawText(GetParam(ForceType<const char *>(), vm, index, ptr));" + print " }" + print " return NULL;" + print " }" } else { print " template <> inline int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, \"" realname "\", res, NULL, DefSQDestructorCallback<" name ">, true); return 1; }" } @@ -324,7 +335,7 @@ BEGIN { print "void SQ" api_cls "_Register(Squirrel *engine)" print "{" print " DefSQClass<" cls ", ST_" toupper(api) "> SQ" api_cls "(\"" api_cls "\");" - if (super_cls == "ScriptObject" || super_cls == "AIAbstractList::Valuator") { + if (super_cls == "Text" || super_cls == "ScriptObject" || super_cls == "AIAbstractList::Valuator") { print " SQ" api_cls ".PreRegister(engine);" } else { print " SQ" api_cls ".PreRegister(engine, \"" api_super_cls "\");" @@ -516,6 +527,8 @@ BEGIN { types = types "a" } else if (match(params[len], "^struct Array")) { types = types "a" + } else if (match(params[len], "^Text")) { + types = types "." } else { types = types "x" } diff --git a/src/script/api/template/template_text.hpp.sq b/src/script/api/template/template_text.hpp.sq new file mode 100644 index 000000000..7a44daf16 --- /dev/null +++ b/src/script/api/template/template_text.hpp.sq @@ -0,0 +1,30 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */ + +#include "../script_text.hpp" + +namespace SQConvert { + /* Allow ScriptText to be used as Squirrel parameter */ + template <> inline ScriptText *GetParam(ForceType<ScriptText *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptText *)instance; } + template <> inline ScriptText &GetParam(ForceType<ScriptText &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptText *)instance; } + template <> inline const ScriptText *GetParam(ForceType<const ScriptText *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptText *)instance; } + template <> inline const ScriptText &GetParam(ForceType<const ScriptText &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptText *)instance; } + + template <> inline Text *GetParam(ForceType<Text *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { + if (sq_gettype(vm, index) == OT_INSTANCE) { + return GetParam(ForceType<ScriptText *>(), vm, index, ptr); + } + if (sq_gettype(vm, index) == OT_STRING) { + return new RawText(GetParam(ForceType<const char *>(), vm, index, ptr)); + } + return NULL; + } +} // namespace SQConvert |