Added code to probe 'interface'

This commit is contained in:
2021-02-07 17:26:48 -05:00
parent 8c15e56fe9
commit 368d066cc7
5 changed files with 73 additions and 9 deletions

View File

@@ -8,6 +8,11 @@ LuaNilMarker LuaNil;
LuaNewTableMarker LuaNewTable; LuaNewTableMarker LuaNewTable;
LuaDiscardMarker LuaDiscard; LuaDiscardMarker LuaDiscard;
void LuaStack::clear_tagged_pointer(LuaSlot target) {
TaggedPointer *tp = (TaggedPointer*)lua_touserdata(L_, target.index());
tp->ptr = 0;
}
void LuaStack::make_tagged_pointer(LuaSlot target, void *ptr, LuaTypeTag tag, LuaDeleterFn del) { void LuaStack::make_tagged_pointer(LuaSlot target, void *ptr, LuaTypeTag tag, LuaDeleterFn del) {
TaggedPointer *tp = (TaggedPointer*)lua_newuserdata(L_, sizeof(TaggedPointer)); TaggedPointer *tp = (TaggedPointer*)lua_newuserdata(L_, sizeof(TaggedPointer));
tp->ptr = ptr; tp->ptr = ptr;
@@ -21,7 +26,7 @@ void LuaStack::make_tagged_pointer(LuaSlot target, void *ptr, LuaTypeTag tag, Lu
} }
int LuaStack::collect_tagged_pointer(lua_State *L) { int LuaStack::collect_tagged_pointer(lua_State *L) {
LuaStack::TaggedPointer *p = (LuaStack::TaggedPointer*)lua_touserdata(L, 1); TaggedPointer *p = (TaggedPointer*)lua_touserdata(L, 1);
if (p==0) { if (p==0) {
luaL_error(L, "lua deleter function received a non-userdata"); luaL_error(L, "lua deleter function received a non-userdata");
} }

View File

@@ -372,6 +372,7 @@ private:
}; };
static int collect_tagged_pointer(lua_State *L); static int collect_tagged_pointer(lua_State *L);
void make_tagged_pointer(LuaSlot target, void *ptr, LuaTypeTag tag, LuaDeleterFn del); void make_tagged_pointer(LuaSlot target, void *ptr, LuaTypeTag tag, LuaDeleterFn del);
void clear_tagged_pointer(LuaSlot target);
template<typename T> template<typename T>
static void delete_pointer(void *p) { delete (T*)p; } static void delete_pointer(void *p) { delete (T*)p; }
@@ -449,6 +450,8 @@ public:
return (T*)(tp->ptr); return (T*)(tp->ptr);
} }
void clearuserdata(LuaSlot target) { clear_tagged_pointer(target); }
int next(LuaSlot tab, LuaSlot key, LuaSlot value) const; int next(LuaSlot tab, LuaSlot key, LuaSlot value) const;
bool isemptytable(LuaSlot s) const; bool isemptytable(LuaSlot s) const;
@@ -462,6 +465,13 @@ public:
pop_any_value(target); pop_any_value(target);
} }
template<typename RT, typename KT>
void gettable(RT &target, LuaSlot tab, KT key) const {
push_any_value(key);
lua_gettable(L_, tab);
pop_any_value(target);
}
template<typename RT, typename KT> template<typename RT, typename KT>
void rawget(RT &target, LuaSlot tab, KT key) const { void rawget(RT &target, LuaSlot tab, KT key) const {
push_any_value(key); push_any_value(key);

View File

@@ -13,13 +13,7 @@ int64_t Viewer::get_player_id() {
return 1; return 1;
} }
void Viewer::update_gui(int64_t id, Gui *gui) { void Viewer::update_gui(int64_t place, Gui *gui) {
gui->clear(); world_->update_gui(get_player_id(), place, gui);
gui->add_menu_item("north", "north");
gui->add_menu_item("south", "south");
gui->add_menu_item("east", "east");
gui->add_menu_item("west", "west");
gui->add_menu_item("build", "build");
gui->add_menu_item("destroy", "destroy");
} }

View File

@@ -2,6 +2,8 @@
#include "world.hpp" #include "world.hpp"
#include "idalloc.hpp" #include "idalloc.hpp"
#include "animqueue.hpp" #include "animqueue.hpp"
#include "gui.hpp"
#include "traceback.hpp"
#include <iostream> #include <iostream>
LuaDefineType(World); LuaDefineType(World);
@@ -131,6 +133,54 @@ World *World::fetch(lua_State *L) {
return w; return w;
} }
void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
gui->clear();
lua_State *L = get_lua_state();
LuaVar actor, place, ugui, func, tangibles;
LuaStack LS(L, actor, place, ugui, func, tangibles);
// Get the actor and place.
LS.getfield(tangibles, LuaRegistry, "tangibles");
LS.rawget(actor, tangibles, actor_id);
LS.rawget(place, tangibles, place_id);
if (!LS.istable(actor) || !LS.istable(place)) {
LS.result();
return;
}
// Get the interface closure.
LS.getfield(func, place, "interface");
if (!LS.isfunction(func)) {
LS.result();
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);
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();
}
LuaDefine(tangible_get, "c") { LuaDefine(tangible_get, "c") {
LuaArg id; LuaArg id;
LuaRet database; LuaRet database;

View File

@@ -7,6 +7,7 @@
#include "idalloc.hpp" #include "idalloc.hpp"
#include "animqueue.hpp" #include "animqueue.hpp"
#include "source.hpp" #include "source.hpp"
#include "gui.hpp"
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
@@ -106,6 +107,10 @@ public:
// //
void tangible_del(int64_t id); void tangible_del(int64_t id);
// Probe the 'interface' function of the specified sprite.
//
void update_gui(int64_t actor_id, int64_t place_id, Gui *gui);
// fetch // fetch
// //
// Given a lua state, fetch the world model associated with // Given a lua state, fetch the world model associated with