script_text.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #include "../../stdafx.h"
00013 #include "../../string_func.h"
00014 #include "script_text.hpp"
00015 #include "../squirrel.hpp"
00016 #include "../../table/control_codes.h"
00017 
00018 ScriptText::ScriptText(HSQUIRRELVM vm) :
00019   ZeroedMemoryAllocator()
00020 {
00021   int nparam = sq_gettop(vm) - 1;
00022   if (nparam < 1) {
00023     throw sq_throwerror(vm, _SC("You need to pass at least a StringID to the constructor"));
00024   }
00025 
00026   /* First resolve the StringID. */
00027   SQInteger sqstring;
00028   if (SQ_FAILED(sq_getinteger(vm, 2, &sqstring))) {
00029     throw sq_throwerror(vm, _SC("First argument must be a valid StringID"));
00030   }
00031   this->string = sqstring;
00032 
00033   /* The rest of the parameters must be arguments. */
00034   for (int i = 0; i < nparam - 1; i++) {
00035     /* Push the parameter to the top of the stack. */
00036     sq_push(vm, i + 3);
00037 
00038     if (SQ_FAILED(this->_SetParam(i, vm))) {
00039       this->~ScriptText();
00040       throw sq_throwerror(vm, _SC("Invalid parameter"));
00041     }
00042 
00043     /* Pop the parameter again. */
00044     sq_pop(vm, 1);
00045   }
00046 }
00047 
00048 ScriptText::~ScriptText()
00049 {
00050   for (int i = 0; i < SCRIPT_TEXT_MAX_PARAMETERS; i++) {
00051     free(this->params[i]);
00052     if (this->paramt[i] != NULL) this->paramt[i]->Release();
00053   }
00054 }
00055 
00056 SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
00057 {
00058   if (parameter >= SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR;
00059 
00060   free(this->params[parameter]);
00061   if (this->paramt[parameter] != NULL) this->paramt[parameter]->Release();
00062 
00063   this->parami[parameter] = 0;
00064   this->params[parameter] = NULL;
00065   this->paramt[parameter] = NULL;
00066 
00067   switch (sq_gettype(vm, -1)) {
00068     case OT_STRING: {
00069       const SQChar *value;
00070       sq_getstring(vm, -1, &value);
00071 
00072       this->params[parameter] = strdup(SQ2OTTD(value));
00073       break;
00074     }
00075 
00076     case OT_INTEGER: {
00077       SQInteger value;
00078       sq_getinteger(vm, -1, &value);
00079 
00080       this->parami[parameter] = value;
00081       break;
00082     }
00083 
00084     case OT_INSTANCE: {
00085       SQUserPointer real_instance = NULL;
00086       HSQOBJECT instance;
00087 
00088       sq_getstackobj(vm, -1, &instance);
00089 
00090       /* Validate if it is a GSText instance */
00091       sq_pushroottable(vm);
00092       sq_pushstring(vm, _SC("GSText"), -1);
00093       sq_get(vm, -2);
00094       sq_pushobject(vm, instance);
00095       if (sq_instanceof(vm) != SQTrue) return SQ_ERROR;
00096       sq_pop(vm, 3);
00097 
00098       /* Get the 'real' instance of this class */
00099       sq_getinstanceup(vm, -1, &real_instance, 0);
00100       if (real_instance == NULL) return SQ_ERROR;
00101 
00102       ScriptText *value = static_cast<ScriptText *>(real_instance);
00103       value->AddRef();
00104       this->paramt[parameter] = value;
00105       break;
00106     }
00107 
00108     default: return SQ_ERROR;
00109   }
00110 
00111   if (this->paramc <= parameter) this->paramc = parameter + 1;
00112   return 0;
00113 }
00114 
00115 SQInteger ScriptText::SetParam(HSQUIRRELVM vm)
00116 {
00117   if (sq_gettype(vm, 2) != OT_INTEGER) return SQ_ERROR;
00118 
00119   SQInteger k;
00120   sq_getinteger(vm, 2, &k);
00121 
00122   if (k > SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR;
00123   if (k < 1) return SQ_ERROR;
00124   k--;
00125 
00126   return this->_SetParam(k, vm);
00127 }
00128 
00129 SQInteger ScriptText::AddParam(HSQUIRRELVM vm)
00130 {
00131   SQInteger res;
00132   res = this->_SetParam(this->paramc, vm);
00133   if (res != 0) return res;
00134 
00135   /* Push our own instance back on top of the stack */
00136   sq_push(vm, 1);
00137   return 1;
00138 }
00139 
00140 SQInteger ScriptText::_set(HSQUIRRELVM vm)
00141 {
00142   int32 k;
00143 
00144   if (sq_gettype(vm, 2) == OT_STRING) {
00145     const SQChar *key;
00146     sq_getstring(vm, 2, &key);
00147     const char *key_string = SQ2OTTD(key);
00148 
00149     if (strncmp(key_string, "param_", 6) != 0 || strlen(key_string) > 8) return SQ_ERROR;
00150     k = atoi(key_string + 6);
00151   } else if (sq_gettype(vm, 2) == OT_INTEGER) {
00152     SQInteger key;
00153     sq_getinteger(vm, 2, &key);
00154     k = (int32)key;
00155   } else {
00156     return SQ_ERROR;
00157   }
00158 
00159   if (k > SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR;
00160   if (k < 1) return SQ_ERROR;
00161   k--;
00162 
00163   return this->_SetParam(k, vm);
00164 }
00165 
00166 const char *ScriptText::GetEncodedText()
00167 {
00168   static char buf[1024];
00169   this->_GetEncodedText(buf, lastof(buf));
00170   return buf;
00171 }
00172 
00173 char *ScriptText::_GetEncodedText(char *p, char *lastofp)
00174 {
00175   p += Utf8Encode(p, SCC_ENCODED);
00176   p += seprintf(p, lastofp, "%X", this->string);
00177   for (int i = 0; i < this->paramc; i++) {
00178     if (this->params[i] != NULL) {
00179       p += seprintf(p, lastofp, ":\"%s\"", this->params[i]);
00180       continue;
00181     }
00182     if (this->paramt[i] != NULL) {
00183       p += seprintf(p, lastofp, ":");
00184       p = this->paramt[i]->_GetEncodedText(p, lastofp);
00185       continue;
00186     }
00187     p += seprintf(p, lastofp,":%X", this->parami[i]);
00188   }
00189 
00190   return p;
00191 }