Changed how userdata is handled
This commit is contained in:
@@ -6,18 +6,13 @@
|
||||
#include "traceback.hpp"
|
||||
#include <iostream>
|
||||
|
||||
LuaDefineType(World);
|
||||
|
||||
Tangible::Tangible() : world_(nullptr) {
|
||||
}
|
||||
|
||||
World::~World() {
|
||||
}
|
||||
|
||||
World::World() {
|
||||
// Initialize the userdata metatables.
|
||||
LuaStack::register_all_userdata(state());
|
||||
|
||||
World::World() {
|
||||
// Initialize the ID allocator in master mode.
|
||||
id_global_pool_.init_master(10);
|
||||
|
||||
@@ -26,8 +21,10 @@ World::World() {
|
||||
LuaStack LS(state(), world);
|
||||
|
||||
// Put the world pointer into the lua registry.
|
||||
LS.newpointer(world, this, false);
|
||||
LS.rawset(LuaRegistry, "world", world);
|
||||
World::store_global_pointer(state(), this);
|
||||
|
||||
// Clear the global GUI pointer.
|
||||
Gui::store_global_pointer(state(), nullptr);
|
||||
|
||||
// Create the tangibles table in the registry.
|
||||
LS.rawset(LuaRegistry, "tangibles", LuaNewTable);
|
||||
@@ -127,13 +124,21 @@ Tangible *World::tangible_make(lua_State *L, int64_t id, bool pushdb) {
|
||||
return t;
|
||||
}
|
||||
|
||||
World *World::fetch(lua_State *L) {
|
||||
LuaVar world;
|
||||
LuaStack LS(L, world);
|
||||
LS.rawget(world, LuaRegistry, "world");
|
||||
World *w = LS.ckuserdata<World>(world);
|
||||
LS.result();
|
||||
return w;
|
||||
void World::store_global_pointer(lua_State *L, World *v) {
|
||||
lua_pushstring(L, "world");
|
||||
lua_pushlightuserdata(L, v);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
World *World::fetch_global_pointer(lua_State *L) {
|
||||
lua_pushstring(L, "world");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
World *result = (World *)lua_touserdata(L, -1);
|
||||
if (result == nullptr) {
|
||||
luaL_error(L, "No world pointer stored.");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
|
||||
@@ -169,30 +174,25 @@ void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct the userdata with the GUI pointer.
|
||||
LS.newpointer<Gui>(ugui, gui, false);
|
||||
|
||||
// Call the interface function.
|
||||
lua_pushvalue(L, func.index());
|
||||
lua_pushvalue(L, actor.index());
|
||||
lua_pushvalue(L, place.index());
|
||||
lua_pushvalue(L, ugui.index());
|
||||
int status = traceback_pcall(L, 3, 0);
|
||||
Gui::store_global_pointer(L, gui);
|
||||
int status = traceback_pcall(L, 2, 0);
|
||||
Gui::store_global_pointer(L, nullptr);
|
||||
if (status != 0) {
|
||||
gui->clear();
|
||||
std::cerr << lua_tostring(L, -1);
|
||||
LS.result();
|
||||
return;
|
||||
}
|
||||
|
||||
// Nuke the userdata, in case somebody saved a pointer to it.
|
||||
LS.clearuserdata(ugui);
|
||||
|
||||
// And we're done.
|
||||
LS.result();
|
||||
}
|
||||
|
||||
void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &action) {
|
||||
void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &action, const GuiResult &gres) {
|
||||
// Validate that the action is legal.
|
||||
Gui validation_gui;
|
||||
update_gui(actor_id, place_id, &validation_gui);
|
||||
@@ -207,8 +207,8 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
|
||||
|
||||
// Set up for Lua manipulation.
|
||||
lua_State *L = state();
|
||||
LuaVar actor, place, func, tangibles, mt, index, actions, thread, threads, message;
|
||||
LuaStack LS(L, actor, place, func, tangibles, mt, index, actions, thread, threads, message);
|
||||
LuaVar actor, place, func, tangibles, mt, index, actions, thread, threads, message, guires;
|
||||
LuaStack LS(L, actor, place, func, tangibles, mt, index, actions, thread, threads, message, guires);
|
||||
|
||||
// Get the actor and place.
|
||||
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
||||
@@ -241,12 +241,18 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert the GuiResult into a lua table.
|
||||
LS.newtable(guires);
|
||||
for (const auto &p : gres) {
|
||||
LS.rawset(guires, p.first, p.second);
|
||||
}
|
||||
|
||||
// Create a new thread, set up function and parameters.
|
||||
lua_State *CO = LS.newthread(thread);
|
||||
lua_pushvalue(L, func.index());
|
||||
lua_pushvalue(L, actor.index());
|
||||
lua_pushvalue(L, place.index());
|
||||
lua_pushnil(L); // Gui state not implemented yet.
|
||||
lua_pushvalue(L, guires.index());
|
||||
lua_xmove(L, CO, 4);
|
||||
|
||||
// Store the thread into place's thread table.
|
||||
@@ -333,13 +339,18 @@ LuaDefine(tangible_get, "c") {
|
||||
}
|
||||
|
||||
LuaDefine(tangible_make, "c") {
|
||||
World::fetch(L)->tangible_make(L, 0, true);
|
||||
World::fetch_global_pointer(L)->tangible_make(L, 0, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LuaDefine(world_wait, "f") {
|
||||
if (lua_type(L, -1) != LUA_TNUMBER) {
|
||||
if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) {
|
||||
luaL_error(L, "Argument to wait must be a number.");
|
||||
}
|
||||
return lua_yield(L, 1);
|
||||
}
|
||||
|
||||
LuaDefine(world_getregistry, "f") {
|
||||
lua_pushvalue(L, LUA_REGISTRYINDEX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user