#include <stdexcept>
#include <sstream>
#include <fstream>
-#include <sqstdio.h>
#include <sqstdaux.h>
#include <sqstdblob.h>
-#include <sqstdsystem.h>
#include <sqstdmath.h>
#include <sqstdstring.h>
using namespace Scripting;
-ScriptManager* script_manager = 0;
+ScriptManager* ScriptManager::instance = NULL;
static void printfunc(HSQUIRRELVM, const char* str, ...)
{
}
ScriptManager::ScriptManager()
+ : parent(NULL)
{
- v = sq_open(1024);
- if(v == 0)
+ vm = sq_open(1024);
+ if(vm == 0)
throw std::runtime_error("Couldn't initialize squirrel vm");
+ sq_setforeignptr(vm, (SQUserPointer) this);
- // register default error handlers
- sqstd_seterrorhandlers(v);
// register squirrel libs
- sq_pushroottable(v);
- if(sqstd_register_bloblib(v) < 0)
- throw SquirrelError(v, "Couldn't register blob lib");
- if(sqstd_register_iolib(v) < 0)
- throw SquirrelError(v, "Couldn't register io lib");
- if(sqstd_register_systemlib(v) < 0)
- throw SquirrelError(v, "Couldn't register system lib");
- if(sqstd_register_mathlib(v) < 0)
- throw SquirrelError(v, "Couldn't register math lib");
- if(sqstd_register_stringlib(v) < 0)
- throw SquirrelError(v, "Couldn't register string lib");
+ sq_pushroottable(vm);
+ if(sqstd_register_bloblib(vm) < 0)
+ throw SquirrelError(vm, "Couldn't register blob lib");
+ if(sqstd_register_mathlib(vm) < 0)
+ throw SquirrelError(vm, "Couldn't register math lib");
+ if(sqstd_register_stringlib(vm) < 0)
+ throw SquirrelError(vm, "Couldn't register string lib");
+ // register supertux API
+ register_supertux_wrapper(vm);
+ sq_pop(vm, 1);
// register print function
- sq_setprintfunc(v, printfunc);
-
- // register supertux API
- register_supertux_wrapper(v);
+ sq_setprintfunc(vm, printfunc);
+ // register default error handlers
+ sqstd_seterrorhandlers(vm);
}
-ScriptManager::~ScriptManager()
+ScriptManager::ScriptManager(ScriptManager* parent)
{
- for(SquirrelVMs::iterator i = squirrel_vms.begin(); i != squirrel_vms.end(); ++i)
- sq_release(v, &(i->vm_obj));
+ this->parent = parent;
+ vm = parent->vm;
+ parent->childs.push_back(this);
+}
- sq_close(v);
+ScriptManager::~ScriptManager()
+{
+ for(SquirrelVMs::iterator i = squirrel_vms.begin();
+ i != squirrel_vms.end(); ++i)
+ sq_release(vm, &(i->vm_obj));
+
+ if(parent != NULL) {
+ parent->childs.erase(
+ std::remove(parent->childs.begin(), parent->childs.end(), this),
+ parent->childs.end());
+ } else {
+ sq_close(vm);
+ }
}
HSQUIRRELVM
-ScriptManager::create_thread()
+ScriptManager::create_thread(bool leave_thread_on_stack)
{
- HSQUIRRELVM vm = sq_newthread(v, 1024);
- if(vm == NULL)
- throw SquirrelError(v, "Couldn't create new VM");
+ HSQUIRRELVM new_vm = sq_newthread(vm, 1024);
+ if(new_vm == NULL)
+ throw SquirrelError(vm, "Couldn't create new VM");
+ sq_setforeignptr(new_vm, (SQUserPointer) this);
// retrieve reference to thread from stack and increase refcounter
HSQOBJECT vm_obj;
sq_resetobject(&vm_obj);
- if(SQ_FAILED(sq_getstackobj(v, -1, &vm_obj))) {
- throw SquirrelError(v, "Couldn't get coroutine vm from stack");
+ if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_obj))) {
+ throw SquirrelError(vm, "Couldn't get coroutine vm from stack");
}
- sq_addref(v, &vm_obj);
- sq_pop(v, 1);
+ sq_addref(vm, &vm_obj);
+
+ if(!leave_thread_on_stack)
+ sq_pop(vm, 1);
- squirrel_vms.push_back(SquirrelVM(vm, vm_obj));
+ squirrel_vms.push_back(SquirrelVM(new_vm, vm_obj));
- return vm;
+ return new_vm;
}
void
}
} catch(std::exception& e) {
std::cerr << "Problem executing script: " << e.what() << "\n";
- sq_release(v, &squirrel_vm.vm_obj);
+ sq_release(vm, &squirrel_vm.vm_obj);
i = squirrel_vms.erase(i);
continue;
}
}
if (vm_state != SQ_VMSTATE_SUSPENDED) {
- sq_release(v, &(squirrel_vm.vm_obj));
+ sq_release(vm, &(squirrel_vm.vm_obj));
i = squirrel_vms.erase(i);
} else {
++i;
{
assert(event.type >= 0 && event.type < WAKEUP_EVENT_COUNT);
// find the VM in the list and update it
- for(SquirrelVMs::iterator i = squirrel_vms.begin(); i != squirrel_vms.end(); ++i) {
+ for(SquirrelVMs::iterator i = squirrel_vms.begin();
+ i != squirrel_vms.end(); ++i) {
SquirrelVM& squirrel_vm = *i;
if(squirrel_vm.vm == vm)
{
ScriptManager::fire_wakeup_event(WakeupData event)
{
assert(event.type >= 0 && event.type < WAKEUP_EVENT_COUNT);
- for(SquirrelVMs::iterator i = squirrel_vms.begin(); i != squirrel_vms.end(); ++i)
- {
- SquirrelVM& vm = *i;
- if(vm.waiting_for_events.type == event.type && vm.waiting_for_events.type != NO_EVENT)
- {
- vm.wakeup_time = game_time;
- break;
- }
+ for(SquirrelVMs::iterator i = squirrel_vms.begin();
+ i != squirrel_vms.end(); ++i) {
+ SquirrelVM& vm = *i;
+ if(vm.waiting_for_events.type == event.type
+ && vm.waiting_for_events.type != NO_EVENT) {
+ vm.wakeup_time = game_time;
+ break;
}
+ }
+
+ for(std::vector<ScriptManager*>::iterator i = childs.begin();
+ i != childs.end(); ++i) {
+ ScriptManager* child = *i;
+ child->fire_wakeup_event(event);
+ }
}
void