int CEventNatives::Call(SQVM* pVM) { // we need enough parameters if(sq_gettop(pVM)<3) { sq_pushbool(pVM, false); return 1; } // get the event name const char* szEventName; if(SQ_FAILED(sq_getstring(pVM, 2, &szEventName))) { sq_pushbool(pVM, false); return 1; } // get the entity which it should effect CEntity* pEntity = sq_toentity(pVM, 3); // if we have a valid entity, use it if(pEntity) { // collect the parameters CSquirrelArguments* pArguments = new CSquirrelArguments(); for(int i = 4; i <= sq_gettop(pVM); ++ i) { // push all arguments from the stack if(!pArguments->pushFromStack(pVM, i)) { sq_pushbool(pVM, false); delete pArguments; return 1; } } sq_pushbool(pVM, pEntity->CallEvent(szEventName, pArguments)); delete pArguments; } else sq_pushbool(pVM, false); return 1; }
// TODO: 'Call for this script only' argument // callEvent(eventname, defaultretval, ...) SQInteger CEventNatives::Call(SQVM * pVM) { CHECK_PARAMS_MIN("callEvent", 2); CHECK_TYPE("callEvent", 1, 2, OT_STRING); SQInteger iTop = sq_gettop(pVM); // Get the name const char * szEventName; sq_getstring(pVM, 2, &szEventName); // Grab all arguments CSquirrelArguments pArguments; for(SQInteger i = 3; i <= iTop; ++ i) pArguments.pushFromStack(pVM, i); // Call the event CSquirrelArgument pReturn = CEvents::GetInstance()->Call(szEventName, &pArguments); pReturn.push(pVM); return 1; }
bool CSquirrelArgument::pushFromStack(SQVM * pVM, int idx) { reset(); SQObjectPtr obj = stack_get(pVM, idx); switch(obj._type) { case OT_NULL: // Nothing needed break; case OT_INTEGER: data.i = obj._unVal.nInteger; break; case OT_BOOL: data.b = (obj._unVal.nInteger != 0); break; case OT_FLOAT: data.f = obj._unVal.fFloat; break; case OT_STRING: data.str = new String(obj._unVal.pString->_val); break; case OT_TABLE: { CSquirrelArguments * pArguments = new CSquirrelArguments(); sq_push(pVM, idx); sq_pushnull(pVM); while(SQ_SUCCEEDED(sq_next(pVM, -2))) { if(!pArguments->pushFromStack(pVM, -2) || !pArguments->pushFromStack(pVM, -1)) { sq_pop(pVM, 4); delete pArguments; return false; } sq_pop(pVM, 2); } sq_pop(pVM, 2); data.pArray = pArguments; } break; case OT_ARRAY: { CSquirrelArguments * pArguments = new CSquirrelArguments(); sq_push(pVM, idx); sq_pushnull(pVM); while(SQ_SUCCEEDED(sq_next(pVM, -2))) { if(!pArguments->pushFromStack(pVM, -1)) { sq_pop(pVM, 4); delete pArguments; return false; } sq_pop(pVM, 2); } sq_pop(pVM, 2); data.pArray = pArguments; } break; case OT_CLOSURE: case OT_NATIVECLOSURE: data.sqObject = SQObject(obj); break; case OT_INSTANCE: data.pInstance = obj._unVal.pInstance; break; default: return false; break; } type = obj._type; return true; }
bool CSquirrelArguments::pushFromStack(SQVM* pVM, int idx) { switch(sq_gettype(pVM,idx)) { case OT_NULL: push(); break; case OT_INTEGER: { int i; sq_getinteger(pVM, idx, &i); push(i); } break; case OT_BOOL: { SQBool b; sq_getbool(pVM, idx, &b); push(b!=0); } break; case OT_FLOAT: { float f; sq_getfloat(pVM, idx, &f); push(f); } break; case OT_STRING: { const char* szTemp; sq_getstring(pVM, idx, &szTemp); push(szTemp); } break; case OT_TABLE: { CSquirrelArguments* pArguments = new CSquirrelArguments(); sq_push(pVM, idx); sq_pushnull(pVM); while(SQ_SUCCEEDED(sq_next(pVM,-2))) { if(!pArguments->pushFromStack(pVM, -2) || !pArguments->pushFromStack(pVM,-1)) { sq_pop(pVM,4); delete pArguments; return false; } sq_pop(pVM,2); } sq_pop(pVM,2); push(pArguments, false); break; } case OT_ARRAY: { CSquirrelArguments* pArguments = new CSquirrelArguments(); sq_push(pVM, idx); sq_pushnull(pVM); while(SQ_SUCCEEDED(sq_next(pVM,-2))) { if(!pArguments->pushFromStack(pVM,-1)) { sq_pop(pVM,4); delete pArguments; return false; } sq_pop(pVM,2); } sq_pop(pVM,2); push(pArguments, true); break; } default: return false; } return true; }