script-squirrel.cpp

Go to the documentation of this file.
00001 #include "script-squirrel.h"
00002 #include <cstring>
00003 
00004 #ifdef SCRIPT_SUPPORT
00005 
00006 void registerStdLib(HSQUIRRELVM);
00007 
00008 /*
00009  * printfunc - Print function for Squirrel
00010  */
00011 void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
00012 {
00013     va_list arglist;
00014     va_start(arglist, s);
00015     vprintf(s, arglist);
00016     va_end(arglist);
00017 }
00018 
00019 /*
00020  * functionCall - Call function with arguments
00021  * fn   - name of function
00022  * args - string with argument types.
00023  *        's' = String
00024  *        'i' = Integer
00025  *        'f' = Float
00026  */
00027 bool functionCall(HSQUIRRELVM v, const char *fn, const char *args, ...)
00028 {
00029     int argCount = 0;
00030     va_list arglist;
00031     va_start(arglist, args);
00032 
00033     int top = sq_gettop(v); //save stack
00034     sq_pushroottable(v);    //pushes global table
00035     sq_pushstring(v, _SC(fn), -1);
00036 
00037     if (SQ_SUCCEEDED(sq_get(v, -2)))
00038     {
00039         sq_pushroottable(v); //push 'this'
00040 
00041         if (args != NULL)
00042         {
00043             for (int i = 0; i < strlen(args); i++)
00044             {
00045                 switch (args[i])
00046                 {
00047                     case 'S':
00048                     case 's':
00049                         //string
00050                         argCount++;
00051                         sq_pushstring(v, va_arg(arglist, char*), -1);
00052                         break;
00053                     case 'I':
00054                     case 'i':
00055                         //integer
00056                         argCount++;
00057                         sq_pushinteger(v, va_arg(arglist, int));
00058                         break;
00059                     case 'F':
00060                     case 'f':
00061                         //float
00062                         argCount++;
00063                         sq_pushfloat(v, va_arg(arglist, float));
00064                         break;
00065                 }
00066             }
00067         }
00068 
00069         sq_call(v, argCount + 1, 0);
00070     }
00071     else return false;
00072 
00073     sq_settop(v, top);
00074     va_end(arglist);
00075 
00076     return true;
00077 }
00078 
00079 /*
00080  * functionRegister
00081  * Registers a function in Squirrel VM
00082  */
00083 void functionRegister(HSQUIRRELVM v, SQFUNCTION f, const char *name)
00084 {
00085     sq_pushroottable(v);
00086     sq_pushstring(v, name, -1);
00087     sq_newclosure(v, f, 0);
00088     sq_createslot(v, -3);
00089     sq_pop(v, 1);
00090 }
00091 
00092 /*
00093  * Test function called from Squirrel (modified form Squirrel docs)
00094  * Prints the type of all arguments.
00095  */
00096 int testFunc(HSQUIRRELVM v)
00097 {
00098     int nargs = sq_gettop(v);
00099 
00100     for (int n = 1; n <= nargs; n++)
00101     {
00102         printf("arg: %d is ", n);
00103 
00104         switch (sq_gettype(v, n))
00105         {
00106             case OT_NULL:
00107                 printf("null");
00108                 break;
00109             case OT_INTEGER:
00110                 printf("integer");
00111                 break;
00112             case OT_FLOAT:
00113                 printf("float");
00114                 break;
00115             case OT_STRING:
00116                 printf("string");
00117                 break;
00118             case OT_TABLE:
00119                 printf("table");
00120                 break;
00121             case OT_ARRAY:
00122                 printf("array");
00123                 break;
00124             case OT_USERDATA:
00125                 printf("userdata");
00126                 break;
00127             case OT_CLOSURE:
00128                 printf("closure");
00129                 break;
00130             case OT_NATIVECLOSURE:
00131                 printf("nativeclosure");
00132                 break;
00133             case OT_GENERATOR:
00134                 printf("generator");
00135                 break;
00136             case OT_USERPOINTER:
00137                 printf("userpointer");
00138                 break;
00139             default:
00140                 printf("unknown");
00141         }
00142     }
00143     printf("\n");
00144     sq_pushinteger(v, nargs);
00145     return 1;
00146 }
00147 
00148 /******/
00149 
00150 ScriptSquirrel::ScriptSquirrel(const std::string &file) :
00151     Script(file)
00152 {
00153     vm = sq_open(1024);  //1024 byte stack
00154     sqstd_seterrorhandlers(vm);
00155     sq_setprintfunc(vm, printfunc);
00156 
00157     sq_pushroottable(vm);
00158 
00159     if (!SQ_SUCCEEDED(sqstd_dofile(vm, _SC(scriptName.c_str()), 0, 1)))
00160     {
00161         std::cerr << "Error: ScriptSquirrel: could not execute "
00162                   << scriptName << std::endl;
00163     }
00164     else
00165     {
00166         registerStdLib(vm);
00167 
00168         functionCall(vm, "", NULL);
00169         functionCall(vm, "init", NULL);
00170     }
00171 }
00172 
00173 ScriptSquirrel::~ScriptSquirrel()
00174 {
00175     functionCall(vm, "destroy", NULL);
00176 
00177     sq_pop(vm, 1);
00178     sq_close(vm);
00179 }
00180 
00181 void ScriptSquirrel::update()
00182 {
00183     functionCall(vm, "update", NULL);
00184 }
00185 
00186 bool ScriptSquirrel::execute(const std::string &functionName)
00187 {
00188     return functionCall(vm, functionName.c_str(), NULL);
00189 }
00190 
00191 void ScriptSquirrel::message(char *msg)
00192 {
00193     functionCall(vm, "message", "s", msg);
00194 }
00195 
00196 /******************************/
00197 /*
00198  * Standard Library Functions
00199  */
00200 int getName(HSQUIRRELVM v)
00201 {
00202     sq_pushstring(v, "no name", -1);
00203     return 1;
00204 }
00205 
00206 int getX(HSQUIRRELVM v)
00207 {
00208     sq_pushinteger(v, 0);
00209     return 1;
00210 }
00211 
00212 int getY(HSQUIRRELVM v)
00213 {
00214     sq_pushinteger(v, 0);
00215     return 1;
00216 }
00217 
00218 int getMap(HSQUIRRELVM v)
00219 {
00220     sq_pushstring(v, "map1.map", -1);
00221     return 1;
00222 }
00223 
00224 int getLevel(HSQUIRRELVM v)
00225 {
00226     sq_pushinteger(v, 0);
00227     return 1;
00228 }
00229 
00230 int getHealth(HSQUIRRELVM v)
00231 {
00232     sq_pushinteger(v, 0);
00233     return 1;
00234 }
00235 
00236 int getMaxHealth(HSQUIRRELVM v)
00237 {
00238     sq_pushinteger(v, 0);
00239     return 1;
00240 }
00241 
00242 int getAttack(HSQUIRRELVM v)
00243 {
00244     sq_pushinteger(v, 0);
00245     return 1;
00246 }
00247 
00248 int getDefense(HSQUIRRELVM v)
00249 {
00250     sq_pushinteger(v, 0);
00251     return 1;
00252 }
00253 
00254 int getLuck(HSQUIRRELVM v)
00255 {
00256     sq_pushinteger(v, 0);
00257     return 1;
00258 }
00259 
00260 int getVitality(HSQUIRRELVM v)
00261 {
00262     sq_pushinteger(v, 0);
00263     return 1;
00264 }
00265 
00266 /*
00267  *  Register standard functions for game script
00268  */
00269 void registerStdLib(HSQUIRRELVM v)
00270 {
00271     functionRegister(v, getName, "getName");
00272     functionRegister(v, getX, "getX");
00273     functionRegister(v, getY, "getY");
00274     functionRegister(v, getMap, "getMap");
00275     functionRegister(v, getLevel, "getLevel");
00276     functionRegister(v, getHealth, "getHealth");
00277     functionRegister(v, getMaxHealth, "getMaxHealth");
00278     functionRegister(v, getAttack, "getAttack");
00279     functionRegister(v, getDefense, "getDefense");
00280     functionRegister(v, getLuck, "getLuck");
00281     functionRegister(v, getVitality, "getVitality");
00282 }
00283 
00284 #endif

Generated on Fri Mar 30 15:39:16 2007 for TMW Server by  doxygen 1.3.9.1