Exemple #1
0
static SQInteger thread_wakeup(HSQUIRRELVM v)
{
	SQObjectPtr o = stack_get(v,1);
	if(type(o) == OT_THREAD) {
		SQVM *thread = _thread(o);
		SQInteger state = sq_getvmstate(thread);
		if(state != SQ_VMSTATE_SUSPENDED) {
			switch(state) {
				case SQ_VMSTATE_IDLE:
					return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
				break;
				case SQ_VMSTATE_RUNNING:
					return sq_throwerror(v,_SC("cannot wakeup a running thread"));
				break;
			}
		}
			
		SQInteger wakeupret = sq_gettop(v)>1?1:0;
		if(wakeupret) {
			sq_move(thread,v,2);
		}
		if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1,SQFalse))) {
			sq_move(v,thread,-1);
			sq_pop(thread,1);
			if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
				sq_pop(thread,1);
			}
			return 1;
		}
		return SQ_ERROR;
	}
	return sq_throwerror(v,_SC("wrong parameter"));
}
Exemple #2
0
static SQInteger thread_call(HSQUIRRELVM v)
{
	SQObjectPtr o = stack_get(v,1);
	if(type(o) == OT_THREAD) {
		SQInteger nparams = sq_gettop(v);
		_thread(o)->Push(_thread(o)->_roottable);
		for(SQInteger i = 2; i<(nparams+1); i++)
			sq_move(_thread(o),v,i);
		if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
			sq_move(v,_thread(o),-1);
			return 1;
		}
		return SQ_ERROR;
	}
	return sq_throwerror(v,_SC("wrong parameter"));
}
Exemple #3
0
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"));
}
Exemple #4
0
static SQInteger base_newthread(HSQUIRRELVM v)
{
	SQObjectPtr &func = stack_get(v,2);
	SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
	HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
	sq_move(newv,v,-2);
	return 1;
}
Exemple #5
0
/**
 * ベースVM上でスクリプトを実行する。
 * この呼び出しはスレッドによるものではないため、処理中に suspend() / wait() を
 * 呼ぶとエラーになるので注意してください。必ず1度で呼びきれるものを渡す必要があります。
 * @param func グローバル関数。※ファイルは指定できません
 * @param ... 引数
 */
SQRESULT
Thread::global_execOnBase(HSQUIRRELVM v)
{
	SQInteger max = sq_gettop(v);
	if (max <= 1) {
		return ERROR_INVALIDPARAM(v);
	}
	HSQUIRRELVM gv = getGlobalVM();
	SQRESULT result = SQ_OK;
	if (gv == v) {
		sq_push(gv, 2);
		sq_pushroottable(gv); // 引数:self(root)
		int argc = 1;
		for (int i=3;i<=max;i++) {
			sq_push(v, i);
			argc++;
		}
		if (SQ_SUCCEEDED(result = sq_call(gv, argc, SQTrue, SQTrue))) {
			sq_remove(gv, -2); // func
		} else {
			sq_pop(gv, 1); // func
		}
	} else {
		sq_move(gv, v, 2);    // func
		sq_pushroottable(gv); // 引数:self(root)
		int argc = 1;
		for (int i=3;i<=max;i++) {
			sq_move(gv, v, i);
			argc++;
		}
		if (SQ_SUCCEEDED(result = sq_call(gv, argc, SQTrue, SQTrue))) {
			sq_move(v, gv, sq_gettop(gv));
			sq_pop(gv, 2);
		} else {
			sq_pop(gv, 1); // func
		}
	}
	return result;
}
Exemple #6
0
/**
 * 内部用:fork 処理。スレッドを1つ生成して VMにPUSHする
 * @param v squirrelVM
 * @return 成功したら true
 */
bool
Thread::_fork(HSQUIRRELVM v)
{
	// スレッドオブジェクトはグローバル上に生成する
	SQInteger max = sq_gettop(v);
	HSQUIRRELVM gv = getGlobalVM();
	sq_pushroottable(gv); // root
	sq_pushstring(gv, SQTHREADNAME, -1);
	if (SQ_SUCCEEDED(sq_get(gv,-2))) { // class
		sq_pushroottable(gv); // 引数:self(root)
		sq_pushnull(gv);      // 引数:delegate
		// 引数をコピー
		int argc = 2;
		if (gv == v) {
			for (int i=2;i<=max;i++) {
				sq_push(gv,i);
				argc++;
			}
		} else {
			for (int i=2;i<=max;i++) {
				sq_move(gv, v, i);
				argc++;
			}
		}
		if (SQ_SUCCEEDED(sq_call(gv, argc, SQTrue, SQTrue))) { // コンストラクタ呼び出し
			if (gv == v) {
				sq_remove(gv, -2); // class
				sq_remove(gv, -2); // root
			} else {
				sq_move(v, gv, sq_gettop(gv)); // 元VMのほうに移す
				sq_pop(gv, 3); // thread,class,root
			}
			return true;
		}
		sq_pop(gv, 1); // class
	}
	sq_pop(gv,1); // root
	return false;
}