2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "scripting/squirrel_util.hpp"
23 #include <sqstdblob.h>
24 #include <sqstdmath.h>
25 #include <sqstdstring.h>
30 std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
32 std::ostringstream os;
33 switch(sq_gettype(v, i))
49 sq_getinteger(v, i, &val);
55 sq_getfloat(v, i, &val);
61 sq_getstring(v, i, &val);
62 os << "\"" << val << "\"";
68 sq_pushnull(v); //null iterator
69 while(SQ_SUCCEEDED(sq_next(v,i-1)))
76 //here -1 is the value and -2 is the key
77 os << squirrel2string(v, -2) << " => "
78 << squirrel2string(v, -1);
80 sq_pop(v,2); //pops key and val before the nex iteration
89 sq_pushnull(v); //null iterator
90 while(SQ_SUCCEEDED(sq_next(v,i-1)))
97 //here -1 is the value and -2 is the key
98 // we ignore the key, since that is just the index in an array
99 os << squirrel2string(v, -1);
101 sq_pop(v,2); //pops key and val before the nex iteration
113 case OT_NATIVECLOSURE:
114 os << "<native closure>";
141 void print_squirrel_stack(HSQUIRRELVM v)
143 printf("--------------------------------------------------------------\n");
144 int count = sq_gettop(v);
145 for(int i = 1; i <= count; ++i) {
147 switch(sq_gettype(v, i))
154 sq_getinteger(v, i, &val);
155 printf("integer (%d)", static_cast<int> (val));
160 sq_getfloat(v, i, &val);
161 printf("float (%f)", val);
166 sq_getstring(v, i, &val);
167 printf("string (%s)", val);
180 printf("closure(function)");
182 case OT_NATIVECLOSURE:
183 printf("native closure(C function)");
189 printf("userpointer");
204 printf("unknown?!?");
209 printf("--------------------------------------------------------------\n");
212 SQInteger squirrel_read_char(SQUserPointer file)
214 std::istream* in = reinterpret_cast<std::istream*> (file);
221 void compile_script(HSQUIRRELVM vm, std::istream& in, const std::string& sourcename)
223 if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in, sourcename.c_str(), true)))
224 throw SquirrelError(vm, "Couldn't parse script");
227 void compile_and_run(HSQUIRRELVM vm, std::istream& in,
228 const std::string& sourcename)
230 compile_script(vm, in, sourcename);
232 SQInteger oldtop = sq_gettop(vm);
235 sq_pushroottable(vm);
236 if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue)))
237 throw SquirrelError(vm, "Couldn't start script");
239 sq_settop(vm, oldtop);
243 // we can remove the closure in case the script was not suspended
244 if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
245 sq_settop(vm, oldtop-1);
249 HSQOBJECT create_thread(HSQUIRRELVM vm)
251 HSQUIRRELVM new_vm = sq_newthread(vm, 64);
253 throw SquirrelError(vm, "Couldn't create new VM");
256 sq_resetobject(&vm_object);
257 if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
258 throw SquirrelError(vm, "Couldn't get squirrel thread from stack");
259 sq_addref(vm, &vm_object);
266 HSQOBJECT vm_to_object(HSQUIRRELVM vm)
269 sq_resetobject(&object);
270 object._unVal.pThread = vm;
271 object._type = OT_THREAD;
276 HSQUIRRELVM object_to_vm(HSQOBJECT object)
278 if(object._type != OT_THREAD)
281 return object._unVal.pThread;
284 // begin: serialization functions
286 void store_float(HSQUIRRELVM vm, const char* name, float val)
288 sq_pushstring(vm, name, -1);
289 sq_pushfloat(vm, val);
290 if(SQ_FAILED(sq_createslot(vm, -3)))
291 throw scripting::SquirrelError(vm, "Couldn't add float value to table");
294 void store_int(HSQUIRRELVM vm, const char* name, int val)
296 sq_pushstring(vm, name, -1);
297 sq_pushinteger(vm, val);
298 if(SQ_FAILED(sq_createslot(vm, -3)))
299 throw scripting::SquirrelError(vm, "Couldn't add int value to table");
302 void store_string(HSQUIRRELVM vm, const char* name, const std::string& val)
304 sq_pushstring(vm, name, -1);
305 sq_pushstring(vm, val.c_str(), val.length());
306 if(SQ_FAILED(sq_createslot(vm, -3)))
307 throw scripting::SquirrelError(vm, "Couldn't add float value to table");
310 void store_bool(HSQUIRRELVM vm, const char* name, bool val)
312 sq_pushstring(vm, name, -1);
313 sq_pushbool(vm, val ? SQTrue : SQFalse);
314 if(SQ_FAILED(sq_createslot(vm, -3)))
315 throw scripting::SquirrelError(vm, "Couldn't add float value to table");
318 bool has_float(HSQUIRRELVM vm, const char* name)
320 sq_pushstring(vm, name, -1);
321 if (SQ_FAILED(sq_get(vm, -2))) return false;
326 bool has_int(HSQUIRRELVM vm, const char* name)
328 return has_float(vm, name);
331 bool has_string(HSQUIRRELVM vm, const char* name)
333 return has_float(vm, name);
336 bool has_bool(HSQUIRRELVM vm, const char* name)
338 return has_float(vm, name);
341 float read_float(HSQUIRRELVM vm, const char* name)
343 sq_pushstring(vm, name, -1);
344 if(SQ_FAILED(sq_get(vm, -2))) {
345 std::ostringstream msg;
346 msg << "Couldn't get float value for '" << name << "' from table";
347 throw scripting::SquirrelError(vm, msg.str());
351 if(SQ_FAILED(sq_getfloat(vm, -1, &result))) {
352 std::ostringstream msg;
353 msg << "Couldn't get float value for '" << name << "' from table";
354 throw scripting::SquirrelError(vm, msg.str());
361 int read_int(HSQUIRRELVM vm, const char* name)
363 sq_pushstring(vm, name, -1);
364 if(SQ_FAILED(sq_get(vm, -2))) {
365 std::ostringstream msg;
366 msg << "Couldn't get int value for '" << name << "' from table";
367 throw scripting::SquirrelError(vm, msg.str());
371 if(SQ_FAILED(sq_getinteger(vm, -1, &result))) {
372 std::ostringstream msg;
373 msg << "Couldn't get int value for '" << name << "' from table";
374 throw scripting::SquirrelError(vm, msg.str());
381 std::string read_string(HSQUIRRELVM vm, const char* name)
383 sq_pushstring(vm, name, -1);
384 if(SQ_FAILED(sq_get(vm, -2))) {
385 std::ostringstream msg;
386 msg << "Couldn't get string value for '" << name << "' from table";
387 throw scripting::SquirrelError(vm, msg.str());
391 if(SQ_FAILED(sq_getstring(vm, -1, &result))) {
392 std::ostringstream msg;
393 msg << "Couldn't get string value for '" << name << "' from table";
394 throw scripting::SquirrelError(vm, msg.str());
398 return std::string(result);
401 bool read_bool(HSQUIRRELVM vm, const char* name)
403 sq_pushstring(vm, name, -1);
404 if(SQ_FAILED(sq_get(vm, -2))) {
405 std::ostringstream msg;
406 msg << "Couldn't get bool value for '" << name << "' from table";
407 throw scripting::SquirrelError(vm, msg.str());
411 if(SQ_FAILED(sq_getbool(vm, -1, &result))) {
412 std::ostringstream msg;
413 msg << "Couldn't get bool value for '" << name << "' from table";
414 throw scripting::SquirrelError(vm, msg.str());
418 return result == SQTrue;
421 bool get_float(HSQUIRRELVM vm, const char* name, float& val) {
422 if (!has_float(vm, name)) return false;
423 val = read_float(vm, name);
427 bool get_int(HSQUIRRELVM vm, const char* name, int& val) {
428 if (!has_int(vm, name)) return false;
429 val = read_int(vm, name);
433 bool get_string(HSQUIRRELVM vm, const char* name, std::string& val) {
434 if (!has_string(vm, name)) return false;
435 val = read_string(vm, name);
439 bool get_bool(HSQUIRRELVM vm, const char* name, bool& val) {
440 if (!has_bool(vm, name)) return false;
441 val = read_bool(vm, name);
445 // end: serialization functions