HSQOBJECT class_init(HSQUIRRELVM v,SQFUNCTION c,const SQChar * p_name) { HSQOBJECT class_id; sq_pushroottable(v); sq_pushstring(v,p_name,-1); sq_newclass(v,SQFalse); sq_getstackobj(v,-1,&class_id); sq_settypetag(v,-1,&class_id); HSQOBJECT string_constructor; sq_pushstring(v,_SC("constructor"),-1); sq_resetobject(&string_constructor); sq_getstackobj(v,-1,&string_constructor); sq_newclosure(v,c,0); sq_newslot(v,-3,false); sq_pushstring(v,_SC("_cloned"),-1); sq_newclosure(v,clone<T>,0); sq_newslot(v,-3,false); sq_newslot(v,-3,false); sq_pop(v,1); return class_id; }
void SquirrelThread::initThread(HSQUIRRELVM parentVm) { m_oldTop = -1; m_parentVm = parentVm; createThread(); // create a local environment for the m_thread HSQOBJECT env; sq_resetobject(&env); sq_newtable(m_thread); // store the object in env if(sq_getstackobj(m_thread, -1, &env) < 0) { return; } sq_addref(m_thread, &env); sq_pop(m_thread, 1); // remove env from stack // set old roottable as delegate on env sq_pushobject(m_thread, env); // push env sq_pushroottable(m_thread); // [env, root] sq_setdelegate(m_thread, -2); // env.set_delegate(root) sq_pop(m_thread, 1); // pop env // set env as new roottable sq_pushobject(m_thread, env); sq_setroottable(m_thread); sq_release(m_thread, &env); }
template <> inline Array *GetParam(ForceType<Array *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQObject obj; sq_getstackobj(vm, index, &obj); sq_pushobject(vm, obj); sq_pushnull(vm); SmallVector<int32, 2> data; while (SQ_SUCCEEDED(sq_next(vm, -2))) { SQInteger tmp; if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) { *data.Append() = (int32)tmp; } else { sq_pop(vm, 4); throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric")); } sq_pop(vm, 2); } sq_pop(vm, 2); Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length()); arr->size = data.Length(); memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length()); *ptr->Append() = arr; return arr; }
bool Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret, int suspend) { assert(!this->crashed); /* Store the stack-location for the return value. We need to * restore this after saving or the stack will be corrupted * if we're in the middle of a DoCommand. */ SQInteger last_target = this->vm->_suspended_target; /* Store the current top */ int top = sq_gettop(this->vm); /* Go to the instance-root */ sq_pushobject(this->vm, instance); /* Find the function-name inside the script */ sq_pushstring(this->vm, OTTD2SQ(method_name), -1); if (SQ_FAILED(sq_get(this->vm, -2))) { DEBUG(misc, 0, "[squirrel] Could not find '%s' in the class", method_name); sq_settop(this->vm, top); return false; } /* Call the method */ sq_pushobject(this->vm, instance); if (SQ_FAILED(sq_call(this->vm, 1, ret == NULL ? SQFalse : SQTrue, SQTrue, suspend))) return false; if (ret != NULL) sq_getstackobj(vm, -1, ret); /* Reset the top, but don't do so for the AI main function, as we need * a correct stack when resuming. */ if (suspend == -1 || !this->IsSuspended()) sq_settop(this->vm, top); /* Restore the return-value location. */ this->vm->_suspended_target = last_target; return true; }
int CEventNatives::RemoveHandler(SQVM* pVM) { // get the event name const char* szEventName; sq_getstring(pVM, 2, &szEventName); // get the entity which it should effect CEntity* pEntity = sq_toentity(pVM, 3); // get the function to execute upon calling the event SQObject o; sq_getstackobj(pVM, 4, &o); // if we have a valid entity, use it if(pEntity) { sEventData event; event.pFunction = o; // get the resource calling this function event.pResource = g_pResourceManager->Get(pVM); assert(event.pResource); // pass the result to the script sq_pushbool(pVM, pEntity->RemoveEvent(szEventName, event)); } else sq_pushbool(pVM, false); return 1; }
static inline void sq_create_delegate_table(HSQUIRRELVM vm, SQRegFunction *methods, HSQOBJECT *handle) { sq_newtable(vm); sq_insert_reg_funcs(vm, methods); sq_resetobject(handle); sq_getstackobj(vm, -1, handle); sq_addref(vm, handle); }
void SquirrelObject::AttachToStackObject(int idx) { HSQOBJECT t; sq_getstackobj(m_Vm.GetVMPtr(),idx,&t); sq_addref(m_Vm.GetVMPtr(),&t); sq_release(m_Vm.GetVMPtr(),&_o); _o = t; }
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; }
void CSquirrelVM::SetClassInstance(const char* szClassName, void * pInstance) { sq_setinstanceup(m_pVM, 1, (SQUserPointer *) pInstance); sq_setreleasehook(m_pVM, 1, deleteClassInstance); HSQOBJECT instance; sq_resetobject(&instance); sq_getstackobj(m_pVM, 1, &instance); sq_addref(m_pVM, &instance); m_Instances.insert(std::pair<void*, HSQOBJECT>(pInstance, instance)); }
void loadVariablePath(HSQUIRRELVM vm, const std::vector<std::string>& path) { for (const std::string& i : path) { sq_pushstring(vm, i.c_str(), i.size()); CSQ(sq_get(vm, -2)); } HSQOBJECT h; CSQ(sq_getstackobj(vm, -1, &h)); sq_pop(vm, path.size() - 1); sq_pushobject(vm, h); }
bool SQDbgServer::Init() { //creates an environment table for the debugger sq_newtable(_v); sq_getstackobj(_v,-1,&_debugroot); sq_addref(_v,&_debugroot); //creates a emptyslot to store the watches sq_pushstring(_v,_SC("watches"),-1); sq_pushnull(_v); sq_createslot(_v,-3); sq_pushstring(_v,_SC("beginelement"),-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,beginelement,1); sq_setparamscheck(_v,2,_SC(".s")); sq_createslot(_v,-3); sq_pushstring(_v,_SC("endelement"),-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,endelement,1); sq_setparamscheck(_v,2,_SC(".s")); sq_createslot(_v,-3); sq_pushstring(_v,_SC("attribute"),-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,attribute,1); sq_setparamscheck(_v,3,_SC(".ss")); sq_createslot(_v,-3); sq_pop(_v,1); //stores debug hook and error handler in the registry sq_pushregistrytable(_v); sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,debug_hook,1); sq_createslot(_v,-3); sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,error_handler,1); sq_createslot(_v,-3); sq_pop(_v,1); //sets the error handlers SetErrorHandlers(); return true; }
//------------------------------------------------------------------------------ void Entity::unserializeState(const Variant & o, const SerializationContext & context) { // Name m_name = o["name"].getString(); // Enabled flag bool bEnabled = false; sn::unserialize(o["enabled"], bEnabled, true); setFlag(SN_EF_ENABLED, bEnabled); // Deserialize tags removeAllTags(); std::unordered_set<std::string> tags; sn::unserialize(o["tags"], tags); for (auto it = tags.begin(); it != tags.end(); ++it) { const std::string & tagName = *it; addTag(tagName); } // Script auto & script = o["script"]; if (script.isDictionary()) { std::string classPath = script["class"].getString(); if (!classPath.empty()) { // TODO should be context.squirrelVM HSQUIRRELVM vm = Application::get().getScriptManager().getVM(); if (m_script.create(vm, classPath)) { // Set the "entity" member if (pushScriptObject(vm)) { HSQOBJECT entityObj; sq_getstackobj(vm, -1, &entityObj); m_script.setMember("entity", entityObj); sq_pop(vm, 1); // pop entityObj } // Call onCreate m_script.callMethod("onCreate"); } } } // TODO Unserialize script members }
MyScript SqEnv::compile_script(const std::string& s, const SQChar * debugInfo)const { // AutoLock a(&_m); Sqrat::DefaultVM::Set(*_vm); SQObject obj; if(SQ_FAILED(sqstd_loadfile(*_vm, s.c_str(), true))) { //return false; throw Sqrat::Exception(Sqrat::LastErrorString(*_vm)); } sq_getstackobj(*_vm,-1,&obj); //sq_pop(_vm,1); //mco return MyScript(*_vm, obj); }
MyScript SqEnv::compile_buffer(const SQChar *s, size_t length, const SQChar * debugInfo)const { //AutoLock a(&_m); Sqrat::DefaultVM::Set(*_vm); SQObject obj; if(SQ_FAILED(sq_compilebuffer(*_vm, s, static_cast<SQInteger>(length), debugInfo, true))) { throw Sqrat::Exception(Sqrat::LastErrorString(*_vm)); } sq_getstackobj(*_vm,-1,&obj); return MyScript(*_vm, obj); }
HSQOBJECT create_thread(HSQUIRRELVM vm) { HSQUIRRELVM new_vm = sq_newthread(vm, 64); if(new_vm == NULL) throw SquirrelError(vm, "Couldn't create new VM"); HSQOBJECT vm_object; sq_resetobject(&vm_object); if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object))) throw SquirrelError(vm, "Couldn't get squirrel thread from stack"); sq_addref(vm, &vm_object); sq_pop(vm, 1); return vm_object; }
void ThreadQueue::add(HSQUIRRELVM vm) { // create a weakref to the VM HSQOBJECT vm_obj = vm_to_object(vm); sq_pushobject(global_vm, vm_obj); sq_weakref(global_vm, -1); HSQOBJECT object; if(SQ_FAILED(sq_getstackobj(global_vm, -1, &object))) { sq_pop(global_vm, 2); throw SquirrelError(global_vm, "Couldn't get thread weakref from vm"); } sq_addref(global_vm, &object); threads.push_back(object); sq_pop(global_vm, 2); }
void TimeScheduler::schedule_thread(HSQUIRRELVM scheduled_vm, float time) { // create a weakref to the VM SQObject vm_obj = vm_to_object(scheduled_vm); sq_pushobject(global_vm, vm_obj); sq_weakref(global_vm, -1); ScheduleEntry entry; if(SQ_FAILED(sq_getstackobj(global_vm, -1, & entry.thread_ref))) { sq_pop(global_vm, 2); throw SquirrelError(global_vm, "Couldn't get thread weakref from vm"); } entry.wakeup_time = time; sq_addref(global_vm, & entry.thread_ref); sq_pop(global_vm, 2); schedule.push_back(entry); std::push_heap(schedule.begin(), schedule.end()); }
void CSquirrelVM::PushInstance(const char* szClassName, void * pInstance) { // TODO:: remove instances when they are destoryed if (m_Instances.find(pInstance) != m_Instances.end()) { sq_pushobject(m_pVM, m_Instances.find(pInstance)->second); } else { CreateConstructNativeClassInstance(m_pVM, szClassName); sq_setinstanceup(m_pVM, -1, (SQUserPointer *) pInstance); sq_setreleasehook(m_pVM, -1, deleteClassInstance); HSQOBJECT instance; sq_resetobject(&instance); sq_getstackobj(m_pVM, -1, &instance); sq_addref(m_pVM, &instance); m_Instances.insert(std::pair<void*, HSQOBJECT>(pInstance, instance)); } }
bool CreateNativeClassInstance(HSQUIRRELVM v, const SQChar *classname, SQUserPointer ud, SQRELEASEHOOK hook) { // If we don't do this, SquirrelVM keeps an old pointer around and this // will be used by SquirrelObject. That crashes when using several VMs. int oldtop = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v, classname, -1); if (SQ_FAILED(sq_rawget(v, -2))){ //Get the class (created with sq_newclass()). sq_settop(v, oldtop); return false; } //sq_pushroottable(v); if (SQ_FAILED(sq_createinstance(v, -1))) { sq_settop(v, oldtop); return false; } #ifdef SQ_USE_CLASS_INHERITANCE HSQOBJECT ho; sq_getstackobj(v, -1, &ho); // OT_INSTANCE SquirrelObject instance(ho); SqPlus::PopulateAncestry(v, instance, ud); #endif sq_remove(v, -3); //removes the root table sq_remove(v, -2); //removes the class if (SQ_FAILED(sq_setinstanceup(v, -1, ud))) { sq_settop(v, oldtop); return false; } sq_setreleasehook(v, -1, hook); return true; }
SQInteger Sq_RegisterMenu(HSQUIRRELVM v) { const SQChar *What; HSQOBJECT Handler; sq_resetobject(&Handler); sq_getstackobj(v, 2, &Handler); sq_getstring(v, 3, &What); sq_addref(v, &Handler); SquirrelHook *NewHook = (SquirrelHook*)malloc(sizeof(SquirrelHook)); if(!NewHook) exit(0); // add new menu command strlcpy(NewHook->Name, What, sizeof(NewHook->Name)); NewHook->Script = v; NewHook->Function = Handler; NewHook->Prev = NULL; NewHook->Next = AllMenuCommands; if(AllMenuCommands) AllMenuCommands->Prev = NewHook; AllMenuCommands = NewHook; return 0; }
//------------------------------------------------------------------------------ bool Script::compileString( const std::string & sourceCode, const std::string & scriptName) { releaseObject(); if(SQ_FAILED(sq_compilebuffer(m_vm, sourceCode.c_str(), static_cast<SQInteger>(sourceCode.size()), scriptName.c_str(), true // raise error ))) { return false; } sq_getstackobj(m_vm, -1, &m_object); sq_addref(m_vm, &m_object); sq_pop(m_vm, 1); return true; }
SQRESULT sqrat_import(HSQUIRRELVM v) { const SQChar* moduleName; HSQOBJECT table; SQRESULT res = SQ_OK; SQInteger top = sq_gettop(v); sq_getstring(v, -2, &moduleName); sq_getstackobj(v, -1, &table); sq_addref(v, &table); sq_settop(v, 0); // Clear Stack sq_pushobject(v, table); // Push the target table onto the stack if(SQ_FAILED(sqrat_importscript(v, moduleName))) { res = sqrat_importbin(v, moduleName); } sq_settop(v, 0); // Clean up the stack (just in case the module load leaves it messy) sq_pushobject(v, table); // return the target table sq_release(v, &table); return res; }
void SquirrelThread::createThread() { //assert(!m_thread); m_thread = sq_newthread(m_parentVm, 1024); // create m_thread and store it on the stack if (0 == m_thread) { ASSERT_NOT_REACHED(); return; } // Create a HSQOBJECT to hold a reference to the m_thread sq_resetobject(&m_threadObj); // init the object // store m_thread created by sq_newthread into thread_obj if (sq_getstackobj(m_parentVm, -1, &m_threadObj) < 0) { ASSERT_NOT_REACHED(); return; } sq_addref(m_parentVm, &m_threadObj); // add reference sq_pop(m_parentVm, 1); // remove the m_thread from the stack }
/* static */ bool Squirrel::CreateClassInstanceVM(HSQUIRRELVM vm, const char *class_name, void *real_instance, HSQOBJECT *instance, SQRELEASEHOOK release_hook) { int oldtop = sq_gettop(vm); /* First, find the class */ sq_pushroottable(vm); sq_pushstring(vm, OTTD2SQ(class_name), -1); if (SQ_FAILED(sq_get(vm, -2))) { DEBUG(misc, 0, "[squirrel] Failed to find class by the name '%s'", class_name); sq_settop(vm, oldtop); return false; } /* Create the instance */ if (SQ_FAILED(sq_createinstance(vm, -1))) { DEBUG(misc, 0, "[squirrel] Failed to create instance for class '%s'", class_name); sq_settop(vm, oldtop); return false; } if (instance != NULL) { /* Find our instance */ sq_getstackobj(vm, -1, instance); /* Add a reference to it, so it survives for ever */ sq_addref(vm, instance); } sq_remove(vm, -2); // Class-name sq_remove(vm, -2); // Root-table /* Store it in the class */ sq_setinstanceup(vm, -1, real_instance); if (release_hook != NULL) sq_setreleasehook(vm, -1, release_hook); if (instance != NULL) sq_settop(vm, oldtop); return true; }
SQInteger _VwSetTimerInternal(HSQUIRRELVM v, TIMERPROC lpTimerFunc) { SQInteger nargs = sq_gettop(v); SQInteger Handle = 0; SQInteger uElapse = 0; LPCTSTR pstrFunc = NULL; SetTimerParam* pTimerParam = NULL; SQUserPointer nRet = NULL; if (!v || 3 + 1 != nargs) {goto _Exit_;} if (OT_INTEGER != sq_gettype(v, 2)) {goto _Exit_;} if (OT_STRING != sq_gettype(v, 3)) {goto _Exit_;} if (OT_INSTANCE != sq_gettype(v, 4)) {goto _Exit_;} sq_getinteger(v, 2, &uElapse); sq_getstring(v, 3, &pstrFunc); pTimerParam = new SetTimerParam(); pTimerParam->v = v; pTimerParam->sFunc = pstrFunc; sq_getstackobj(v, 4, &pTimerParam->Obj); CScriptMgr* pMgr = (CScriptMgr*)sq_getforeignptr(v); if (!pMgr) {goto _Exit_;} CPaintManagerUI* pPM = pMgr->GetManager(); if (!pPM) {goto _Exit_;} if (NULL != ::SetTimer(pPM->GetPaintWindow(), (UINT_PTR)pTimerParam, uElapse, lpTimerFunc)) { nRet = (SQUserPointer)pTimerParam; } else { nRet = NULL; } _Exit_: sq_pushuserpointer(v, nRet); return 1; }
static SQRESULT sq_libclang_parseTranslationUnit(HSQUIRRELVM v){ SQ_FUNC_VARS(v); GET_libclang_INSTANCE(); if(sq_gettype(v, 2) != OT_CLOSURE) return sq_throwerror(v, _SC("invalid fisrt parameter expected closure")); SQ_GET_STRING(v, 3, fname); release_visitor_cb(self); sq_getstackobj(v, 2, &self->visitor_cb); sq_addref(v, &self->visitor_cb); const char *cl_argsDefault[] = {"-I."}; const char **cl_args = cl_argsDefault; int cl_argNum = 1; int rc = 0; const int cl_arg_start = 4; bool has_extra_params = _top_ >= cl_arg_start; if(has_extra_params) { //create cl_args with extra parameters cl_argNum = _top_ - (cl_arg_start -1); cl_args = (const char **)sq_malloc(sizeof(char*) * cl_argNum); for(int i=cl_arg_start; i <= _top_; ++i) { const SQChar *p; if(sq_gettype(v, i) == OT_STRING) { rc = sq_getstring(v, i, &p); } else { rc = sq_throwerror(v, _SC("not a string parameter at %d"), i); goto cleanup; } cl_args[i-cl_arg_start] = p; } } CXTranslationUnit TU; CXCursor rootCursor; TU = dlclang_parseTranslationUnit(self->index, fname, cl_args, cl_argNum, 0, 0, CXTranslationUnit_Incomplete); if (TU == NULL) { rc = sq_throwerror(v, _SC("clang_parseTranslationUnit for %s failed\n"), fname); goto cleanup; } rootCursor = dlclang_getTranslationUnitCursor(TU); dlclang_visitChildren(rootCursor, cursorVisitor, self); dlclang_disposeTranslationUnit(TU); cleanup: if(has_extra_params) { sq_free(cl_args, sizeof(char*) * cl_argNum); } return rc; }
// ------------------------------------------------------------------------------------------------ SQInteger Routine::Create(HSQUIRRELVM vm) { // Locate the identifier of a free slot const SQInteger slot = FindUnused(); // See if we have where to store this routine if (slot < 0) { return sq_throwerror(vm, "Reached the maximum number of active routines"); } // Grab the top of the stack const SQInteger top = sq_gettop(vm); // See if too many arguments were specified if (top >= 20) /* 5 base + 14 parameters = 19 */ { return sq_throwerror(vm, "Too many parameters specified"); } // Was there was an environment specified? else if (top <= 1) { return sq_throwerror(vm, "Missing routine environment"); } // Was there was a callback specified? else if (top <= 2) { return sq_throwerror(vm, "Missing routine callback"); } // Validate the callback type else if (sq_gettype(vm, 3) != OT_CLOSURE && sq_gettype(vm, 3) != OT_NATIVECLOSURE) { return sq_throwerror(vm, "Invalid callback type"); } SQRESULT res = SQ_OK; // Prepare an object for the environment HSQOBJECT env; // Is the specified environment a null value? if (sq_gettype(vm, 2) == OT_NULL) { // Preserve the stack state const StackGuard sg(vm); // Push the root table on the stack sq_pushroottable(vm); // Attempt to retrieve the table object res = sq_getstackobj(vm, -1, &env); } else { sq_getstackobj(vm, 2, &env); // Just retrieve the specified environment } // Validate the result if (SQ_FAILED(res)) { return res; // Propagate the error } // Prepare an object for the function HSQOBJECT func; // Fetch the specified callback object res = sq_getstackobj(vm, 3, &func); // Validate the result if (SQ_FAILED(res)) { return res; // Propagate the error } // The number of iterations and interval to execute the routine SQInteger intrv = 0, itr = 0; // Was there an interval specified? if (top > 3) { // Grab the interval from the stack res = sq_getinteger(vm, 4, &intrv); // Validate the result if (SQ_FAILED(res)) { return res; // Propagate the error } } // Was there a number of iterations specified? if (top > 4) { // Grab the iterations from the stack res = sq_getinteger(vm, 5, &itr); // Validate the result if (SQ_FAILED(res)) { return res; // Propagate the error } } // Attempt to create a routine instance try { ClassType< Routine >::PushInstance(vm, new Routine()); } catch (const Sqrat::Exception & e) { return sq_throwerror(vm, "Unable to create the routine instance"); } // Prepare an object for the routine HSQOBJECT obj; // Fetch the created routine object res = sq_getstackobj(vm, -1, &obj); // Validate the result if (SQ_FAILED(res)) { return res; // Propagate the error } // At this point we can grab a reference to our slot Instance & inst = s_Instances[slot]; // Were there any arguments specified? if (top > 5) { // Grab a pointer to the arguments array Argument * args = inst.mArgv; // Reset the argument counter inst.mArgc = 0; // Grab the specified arguments from the stack for (SQInteger i = 6; i <= top; ++i) { res = sq_getstackobj(vm, i, &(args[inst.mArgc].mObj)); // Validate the result if (SQ_FAILED(res)) { // Clear previous arguments inst.Clear(); // Propagate the error return res; } // Keep a strong reference to the argument sq_addref(vm, &(args[inst.mArgc].mObj)); // Increase the argument counter ++inst.mArgc; } } // Attempt to retrieve the routine from the stack and associate it with the slot try { Var< Routine * >(vm, -1).value->m_Slot = ConvTo< Uint32 >::From(slot); } catch (const Sqrat::Exception & e) { // Clear extracted arguments inst.Clear(); // Now it's safe to throw the error return sq_throwerror(vm, "Unable to create the routine instance"); } // Alright, at this point we can initialize the slot inst.Init(env, func, obj, intrv, itr); // Now initialize the timer s_Intervals[slot] = intrv; // We have the created routine on the stack, so let's return it return 1; }
ScriptBehavior::ScriptBehavior( HSQUIRRELVM vm,HSQOBJECT classObject,const std::map< tstring_symbol,ScriptParameterInterfacePtr >& scriptParameters ) : m_vm(vm) , m_start(false) { int top = sq_gettop(m_vm); sq_pushobject(m_vm, classObject); sq_pushroottable( m_vm ); m_initialize = false; m_haveAwake = false; m_haveStart = false; m_haveUpdate = false; if( SQ_SUCCEEDED( sq_call( m_vm,1,SQTrue,SQTrue) ) ) { if( SQ_SUCCEEDED( sq_getstackobj(m_vm, -1, &m_instance) ) ) { sq_addref( m_vm,&m_instance ); m_initialize = true; sq_pushstring( m_vm,_SC("Awake"),-1 ); if( SQ_SUCCEEDED( sq_get(m_vm,-2 ) ) ) { if( SQ_SUCCEEDED( sq_getstackobj(m_vm, -1, &m_awakeFunction) ) ) { sq_addref( m_vm,&m_awakeFunction ); m_haveAwake = true; } } sq_pop(m_vm,1); sq_pushstring( m_vm,_SC("Start"),-1 ); if( SQ_SUCCEEDED( sq_get(m_vm,-2 ) ) ) { if( SQ_SUCCEEDED( sq_getstackobj(m_vm, -1, &m_startFunction) ) ) { sq_addref( m_vm,&m_startFunction ); m_haveStart = true; } } sq_pop(m_vm,1); sq_pushstring( m_vm,_SC("Update"),-1 ); if( SQ_SUCCEEDED( sq_get(m_vm,-2 ) ) ) { if( SQ_SUCCEEDED( sq_getstackobj(m_vm, -1, &m_updateFunction) ) ) { sq_addref( m_vm,&m_updateFunction ); m_haveUpdate = true; } } sq_pop(m_vm,1); std::map< tstring_symbol,ScriptParameterInterfacePtr >::const_iterator it = scriptParameters.begin(); while( it!=scriptParameters.end() ) { it->second->SetParameter( m_vm ); it++; } } } sq_settop( m_vm,top ); }
/** * Get the Squirrel-instance pointer. * @note This will only work just after a function-call from within Squirrel * to your C++ function. */ static bool GetInstance(HSQUIRRELVM vm, HSQOBJECT *ptr, int pos = 1) { sq_getclass(vm, pos); sq_getstackobj(vm, pos, ptr); sq_pop(vm, 1); return true; }
/* static */ bool Squirrel::CreateClassInstanceVM(HSQUIRRELVM vm, const char *class_name, void *real_instance, HSQOBJECT *instance, SQRELEASEHOOK release_hook, bool prepend_API_name) { Squirrel *engine = (Squirrel *)sq_getforeignptr(vm); int oldtop = sq_gettop(vm); /* First, find the class */ sq_pushroottable(vm); if (prepend_API_name) { size_t len = strlen(class_name) + strlen(engine->GetAPIName()) + 1; char *class_name2 = (char *)alloca(len); seprintf(class_name2, class_name2 + len - 1, "%s%s", engine->GetAPIName(), class_name); sq_pushstring(vm, class_name2, -1); } else { sq_pushstring(vm, class_name, -1); } if (SQ_FAILED(sq_get(vm, -2))) { DEBUG(misc, 0, "[squirrel] Failed to find class by the name '%s%s'", prepend_API_name ? engine->GetAPIName() : "", class_name); sq_settop(vm, oldtop); return false; } /* Create the instance */ if (SQ_FAILED(sq_createinstance(vm, -1))) { DEBUG(misc, 0, "[squirrel] Failed to create instance for class '%s%s'", prepend_API_name ? engine->GetAPIName() : "", class_name); sq_settop(vm, oldtop); return false; } if (instance != NULL) { /* Find our instance */ sq_getstackobj(vm, -1, instance); /* Add a reference to it, so it survives for ever */ sq_addref(vm, instance); } sq_remove(vm, -2); // Class-name sq_remove(vm, -2); // Root-table /* Store it in the class */ sq_setinstanceup(vm, -1, real_instance); if (release_hook != NULL) sq_setreleasehook(vm, -1, release_hook); if (instance != NULL) sq_settop(vm, oldtop); return true; }