bool CreateConstructNativeClassInstance(HSQUIRRELVM v, const SQChar * className) { 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; } // if #if 0 sq_remove(v, -3); // Remove the root table. sq_push(v, 1); // Push the 'this'. #else // Kamaitati's change. 5/28/06 jcs. sq_remove(v, -2); // Remove the root table. sq_pushroottable(v); // Push the 'this'. #endif if (SQ_FAILED(sq_call(v, 1, SQTrue, false))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called). sq_settop(v, oldtop); return false; } // if sq_remove(v, -2); // Remove the class. // int newtop = sq_gettop(v); return true; } // CreateConstructNativeClassInstance
BOOL SbuCreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd) { int n = 0; int oldtop = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v,cd->name,-1); if(cd->base) { sq_pushstring(v,cd->base,-1); if(SQ_FAILED(sq_get(v,-3))) { sq_settop(v,oldtop); return FALSE; } } if(SQ_FAILED(sq_newclass(v,cd->base?1:0))) { sq_settop(v,oldtop); return FALSE; } sq_settypetag(v,-1,(SQUserPointer)cd); const ScriptClassMemberDecl *members = cd->members; const ScriptClassMemberDecl *m = NULL; while(members[n].name) { m = &members[n]; sq_pushstring(v,m->name,-1); sq_newclosure(v,m->func,0); sq_setparamscheck(v,m->params,m->typemask); sq_setnativeclosurename(v,-1,m->name); sq_createslot(v,-3); n++; } sq_createslot(v,-3); sq_pop(v,1); return TRUE; }
void CSquirrelVM::BeginRegisterScriptClass(const char* className, scriptFunction pfnFunction, void* userPointer, const char* baseClass) { iFuncIndex = 0; #if 1 int n = 0; oldtop = sq_gettop(m_pVM); sq_pushroottable(m_pVM); sq_pushstring(m_pVM, className, -1); if(baseClass) { sq_pushstring(m_pVM, baseClass, -1); if(SQ_FAILED(sq_get(m_pVM, -3))) { // make sure base exists sq_settop(m_pVM, oldtop); return; } } if(SQ_FAILED(sq_newclass(m_pVM, baseClass ? 1 : 0))) { sq_settop(m_pVM, oldtop); return; } sq_pushstring(m_pVM, _SC("constructor"), -1); if (userPointer != nullptr) { sq_pushuserpointer(m_pVM, userPointer); sq_newclosure(m_pVM, (SQFUNCTION) pfnFunction, 1); } else sq_newclosure(m_pVM, (SQFUNCTION)pfnFunction, 0); sq_newslot(m_pVM, -3, false); // Add the constructor method #endif }
bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) { if(func < 0) { if(!v->ObjCmp(a,b,ret)) return false; } else { SQInteger top = sq_gettop(v); sq_push(v, func); sq_pushroottable(v); v->Push(a); v->Push(b); if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { if(!sq_isstring( v->_lasterror)) v->Raise_Error(_SC("compare func failed")); return false; } if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { v->Raise_Error(_SC("numeric value expected as return value of the compare function")); return false; } sq_settop(v, top); return true; } return true; }
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 main(int argc, char** argv) { HSQUIRRELVM vm=sq_open(SQUIRREL_STACK_SIZE); sq_setprintfunc(vm, squirrel_print_function, NULL); register_global_func(vm,ShowVersion,"ShowVersion"); register_global_func(vm,Multiply,"Multiply"); if(SQ_FAILED(sqstd_dofile(vm,"test.nut",SQFalse,SQFalse))) return 1; /*const SQChar *program = "::print(\"Hello World!\\n\");"; if (SQ_FAILED(sq_compilebuffer(vm, program, sizeof(SQChar) * strlen(program), "program", SQFalse))) { return 1; }*/ sq_pushroottable(vm); if (SQ_FAILED(sq_call(vm, 1, SQFalse, SQFalse))) { //squirrel_print_last_error(sqvm); return 1; } sq_close(vm); return 0; }
ScriptText::ScriptText(HSQUIRRELVM vm) : ZeroedMemoryAllocator() { int nparam = sq_gettop(vm) - 1; if (nparam < 1) { throw sq_throwerror(vm, _SC("You need to pass at least a StringID to the constructor")); } /* First resolve the StringID. */ SQInteger sqstring; if (SQ_FAILED(sq_getinteger(vm, 2, &sqstring))) { throw sq_throwerror(vm, _SC("First argument must be a valid StringID")); } this->string = sqstring; /* The rest of the parameters must be arguments. */ for (int i = 0; i < nparam - 1; i++) { /* Push the parameter to the top of the stack. */ sq_push(vm, i + 3); if (SQ_FAILED(this->_SetParam(i, vm))) { this->~ScriptText(); throw sq_throwerror(vm, _SC("Invalid parameter")); } /* Pop the parameter again. */ sq_pop(vm, 1); } }
// write SQInteger file_put_contents(HSQUIRRELVM v) { // function parameters const SQChar* filename; const SQChar* contents; // internal structures apr_file_t* file; apr_size_t nbytes; apr_status_t status; request_rec* r = get_request_rec(v); // for error messages char error[120]; char errorMessage[120]; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "file_put_contents()"); // grab filename param if( sq_gettype(v, 2) != OT_STRING ) { return SQ_ERROR; } else if( SQ_FAILED(sq_getstring(v, 2, &filename)) ) { return SQ_ERROR; } // grab contents param if( sq_gettype(v, 3) != OT_STRING ) { return SQ_ERROR; } else if( SQ_FAILED(sq_getstring(v, 3, &contents)) ) { return SQ_ERROR; } nbytes = strlen(contents); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, " file_put_contents('%s', '%s') %d", filename, contents, (int)nbytes); if( (status = apr_file_open(&file, filename, APR_WRITE|APR_CREATE, APR_OS_DEFAULT, r->pool)) != APR_SUCCESS ) { apr_strerror(status, error, sizeof error); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, " file_put_contents() failed: %s", error); sprintf(errorMessage, "file_put_contents() failed: %s", error); errorfunc(v, errorMessage); sq_pushbool(v, SQFalse); } else if( (status = apr_file_write(file, contents, &nbytes)) != APR_SUCCESS ) { apr_strerror(status, error, sizeof error); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, " file_put_contents() failed: %s", error); sprintf(errorMessage, "file_put_contents() failed: %s", error); errorfunc(v, errorMessage); sq_pushbool(v, SQFalse); } else { sq_pushinteger(v, nbytes); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, " file_put_contents() wrote %d bytes", (int)nbytes); } ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "file_put_contents() returning 1"); return 1; }
static SQRESULT sqrat_importscript(HSQUIRRELVM v, const SQChar* moduleName) { std::basic_string<SQChar> filename(moduleName); filename += _SC(".nut"); if(SQ_FAILED(sqstd_loadfile(v, moduleName, true))) { if(SQ_FAILED(sqstd_loadfile(v, filename.c_str(), true))) { return SQ_ERROR; } } sq_push(v, -2); sq_call(v, 1, false, true); return SQ_OK; }
/** * TJSオブジェクトのオーバライド処理 * 引数1 オブジェクト * 引数2 名前 * 引数3 値。省略時は squirrel インスタンスから名前で参照 */ SQRESULT TJSObject::tjsOverride(HSQUIRRELVM v) { SQRESULT result; tTJSVariant instance; if (getVariant(v,1,&instance) && instance.Type() == tvtObject) { tTJSVariant value; const SQChar *methodName = sqobject::getString(v,2); int n = sq_gettop(v); if (n >= 3) { // 引数で明示指定されている if (SQ_FAILED(result = sq_getvariant(v, 3, &value))) { return result; } } else { // 自己オブジェクトから名前で検索して登録 sq_push(v, 1); sq_pushstring(v, methodName, -1); if (SQ_FAILED(result = sq_get(v, -2))) { sq_pop(v, 1); //self return result; } else { SQObjectType type = sq_gettype(v, -1); if (type == OT_CLOSURE || type == OT_NATIVECLOSURE) { // クロージャの場合は bindenv しておく sq_push(v, 1); if (SQ_FAILED(result = sq_bindenv(v, -2))) { sq_pop(v, 2); // func, self return result; } else { sq_remove(v, -2); // original func } } if (SQ_FAILED(result = sq_getvariant(v, -1, &value))) { // value sq_pop(v, 1); //self return result; } sq_pop(v, 1); // self } } tjs_error error; if (TJS_SUCCEEDED(error = instance.AsObjectClosureNoAddRef().PropSet(TJS_MEMBERENSURE, methodName, NULL, &value, NULL))) { return SQ_OK; } else { return ERROR_KRKR(v, error); } } return ERROR_BADINSTANCE(v); }
/* static */ SQInteger GameInfo::Constructor(HSQUIRRELVM vm) { /* Get the GameInfo */ SQUserPointer instance = NULL; if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == NULL) return sq_throwerror(vm, _SC("Pass an instance of a child class of GameInfo to RegisterGame")); GameInfo *info = (GameInfo *)instance; SQInteger res = ScriptInfo::Constructor(vm, info); if (res != 0) return res; if (info->engine->MethodExists(*info->SQ_instance, "MinVersionToLoad")) { if (!info->engine->CallIntegerMethod(*info->SQ_instance, "MinVersionToLoad", &info->min_loadable_version, MAX_GET_OPS)) return SQ_ERROR; } else { info->min_loadable_version = info->GetVersion(); } /* When there is an IsSelectable function, call it. */ if (info->engine->MethodExists(*info->SQ_instance, "IsDeveloperOnly")) { if (!info->engine->CallBoolMethod(*info->SQ_instance, "IsDeveloperOnly", &info->is_developer_only, MAX_GET_OPS)) return SQ_ERROR; } else { info->is_developer_only = false; } /* Try to get the API version the AI is written for. */ if (!info->CheckMethod("GetAPIVersion")) return SQ_ERROR; if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_OPS)) return SQ_ERROR; if (!CheckAPIVersion(info->api_version)) { DEBUG(script, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion()); return SQ_ERROR; } /* Remove the link to the real instance, else it might get deleted by RegisterGame() */ sq_setinstanceup(vm, 2, NULL); /* Register the Game to the base system */ info->GetScanner()->RegisterScript(info); return 0; }
void ThreadQueue::wakeup() { // we traverse the list in reverse orders and use indices. This should be // robust for scripts that add new entries to the list while we're traversing // it size_t i = threads.size() - 1; size_t end = static_cast<size_t>(0 - 1); size_t size_begin = threads.size(); while(i != end) { HSQOBJECT object = threads[i]; sq_pushobject(global_vm, object); sq_getweakrefval(global_vm, -1); HSQUIRRELVM scheduled_vm; if(sq_gettype(global_vm, -1) == OT_THREAD && SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) { if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) { log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl; } } sq_release(global_vm, &object); sq_pop(global_vm, 1); i--; } threads.erase(threads.begin(), threads.begin() + size_begin); }
static SQInteger array_reduce(HSQUIRRELVM v) { SQObject &o = stack_get(v,1); SQArray *a = _array(o); SQInteger size = a->Size(); if(size == 0) { return 0; } SQObjectPtr res; a->Get(0,res); if(size > 1) { SQObjectPtr other; for(SQInteger n = 1; n < size; n++) { a->Get(n,other); v->Push(o); v->Push(res); v->Push(other); if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { return SQ_ERROR; } res = v->GetUp(-1); v->Pop(); } } v->Push(res); return 1; }
static SQInteger base_setconsttable(HSQUIRRELVM v) { SQObjectPtr o = _ss(v)->_consts; if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; v->Push(o); return 1; }
static SQInteger base_setroottable(HSQUIRRELVM v) { SQObjectPtr o = v->_roottable; if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; v->Push(o); return 1; }
static SQInteger thread_getstackinfos(HSQUIRRELVM v) { SQObjectPtr o = stack_get(v,1); if(type(o) == OT_THREAD) { SQVM *thread = _thread(o); SQInteger threadtop = sq_gettop(thread); SQInteger level; sq_getinteger(v,-1,&level); SQRESULT res = __getcallstackinfos(thread,level); if(SQ_FAILED(res)) { sq_settop(thread,threadtop); if(type(thread->_lasterror) == OT_STRING) { sq_throwerror(v,_stringval(thread->_lasterror)); } else { sq_throwerror(v,_SC("unknown error")); } } if(res > 0) { //some result sq_move(v,thread,-1); sq_settop(thread,threadtop); return 1; } //no result sq_settop(thread,threadtop); return 0; } return sq_throwerror(v,_SC("wrong parameter")); }
// exists SQInteger file_exists(HSQUIRRELVM v) { const SQChar* filename; apr_finfo_t finfo; apr_status_t status; request_rec* r = get_request_rec(v); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "file_exists()"); // grab function param if( sq_gettype(v, 2) != OT_STRING ) { return SQ_ERROR; } if( SQ_FAILED(sq_getstring(v, 2, &filename)) ) { return SQ_ERROR; } ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, " file_exists(%s)", filename); status = apr_stat(&finfo, filename, APR_FINFO_CSIZE, r->pool); if( status ) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, " set false"); sq_pushbool(v, SQFalse); } else { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, " set true"); sq_pushbool(v, SQTrue); } ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, " returning 1"); return 1; }
// // Transport.TimeSignature numerator // SQInteger TransportTimeSignaturenumerator(HSQUIRRELVM vm) { SQInteger numargs = sq_gettop(vm); // check parameter count if(numargs > 1) { return sq_throwerror(vm, "too many parameters, expected at most 0"); } // get "this" pointer SQUserPointer userPtr = 0; if (SQ_FAILED(sq_getinstanceup(vm, 1, &userPtr, 0))) { return sq_throwerror(vm, "numerator method needs an instance of TimeSignature"); } TimeSignature *obj = static_cast<TimeSignature*>(userPtr); if(!obj) { return sq_throwerror(vm, "numerator method called before Transport.TimeSignature constructor"); } // return value SQInteger ret; // call the implementation try { ret = obj->getNumerator(); } catch(std::exception const& e) { return sq_throwerror(vm, e.what()); } // push return value sq_pushinteger(vm, ret); return 1; }
static SQInteger table_setdelegate(HSQUIRRELVM v) { if(SQ_FAILED(sq_setdelegate(v,-2))) return SQ_ERROR; sq_push(v,-1); // -1 because sq_setdelegate pops 1 return 1; }
static SQInteger array_apply(HSQUIRRELVM v) { SQObject &o = stack_get(v,1); if(SQ_FAILED(__map_array(_array(o),_array(o),v))) return SQ_ERROR; return 0; }
/* * load squirrel script from given file name */ bool loadScript(const char* fname) { FILE* fp = fopen(fname, "r"); if (fp == NULL) { engine->setLastError(ERR_SCRIPT_OPEN); LOGW("loadScript: failed to open main script file"); LOGW(fname); return false; } if (SQ_SUCCEEDED(sq_compile(engine->sqvm, sq_lexer_fp, fp, fname, SQTrue))) { sq_pushroottable(engine->sqvm); if (SQ_FAILED(sq_call(engine->sqvm, 1, SQFalse, SQTrue))) { engine->setLastError(ERR_SCRIPT_CALL_ROOT); LOGW("loadScript: failed to sq_call"); LOGW(fname); fclose(fp); return false; } } else { engine->setLastError(ERR_SCRIPT_COMPILE); LOGW("loadScript: failed to compile squirrel script"); LOGW(fname); fclose(fp); return false; } fclose(fp); return true; }
static SQInteger base_setconsttable(HSQUIRRELVM v) { SQObjectPtr &o=stack_get(v,2); if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; v->Push(o); return 1; }
static SQInteger command_set(HSQUIRRELVM v, struct flash_memory_driver *t) { long command, address ,mask; SQRESULT r = qr_argument_get(v, 3, &command, &address, &mask); if(SQ_FAILED(r)){ return r; } long d = command & (mask - 1); d |= address; switch(command){ case 0x0000: t->c000x = d; break; case 0x02aa: case 0x2aaa: t->c2aaa = d; break; case 0x0555: case 0x5555: t->c5555 = d; break; default: return sq_throwerror(v, wgT("unknown command address")); } t->command_change = true; return 0; }
void TimeScheduler::update(float time) { while(!schedule.empty() && schedule.front().wakeup_time < time) { HSQOBJECT thread_ref = schedule.front().thread_ref; sq_pushobject(global_vm, thread_ref); sq_getweakrefval(global_vm, -1); HSQUIRRELVM scheduled_vm; if(sq_gettype(global_vm, -1) == OT_THREAD && SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) { if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) { std::ostringstream msg; msg << "Error waking VM: "; sq_getlasterror(scheduled_vm); if(sq_gettype(scheduled_vm, -1) != OT_STRING) { msg << "(no info)"; } else { const char* lasterr; sq_getstring(scheduled_vm, -1, &lasterr); msg << lasterr; } log_warning << msg.str() << std::endl; sq_pop(scheduled_vm, 1); } } sq_release(global_vm, &thread_ref); sq_pop(global_vm, 2); std::pop_heap(schedule.begin(), schedule.end()); schedule.pop_back(); } }
_MEMBER_FUNCTION_IMPL(GUIElement, constructor) { const char * name; sq_getstring(pVM, -1, &name); String szName = name; if(szName.IsEmpty()) _SET_RELEASE_HOOK(GUIElement); // Get our GUI instance CGUI * pGUI = g_pClient->GetGUI(); try { pGUI->GetWindowManager()->getWindow(szName.C_String()); } catch(CEGUI::Exception &e) { e; _SET_RELEASE_HOOK(GUIElement); } CEGUI::Window * pWindow = pGUI->GetWindowManager()->getWindow(szName.C_String()); if(!pWindow || SQ_FAILED(sq_setinstance(pVM, pWindow))) { CLogFile::Printf("Can't create GUIElement."); sq_pushbool(pVM, false); return 1; } SubscribeGuiEvents(pWindow); sq_pushbool(pVM, true); return 1; }
// GUIText _MEMBER_FUNCTION_IMPL(GUIText, constructor) { // Get our GUI CGUI * pGUI = g_pClient->GetGUI(); CEGUI::Window * pWindow = pGUI->CreateGUIStaticText(); if(!pWindow || SQ_FAILED(sq_setinstance(pVM, pWindow))) { CLogFile::Printf("Can't create GUIText."); sq_pushbool(pVM, false); return 1; } //_SET_RELEASE_HOOK(GUIElement); CClientScriptManager * pClientScriptManager = g_pClient->GetClientScriptManager(); pClientScriptManager->GetGUIManager()->Add(pWindow, pClientScriptManager->GetScriptingManager()->Get(pVM)); pWindow->setVisible(true); pWindow->setProperty("FrameEnabled", "false"); pWindow->setProperty("BackgroundEnabled", "false"); pWindow->setFont(pGUI->GetFont("tahoma-bold")); pWindow->setProperty("TextColours", "tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF"); SubscribeGuiEvents(pWindow); sq_pushbool(pVM, true); return 1; }
void flash_device_listup(struct flash_listup *t) { const wgChar *str; HSQUIRRELVM v = qr_open(NULL); SQInteger top = sq_gettop(v); if(SQ_FAILED(sqstd_dofile(v, _SC("flashdevice.nut"), SQFalse, SQTrue))){ // puts("flash device script error"); qr_close(v); return; } int i; const int device_num = flash_device_number_get(v); sq_settop(v, top); for(i = 0; i < device_num; i++){ flash_device_name_get(v, i, &str); if(STRNCMP(str, _SC("dummy"), 6) != 0){ t->append(t->obj_cpu, str); t->append(t->obj_ppu, str); } sq_settop(v, top); } qr_close(v); v = NULL; }
static SQInteger _file_constructor(HSQUIRRELVM v) { const SQChar *filename,*mode; bool owns = true; SQFile *f; SQFILE newf; if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { sq_getstring(v, 2, &filename); sq_getstring(v, 3, &mode); newf = sqstd_fopen(filename, mode); if(!newf) return sq_throwerror(v, _SC("cannot open file")); } else if(sq_gettype(v,2) == OT_USERPOINTER) { owns = !(sq_gettype(v,3) == OT_NULL); sq_getuserpointer(v,2,&newf); } else { return sq_throwerror(v,_SC("wrong parameter")); } f = new SQFile(newf,owns); if(SQ_FAILED(sq_setinstanceup(v,1,f))) { delete f; return sq_throwerror(v, _SC("cannot create blob with negative size")); } sq_setreleasehook(v,1,_file_releasehook); return 0; }
void init_streamclass(HSQUIRRELVM v) { sq_pushregistrytable(v); sq_pushstring(v,_SC("std_stream"),-1); if(SQ_FAILED(sq_get(v,-2))) { sq_pushstring(v,_SC("std_stream"),-1); sq_newclass(v,SQFalse); sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); SQInteger i = 0; while(_stream_methods[i].name != 0) { const SQRegFunction &f = _stream_methods[i]; sq_pushstring(v,f.name,-1); sq_newclosure(v,f.f,0); sq_setparamscheck(v,f.nparamscheck,f.typemask); sq_newslot(v,-3,SQFalse); i++; } sq_newslot(v,-3,SQFalse); sq_pushroottable(v); sq_pushstring(v,_SC("stream"),-1); sq_pushstring(v,_SC("std_stream"),-1); sq_get(v,-4); sq_newslot(v,-3,SQFalse); sq_pop(v,1); } else { sq_pop(v,1); //result } sq_pop(v,1); }
/* 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; }