// GetNodeHeader(Node:nodeid,&nodes,&vehicle_nodes,&ped_nodes,&navi_nodes);
int n_GetNodeHeader(HSQUIRRELVM pVM)
{
	int nodeid;
	sq_getinteger(pVM,-1,&nodeid);
	if(pNodes[nodeid])
	{
		int d1 = 0,
			d2 = 0,
			d3 = 0;
		pNodes[nodeid]->GetInfo(&d1,&d2,&d3);

		sq_newarray(pVM, 0);
		sq_pushinteger(pVM,d1);
		sq_arrayappend(pVM, -2);
		sq_pushinteger(pVM,d2);
		sq_arrayappend(pVM, -2);
		sq_pushinteger(pVM,d3);
		sq_arrayappend(pVM, -2);
		sq_push(pVM, -1);
		return 1;
	}
	return 0;
}
void ScriptBehavior::Update( float deltaTime )
{
    if( !m_start )
    {
        Start();
        m_start = true;
    }

    if( !m_initialize || !m_haveUpdate )
    {
        return;
    }

    int top = sq_gettop(m_vm);

    sq_pushobject(m_vm, m_instance);
    sq_pushobject(m_vm, m_updateFunction);

    sq_push( m_vm,-3 );
    sq_pushfloat( m_vm,deltaTime );
    sq_call( m_vm,2,SQFalse,SQTrue );

    sq_settop( m_vm,top );
}
Esempio n. 3
0
void Interactive(HSQUIRRELVM v)
{
	
#define MAXINPUT 1024
	SQChar buffer[MAXINPUT];
	SQInteger blocks =0;
	SQInteger string=0;
	SQInteger retval=0;
	SQInteger done=0;
	PrintVersionInfos();
		
	sq_pushroottable(v);
	sq_pushstring(v,_SC("quit"),-1);
	sq_pushuserpointer(v,&done);
	sq_newclosure(v,quit,1);
	sq_setparamscheck(v,1,NULL);
	sq_newslot(v,-3,SQFalse);
	sq_pop(v,1);

	while (!done) 
	{
		SQInteger i = 0;
		scprintf(_SC("\nsq>"));
		for(;;) {
			int c;
			if(done)return;
			c = getchar();
			if (c == _SC('\n')) {
				if (i>0 && buffer[i-1] == _SC('\\'))
				{
					buffer[i-1] = _SC('\n');
				}
				else if(blocks==0)break;
				buffer[i++] = _SC('\n');
			}
			else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;}
			else if(c==_SC('{') && !string){
					blocks++;
					buffer[i++] = (SQChar)c;
			}
			else if(c==_SC('"') || c==_SC('\'')){
					string=!string;
					buffer[i++] = (SQChar)c;
			}
			else if (i >= MAXINPUT-1) {
				scfprintf(stderr, _SC("sq : input line too long\n"));
				break;
			}
			else{
				buffer[i++] = (SQChar)c;
			}
		}
		buffer[i] = _SC('\0');
		
		if(buffer[0]==_SC('=')){
			scsprintf(sq_getscratchpad(v,MAXINPUT),_SC("return (%s)"),&buffer[1]);
			memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar));
			retval=1;
		}
		i=scstrlen(buffer);
		if(i>0){
			SQInteger oldtop=sq_gettop(v);
			if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){
				sq_pushroottable(v);
				if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) &&	retval){
					scprintf(_SC("\n"));
					sq_pushroottable(v);
					sq_pushstring(v,_SC("print"),-1);
					sq_get(v,-2);
					sq_pushroottable(v);
					sq_push(v,-4);
					sq_call(v,2,SQFalse,SQTrue);
					retval=0;
					scprintf(_SC("\n"));
				}
			}
			
			sq_settop(v,oldtop);
		}
	}
}
SQInteger ScriptList::Valuate(HSQUIRRELVM vm)
{
	this->modifications++;

	/* The first parameter is the instance of ScriptList. */
	int nparam = sq_gettop(vm) - 1;

	if (nparam < 1) {
		return sq_throwerror(vm, _SC("You need to give a least a Valuator as parameter to ScriptList::Valuate"));
	}

	/* Make sure the valuator function is really a function, and not any
	 * other type. It's parameter 2 for us, but for the user it's the
	 * first parameter they give. */
	SQObjectType valuator_type = sq_gettype(vm, 2);
	if (valuator_type != OT_CLOSURE && valuator_type != OT_NATIVECLOSURE) {
		return sq_throwerror(vm, _SC("parameter 1 has an invalid type (expected function)"));
	}

	/* Don't allow docommand from a Valuator, as we can't resume in
	 * mid C++-code. */
	bool backup_allow = ScriptObject::GetAllowDoCommand();
	ScriptObject::SetAllowDoCommand(false);

	/* Push the function to call */
	sq_push(vm, 2);

	for (ScriptListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
		/* Check for changing of items. */
		int previous_modification_count = this->modifications;

		/* Push the root table as instance object, this is what squirrel does for meta-functions. */
		sq_pushroottable(vm);
		/* Push all arguments for the valuator function. */
		sq_pushinteger(vm, (*iter).first);
		for (int i = 0; i < nparam - 1; i++) {
			sq_push(vm, i + 3);
		}

		/* Call the function. Squirrel pops all parameters and pushes the return value. */
		if (SQ_FAILED(sq_call(vm, nparam + 1, SQTrue, SQTrue))) {
			ScriptObject::SetAllowDoCommand(backup_allow);
			return SQ_ERROR;
		}

		/* Retreive the return value */
		SQInteger value;
		switch (sq_gettype(vm, -1)) {
			case OT_INTEGER: {
				sq_getinteger(vm, -1, &value);
				break;
			}

			case OT_BOOL: {
				SQBool v;
				sq_getbool(vm, -1, &v);
				value = v ? 1 : 0;
				break;
			}

			default: {
				/* See below for explanation. The extra pop is the return value. */
				sq_pop(vm, nparam + 4);

				ScriptObject::SetAllowDoCommand(backup_allow);
				return sq_throwerror(vm, _SC("return value of valuator is not valid (not integer/bool)"));
			}
		}

		/* Was something changed? */
		if (previous_modification_count != this->modifications) {
			/* See below for explanation. The extra pop is the return value. */
			sq_pop(vm, nparam + 4);

			ScriptObject::SetAllowDoCommand(backup_allow);
			return sq_throwerror(vm, _SC("modifying valuated list outside of valuator function"));
		}

		this->SetValue((*iter).first, value);

		/* Pop the return value. */
		sq_poptop(vm);

		Squirrel::DecreaseOps(vm, 5);
	}
	/* Pop from the squirrel stack:
	 * 1. The root stable (as instance object).
	 * 2. The valuator function.
	 * 3. The parameters given to this function.
	 * 4. The ScriptList instance object. */
	sq_pop(vm, nparam + 3);

	ScriptObject::SetAllowDoCommand(backup_allow);
	return 0;
}
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;
}
static SQInteger squirrel_errorhandler(HSQUIRRELVM v) {
  /* Detect whether this error is just propagating through, or it originated
   * here. To do so, we store the last error we saw in the registry and compare
   * it to the current error. If they are the equal, we've already handled this
   * error.
   *
   * Without this check, we'll call the error handler for every transition
   * between the Squirrel and Wasm VMs. */
  /* TODO(binji): It seems like there should be a better way to handle this */
  SQInteger top = sq_gettop(v);
  WasmBool is_new_error = WASM_TRUE;
  /* get the last error we saw */
  sq_pushregistrytable(v);
  sq_pushstring(v, WASM_LAST_ERROR_NAME, -1);
  if (SQ_SUCCEEDED(sq_get(v, -2))) {
    /* STACK: error registry_table last_error */
    sq_push(v, -3);

    HSQOBJECT last_error;
    HSQOBJECT error;
    if (SQ_SUCCEEDED(sq_getstackobj(v, -1, &error)) &&
        SQ_SUCCEEDED(sq_getstackobj(v, -2, &last_error))) {
      /* we don't want to use cmp here, because it will throw if the values are
       * unordered, and because it performs value equality */
      if (squirrel_objects_are_equal_raw(last_error, error))
        is_new_error = WASM_FALSE;
    }

    /* set the last_error in the registry to the new error. */
    /* STACK: registry_table last_error error */
    sq_remove(v, -2);
    sq_pushstring(v, WASM_LAST_ERROR_NAME, -1);
    sq_push(v, -2);
    /* STACK: registry_table error WASM_LAST_ERROR_NAME error */
    SQRESULT r = sq_set(v, -4);
    WASM_USE(r);
    assert(r == SQ_OK);
  }
  sq_settop(v, top);

  if (is_new_error) {
    const char* error_msg = "unknown";
    if (sq_gettop(v) >= 1)
      sq_getstring(v, -1, &error_msg);
    squirrel_error(v, "error: %s\n", error_msg);
    squirrel_error(v, "callstack:\n");
    SQStackInfos stack_info;
    SQInteger depth;
    for (depth = 1; SQ_SUCCEEDED(sq_stackinfos(v, depth, &stack_info));
         depth++) {
      const char* source = stack_info.source ? stack_info.source : "unknown";
      const char* funcname =
          stack_info.funcname ? stack_info.funcname : "unknown";
      SQInteger line = stack_info.line;
      squirrel_error(v,
                     "  #"_PRINT_INT_FMT
                     ": %s:"_PRINT_INT_FMT
                     ": %s()\n",
                     depth, source, line, funcname);
    }
  }
  return 0;
}
Esempio n. 7
0
// ------------------------------------------------------------------------------------------------
SQInteger Signal::SqRequest(HSQUIRRELVM vm)
{
    const Int32 top = sq_gettop(vm);
    // The signal instance
    Signal * signal = nullptr;
    // Attempt to extract the signal instance
    try
    {
        signal = Var< Signal * >(vm, 1).value;
    }
    catch (const Sqrat::Exception & e)
    {
        return sq_throwerror(vm, e.what());
    }
    // Do we have a valid signal instance?
    if (!signal)
    {
        return sq_throwerror(vm, "Invalid signal instance");
    }
    // Walk down the chain and trigger slots
    for (Slot * node = signal->m_Head, * next = nullptr; node != nullptr; node = next)
    {
        // Grab the next node upfront
        next = node->mNext;
        // Remember the current stack size
        const StackGuard sg(vm);
        // Push the callback object
        sq_pushobject(vm, node->mFuncRef);
        // Is there an explicit environment?
        if (sq_isnull(node->mEnvRef))
        {
            sq_pushroottable(vm);
        }
        else
        {
            sq_pushobject(vm, node->mEnvRef);
        }
        // Are there any parameters to forward?
        if (top > 1)
        {
            for (SQInteger i = 2; i <= top; ++i)
            {
                sq_push(vm, i);
            }
        }
        // Make the function call and store the result
        const SQRESULT res = sq_call(vm, top, true, ErrorHandling::IsEnabled());
        // Validate the result
        if (SQ_FAILED(res))
        {
            return res; // Propagate the error
        }
        // Is the returned value not null?
        else if (sq_gettype(vm, -1) != OT_NULL)
        {
            // Push back the returned value
            sq_push(vm, -1);
            // Specify that we returned something
            return 1;
        }
    }
    // Specify that we returned nothing
    return 0;
}
Esempio n. 8
0
// ------------------------------------------------------------------------------------------------
SQInteger Signal::SqQuery(HSQUIRRELVM vm)
{
    const Int32 top = sq_gettop(vm);
    // Do we have the collector environment?
    if (top <= 1)
    {
        return sq_throwerror(vm, "Missing collector environment");
    }
    // Do we have the collector function?
    else if (top <= 2)
    {
        return sq_throwerror(vm, "Missing collector callback");
    }
    // The signal instance
    Signal * signal = nullptr;
    // Attempt to extract the signal instance and collector
    try
    {
        signal = Var< Signal * >(vm, 1).value;
    }
    catch (const Sqrat::Exception & e)
    {
        return sq_throwerror(vm, e.what());
    }
    // Do we have a valid signal instance?
    if (!signal)
    {
        return sq_throwerror(vm, "Invalid signal instance");
    }
    // The collector
    HSQOBJECT cenv, cfunc;
    // Grab the collector environment
    SQRESULT res = sq_getstackobj(vm, 2, &cenv);
    // Validate the result
    if (SQ_FAILED(res))
    {
        return res; // Propagate the error
    }
    // Was there a valid environment?
    else if (sq_isnull(cenv))
    {
        // Remember the current stack size
        const StackGuard sg(vm);
        // Default to the root table
        sq_pushroottable(vm);
        // Try to grab the collector environment again
        SQRESULT res = sq_getstackobj(vm, -1, &cenv);
        // Validate the result
        if (SQ_FAILED(res))
        {
            return res; // Propagate the error
        }
    }
    // Grab the collector function
    res = sq_getstackobj(vm, 3, &cfunc);
    // Validate the result
    if (SQ_FAILED(res))
    {
        return res; // Propagate the error
    }
    // Some dummy checks to make sure the collector is a callable object
    else if (!sq_isfunction(cfunc) && !sq_isclosure(cfunc) && !sq_isnativeclosure(cfunc))
    {
        return sq_throwerror(vm, "Invalid collector");
    }
    // Walk down the chain and trigger slots
    for (Slot * node = signal->m_Head, * next = nullptr; node != nullptr; node = next)
    {
        // Grab the next node upfront
        next = node->mNext;
        // Remember the current stack size
        const StackGuard sg(vm);
        // Push the callback object
        sq_pushobject(vm, node->mFuncRef);
        // Is there an explicit environment?
        if (sq_isnull(node->mEnvRef))
        {
            sq_pushroottable(vm);
        }
        else
        {
            sq_pushobject(vm, node->mEnvRef);
        }
        // Are there any parameters to forward?
        if (top > 3)
        {
            for (SQInteger i = 4; i <= top; ++i)
            {
                sq_push(vm, i);
            }
        }
        // Make the function call and store the result
        res = sq_call(vm, top - 2, true, ErrorHandling::IsEnabled());
        // Validate the result
        if (SQ_FAILED(res))
        {
            return res; // Propagate the error
        }
        // Push the collector onto the stack
        sq_pushobject(vm, cfunc);
        sq_pushobject(vm, cenv);
        // Push the returned value
        sq_push(vm, -3);
        // Make the function call and store the result
        res = sq_call(vm, 2, false, ErrorHandling::IsEnabled());
        // Validate the result
        if (SQ_FAILED(res))
        {
            return res; // Propagate the error
        }
    }
    // Specify that we don't return anything
    return 0;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
static SQInteger _string_escape(HSQUIRRELVM v)
{
    const SQChar *str;
    SQChar *dest,*resstr;
    SQInteger size;
    sq_getstring(v,2,&str);
    size = sq_getsize(v,2);
    if(size == 0) {
        sq_push(v,2);
        return 1;
    }
#ifdef SQUNICODE
#if WCHAR_SIZE == 2
    const SQChar *escpat = _SC("\\x%04x");
    const SQInteger maxescsize = 6;
#else //WCHAR_SIZE == 4
    const SQChar *escpat = _SC("\\x%08x");
    const SQInteger maxescsize = 10;
#endif
#else
    const SQChar *escpat = _SC("\\x%02x");
    const SQInteger maxescsize = 4;
#endif
    SQInteger destcharsize = (size * maxescsize); //assumes every char could be escaped
    resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar));
    SQChar c;
    SQChar escch;
    SQInteger escaped = 0;
    for(int n = 0; n < size; n++){
        c = *str++;
        escch = 0;
        if(scisprint(c) || c == 0) {
            switch(c) {
            case '\a': escch = 'a'; break;
            case '\b': escch = 'b'; break;
            case '\t': escch = 't'; break;
            case '\n': escch = 'n'; break;
            case '\v': escch = 'v'; break;
            case '\f': escch = 'f'; break;
            case '\r': escch = 'r'; break;
            case '\\': escch = '\\'; break;
            case '\"': escch = '\"'; break;
            case '\'': escch = '\''; break;
            case 0: escch = '0'; break;
            }
            if(escch) {
                *dest++ = '\\';
                *dest++ = escch;
                escaped++;
            }
            else {
                *dest++ = c;
            }
        }
        else {

            dest += scsprintf(dest, destcharsize, escpat, c);
            escaped++;
        }
    }

    if(escaped) {
        sq_pushstring(v,resstr,dest - resstr);
    }
    else {
        sq_push(v,2); //nothing escaped
    }
    return 1;
}