From 1f898afdd4ffa66bbc7733710877bb2612e6eaab Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Sun, 17 Jan 2021 16:23:10 -0500 Subject: [PATCH] Added tangible_make to world --- luprex/syscpp/animqueue.cpp | 14 ++++++--- luprex/syscpp/animqueue.hpp | 5 +++- luprex/syscpp/luastack.hpp | 11 ++++--- luprex/syscpp/world.cpp | 57 +++++++++++++++++++++++++++++++++++++ luprex/syscpp/world.hpp | 16 +++++++++++ 5 files changed, 94 insertions(+), 9 deletions(-) diff --git a/luprex/syscpp/animqueue.cpp b/luprex/syscpp/animqueue.cpp index 149cc5f0..a969a80e 100644 --- a/luprex/syscpp/animqueue.cpp +++ b/luprex/syscpp/animqueue.cpp @@ -7,9 +7,8 @@ AnimStep::AnimStep() {} AnimStep::~AnimStep() {} -AnimQueue::AnimQueue(int size_limit) { - assert(size_limit >= 2); - size_limit_ = size_limit; +AnimQueue::AnimQueue() { + size_limit_ = 10; // Default size limit. steps_.emplace_back(); AnimStep &init = steps_.back(); init.id_ = 0; @@ -20,6 +19,11 @@ AnimQueue::AnimQueue(int size_limit) { init.bits_ = AnimStep::HAS_EVERYTHING; } +void AnimQueue::set_size_limit(int n) { + assert(n >= 2); + size_limit_ = n; +} + void AnimQueue::add(int64_t id, const std::string &action) { steps_.emplace_back(); AnimStep &last = steps_.back(); @@ -73,7 +77,9 @@ const util::XYZ &AnimQueue::get_xyz() const { LuaDefine(unittests_animqueue, "c") { // Check initial state. - AnimQueue aq(3); + AnimQueue aq; + aq.set_size_limit(3); + LuaAssert(L, aq.size() == 1); const AnimStep *st = &aq.nth(0); LuaAssert(L, st->id() == 0); diff --git a/luprex/syscpp/animqueue.hpp b/luprex/syscpp/animqueue.hpp index c3164bd6..e6e7f080 100644 --- a/luprex/syscpp/animqueue.hpp +++ b/luprex/syscpp/animqueue.hpp @@ -76,7 +76,7 @@ private: int size_limit_; std::deque steps_; public: - AnimQueue(int size_limit); + AnimQueue(); const AnimStep &nth(int n) const { return steps_[n]; } int size() const { return steps_.size(); } @@ -90,6 +90,9 @@ public: // Get the final resting place. const std::string &get_plane() const; const util::XYZ &get_xyz() const; + + // Functions for unit testing. + void set_size_limit(int n); }; #endif // ANIMQUEUE_HPP diff --git a/luprex/syscpp/luastack.hpp b/luprex/syscpp/luastack.hpp index 1cb92776..039e43dc 100644 --- a/luprex/syscpp/luastack.hpp +++ b/luprex/syscpp/luastack.hpp @@ -3,10 +3,13 @@ // // LUASTACK // -// Class LuaStack lets you create "lua local variables." These are -// variables that seem to store lua values. Class LuaStack also provides -// accessors like "rawget" that reference lua local variables instead of -// using the lua stack. +// The standard lua C API asks you to work with a stack machine. You're supposed +// to manually push and pop values on the lua stack. I find this difficult, I +// find it hard to remember what stack position contains what value. +// +// To make it easier, I've created this module, "LuaStack." This module +// creates the illusion that you're working with local variables that contain +// lua values. // // Of course, this is all using the lua stack under the covers. Lua // local variables are actually just lua stack addresses. But that's diff --git a/luprex/syscpp/world.cpp b/luprex/syscpp/world.cpp index 3e801f27..582e5d7f 100644 --- a/luprex/syscpp/world.cpp +++ b/luprex/syscpp/world.cpp @@ -5,6 +5,9 @@ LuaDefineType(World); +Tangible::Tangible() : world_(nullptr) { +} + World::~World() { } @@ -19,6 +22,9 @@ World::World() { // Initialize the userdata metatables. LuaStack::register_all_userdata(lua_state_); + // Initialize the ID allocator in master mode. + id_global_pool_.init_master(10); + // Prepare to manipulate the lua state. LuaVar world; LuaStack LS(lua_state_, world); @@ -27,6 +33,9 @@ World::World() { LS.newpointer(world, this, false); LS.setfield(LuaRegistry, "world", world); + // Create the tangibles table in the registry. + LS.setfield(LuaRegistry, "tangibles", LuaNewTable); + // Initialize the SourceDB source_db_.initialize(lua_state_); @@ -38,6 +47,39 @@ World::World() { source_db_.run_unittests(); } +Tangible *World::tangible_make(lua_State *L) { + LuaVar tangibles, metatab; + LuaRet database; + LuaStack LS(L, tangibles, database, metatab); + + // Get a fresh ID. + int64_t id = id_global_pool_.alloc_id_for_thread(L); + + // Create the C++ part of the structure. + Tangible *t = &tangibles_[id]; + assert(t->world_ == nullptr); + t->world_ = this; + plane_map_.track(&t->plane_item_); + + // Create the tangible's database and metatable. + LS.set(database, LuaNewTable); + LS.set(metatab, LuaNewTable); + LS.setmetatable(database, metatab); + + // Store the database into the tangibles table. + LS.getfield(tangibles, LuaRegistry, "tangibles"); + LS.rawset(tangibles, id, database); + + // Populate the database and metatable with initial stuff. + LS.setfield(database, "inventory", LuaNewTable); + LS.setfield(database, "id", id); + LS.setfield(metatab, "id", id); + // LS.setfield(metatab, "__metatable", LuaNil); + + LS.result(); + return t; +} + World *World::fetch(lua_State *L) { LuaVar world; LuaStack LS(L, world); @@ -47,3 +89,18 @@ World *World::fetch(lua_State *L) { return w; } +LuaDefine(tangible_get, "c") { + LuaArg id; + LuaRet database; + LuaVar tangibles; + LuaStack LS(L, id, database, tangibles); + + LS.getfield(tangibles, LuaRegistry, "tangibles"); + LS.rawget(database, tangibles, id); + return LS.result(); +} + +LuaDefine(tangible_make, "c") { + World::fetch(L)->tangible_make(L); + return 1; +} diff --git a/luprex/syscpp/world.hpp b/luprex/syscpp/world.hpp index c1ee3a87..29087aff 100644 --- a/luprex/syscpp/world.hpp +++ b/luprex/syscpp/world.hpp @@ -14,6 +14,10 @@ class World; class Tangible { public: + // Simple constructor initializes everything to null. + // + Tangible(); + // Always points back to the world model. World *world_; @@ -68,6 +72,18 @@ public: // lua_State *get_lua_state() { return lua_state_; } + // Make a tangible with a generated ID. + // + // Pushes the database onto the lua stack and returns the tangible pointer. + // + Tangible *tangible_make(lua_State *L); + + // Delete a tangible with the specified ID. + // + // If the tangible doesn't exist, does nothing. + // + void tangible_del(int64_t id); + // fetch // // Given a lua state, fetch the world model associated with