Esempio n. 1
0
// [-3, +3, e]
static int
lcf_socket_read(lua_State *L) {
  as_lm_socket_t *sock = (as_lm_socket_t *)luaL_checkudata(
      L, 1, LM_SOCKET);
  int timeout = luaL_checkinteger(L, 3);
  if (timeout < 0) {
    timeout = LAS_D_TIMOUT_SECS;
  }

  as_thread_res_t *res = sock->res;
  if (res == NULL) {
    lua_pushinteger(L, 0);
    lua_pushnil(L);
    lua_pushinteger(L, EBADFD);
    return 3;
  }

  if (res->th->mode != AS_TMODE_SIMPLE) {
    lua_pushstring(L, "ev error");
    lua_error(L);
  }

  lua_pushinteger(L, LAS_S_YIELD_FOR_IO);
  lua_pushlightuserdata(L, res);
  lua_pushinteger(L, LAS_S_WAIT_FOR_INPUT);
  lua_pushinteger(L, timeout);
  return lua_yieldk(L, 4, (lua_KContext)NULL, k_socket_read);
}
Esempio n. 2
0
int32_t context_lua_t::lua_yield_send(lua_State *L, uint32_t destination, yiled_finalize_t fnz, void* fnz_ud, lua_KFunction yieldk, int64_t timeout)
{
	int stacks;
	context_lua_t* lctx = context_lua_t::lua_get_context(L);
	lctx->m_shared->m_yielding_destination = destination;
	lctx->m_shared->m_yielding_depth = 1;
	lctx->m_shared->m_yielding_finalize = fnz; /* fnz should not be null better */
	lctx->m_shared->m_yielding_finalize_userdata = fnz_ud;
	lctx->m_shared->m_yielding_status = UV_OK;
	lctx->m_shared->m_yielding_timeout = timeout;
	if ((stacks = lua_checkstack(L, LUA_MINSTACK)) && lua_yieldable(L)) { /* reserve LUA_MINSTACK stack for resume result */
		return lua_yieldk(L, 0, 0, yieldk); /* n(0) result to yield and ctx(0) is not allowed */
	} else {
		if (stacks) { /* stack enough, but not yield-able */
			lctx->yielding_finalize(NULL, NL_EYIELD);
			lua_pushboolean(L, 0);
			lua_pushinteger(L, NL_EYIELD);
			lua_pushnil(L);
			lua_pushnil(L);
			return (yieldk == NULL) ? 4 : yieldk(L, LUA_YIELD, 0);
		} else { /* error jump directly */
			lctx->yielding_finalize(NULL, NL_ESTACKLESS);
			return luaL_error(L, "attempt to yield across a stack-less coroutine");
		}
	}
}
Esempio n. 3
0
// startTalking()
// 	startTalking opens the conversation screen and returns its interface.
int talk_lua_start(lua_State *L) {
	lua_getfield(L, LUA_REGISTRYINDEX, "game/stateStack");
	if (lua_isnil(L, -1)) {
		return luaL_error(L, "game not initialized yet");
	}
	state_stack *stack = (state_stack*) lua_touserdata(L, -1);
	lua_pop(L, 1);
	
	state_desc *top = (state_desc*) table_ind(stack, stack->m_len-1);
	int i;
	if (lua_getctx(L, &i) == LUA_OK) {
		top->m_fnPushChild = _talk_push;
		top->m_pChildData = (void*) L;
		return lua_yieldk(L, 0, 0, talk_lua_start);
	}
	
	luaL_Reg funcs[] = {
		{ "resetChoices", _lua_resetchoices },
		{ "addChoice", _lua_addchoice },
		{ "offerChoice", _lua_offerchoice },
		{ "wait", _lua_wait },
		{ "say", _lua_say },
		{ "stop", _lua_stop },
		{ nullptr, nullptr },
	};
	
	luaL_newlibtable(L, funcs);
	top = (state_desc*) table_ind(stack, stack->m_len-1);
	lua_pushlightuserdata(L, top->m_pData);
	luaL_setfuncs(L, funcs, 1);
	return 1;
}
Esempio n. 4
0
// [-0, +3, e]
static int
lcf_socket_ev_wait(lua_State *L) {
  int timeout = luaL_checkinteger(L, 1);

  lua_pushinteger(L, LAS_S_YIELD_FOR_EV);
  lua_pushinteger(L, timeout);
  return lua_yieldk(L, 2, (lua_KContext)NULL, k_socket_ev_wait);
}
Esempio n. 5
0
static int
k_socket_send(lua_State *L, int status, lua_KContext c) {
  as_thread_res_t *res = NULL;
  _send_ctx_t *ctx = (_send_ctx_t *)c;

  if (status == LUA_OK) {
    res = ctx->res;
  } else if (status == LUA_YIELD) {
    int type = luaL_checkinteger(L, 1);
    // as_thread_res_t *rres = (as_thread_res_t *)lua_touserdata(L, 2);
    // int io = luaL_checkinteger(L, 3);

    if (type == LAS_S_RESUME_IO_TIMEOUT) {
      lua_pushinteger(L, ctx->idx);
      lua_pushinteger(L, ETIMEDOUT);
      memp_recycle(ctx);
      return 2;
    } else {
      res = (as_thread_res_t *)lua_touserdata(L, -2);
      lua_pop(L, 3);
    }
  } else {
    memp_recycle(ctx);
    lua_pushstring(L, "send error");
    lua_error(L);
  }

  int fd = res->fdf(res);
  while (1) {
    const char *buf = ctx->buf + ctx->idx;
    size_t len = ctx->len - ctx->idx;
    ssize_t nbyte = send(fd, buf, len, MSG_NOSIGNAL);
    if (nbyte == len) {
      lua_pushinteger(L, ctx->len);
      lua_pushnil(L);
      break;
    } else if (nbyte == -1 && errno != EAGAIN) {
      lua_pushinteger(L, ctx->idx);
      lua_pushinteger(L, errno);
      break;
    } else if (nbyte == -1) {
      lua_pushinteger(L, LAS_S_YIELD_FOR_IO);
      lua_pushlightuserdata(L, res);
      lua_pushinteger(L, LAS_S_WAIT_FOR_OUTPUT);
      lua_pushinteger(L, LAS_D_TIMOUT_SECS);
      return lua_yieldk(L, 4, (lua_KContext)ctx, k_socket_send);
    } else {
      ctx->idx += nbyte;
    }
  }

  memp_recycle(ctx);
  return 2;
}
Esempio n. 6
0
// wait()
// 	wait blocks (yields to the C code), waiting until the user is ready to continue.
// 	Call this in situations where a "press any key to continue" prompt would be appropriate.
int _lua_wait(lua_State *L) {
	_talk_state *st = (_talk_state*) lua_touserdata(L, lua_upvalueindex(1));
	int ctx, status;
	if (st->m_iState == _STOPPED) {
		return luaL_error(L, "conversation is already stopped");
	}
	
	status = lua_getctx(L, &ctx);
	if (status == LUA_YIELD) {
		return 0;
	}
	
	st->m_iState = _WAIT_ANY;
	st->m_pThread = L;
	return lua_yieldk(L, 0, 0, _lua_wait);
}
Esempio n. 7
0
static int auxresume (lua_State *L, lua_State *co, int narg) {
	int status, stacks;
	int ismain = lua_pushthread(L);
	lua_pop(L, 1);
	if (ismain) {
		lua_pushliteral(L, "cannot call resume in main thread");
		return -1;  /* error flag */
	}
	if (!lua_checkstack(co, narg)) {
		lua_pushliteral(L, "too many arguments to resume");
		return -1;  /* error flag */
	}
	if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
		lua_pushliteral(L, "cannot resume dead coroutine");
		return -1;  /* error flag */
	}
	lua_xmove(L, co, narg);
	context_lua_t *lctx = context_lua_t::lua_get_context(L);
	while (((status = lua_resume(co, L, narg)) == LUA_YIELD) && lctx->yielding_up()) { /* can happen only when status == LUA_YIELD */
		if ((stacks = lua_checkstack(L, LUA_MINSTACK)) && lua_yieldable(L)) { /* reserve LUA_MINSTACK stack for resume result */
			return lua_yieldk(L, 0, 0, coresume_continue); /* yield again! n(0) result to yield and ctx(0) is not allowed */
		} else { /* lua_gettop(co) must be 0 since context_lua_t::lua_yield_send yield 0 result */
			int yieldup_status = stacks ? NL_EYIELD : NL_ESTACKLESS;
			lctx->yielding_finalize(NULL, yieldup_status);
			lua_pushboolean(co, 0); /* stack on co must be enough since we have checked it at last yield */
			lua_pushinteger(co, yieldup_status);
			lua_pushnil(co);
			lua_pushnil(co);
			narg = 4;
		}
	}
	if (status == LUA_OK || status == LUA_YIELD) {
		int nres = lua_gettop(co);
		if (!lua_checkstack(L, nres + 1)) {
			lua_pop(co, nres);  /* remove results anyway */
			lua_pushliteral(L, "too many results to resume");
			return -1;  /* error flag */
		}
		lua_xmove(co, L, nres);  /* move yielded values */
		return nres;
	} else {
		lua_xmove(co, L, 1);  /* move error message */
		return -1;  /* error flag */
	}
}
Esempio n. 8
0
// offerChoice()
// 	offerChoice blocks (yields to the C code) until the user makes a choice, returning
// 	the 1-based index of the chosen option.
int _lua_offerchoice(lua_State *L) {
	_talk_state *st = (_talk_state*) lua_touserdata(L, lua_upvalueindex(1));
	int ctx, status;
	if (st->m_iState == _STOPPED) {
		return luaL_error(L, "conversation is already stopped");
	}
	
	status = lua_getctx(L, &ctx);
	if (status == LUA_YIELD) {
		return 1;  // choice should be pushed on the stack before resuming
	}
	
	if (status != LUA_OK) { sys_abort(); }

	menu_auto_resize(st->m_pChoices);
	st->m_iState = _WAIT_CHOICE;
	st->m_pThread = L;
	return lua_yieldk(L, 0, 0, _lua_offerchoice);
}
Esempio n. 9
0
int lua_engine::emu_wait(lua_State *L)
{
	luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected");
	machine().scheduler().timer_set(attotime::from_double(lua_tonumber(L, 1)), timer_expired_delegate(FUNC(lua_engine::resume), this), 0, L);
	return lua_yieldk(L, 0, 0, 0);
}
Esempio n. 10
0
LUA_API int luaS_yield(lua_State *L, int nrets) {
	int ret = lua_yieldk(L, nrets, 0, k);
	return ret;
}
Esempio n. 11
0
LUA_API int luaS_yield(lua_State *L, int nrets) {
	return k(L, lua_yieldk(L, nrets, 0, k), 0);
}