From 293095356910b8df8d19342bf434b59cb173c9c6 Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Tue, 20 Jul 2021 14:48:53 -0400 Subject: [PATCH] Minor tweaks and a new deque operator --- luprex/core/cpp/animqueue.cpp | 2 +- luprex/core/cpp/idalloc.cpp | 2 +- luprex/core/cpp/luasnap.cpp | 4 +-- luprex/core/cpp/streambuffer.cpp | 24 ++++++++--------- luprex/core/cpp/streambuffer.hpp | 24 ++++++++--------- luprex/core/cpp/table.cpp | 39 +++++++++++++++++++++++++++ luprex/core/cpp/table.hpp | 37 +++++++++---------------- luprex/core/cpp/viewer.cpp | 19 ------------- luprex/core/cpp/viewer.hpp | 46 -------------------------------- luprex/core/cpp/world.cpp | 4 +-- 10 files changed, 81 insertions(+), 120 deletions(-) delete mode 100644 luprex/core/cpp/viewer.cpp delete mode 100644 luprex/core/cpp/viewer.hpp diff --git a/luprex/core/cpp/animqueue.cpp b/luprex/core/cpp/animqueue.cpp index 4c99eda2..dac97958 100644 --- a/luprex/core/cpp/animqueue.cpp +++ b/luprex/core/cpp/animqueue.cpp @@ -619,7 +619,7 @@ LuaDefine(unittests_animqueue, "c") { // Apply the diffs, 4 extra bytes should remain. aqds.apply_patch(&sb); - LuaAssert(L, sb.write_count() - sb.read_count() == 4); + LuaAssert(L, sb.total_writes() - sb.total_reads() == 4); LuaAssert(L, aqds.size_and_steps_equal(aq)); // Change the queue size limit. diff --git a/luprex/core/cpp/idalloc.cpp b/luprex/core/cpp/idalloc.cpp index 57e26884..6ed5f9f4 100644 --- a/luprex/core/cpp/idalloc.cpp +++ b/luprex/core/cpp/idalloc.cpp @@ -430,7 +430,7 @@ LuaDefine(unittests_idalloc, "c") { LuaAssert(L, ppds.make_patch(pp, &sb)); sb.write_uint32(0); ppds.apply_patch(&sb); - LuaAssert(L, sb.write_count() - sb.read_count() == 4); + LuaAssert(L, sb.total_writes() - sb.total_reads() == 4); LuaAssert(L, ppds.exactly_equal(pp)); // Pop a value from master pool diff --git a/luprex/core/cpp/luasnap.cpp b/luprex/core/cpp/luasnap.cpp index 9351404d..363b310b 100644 --- a/luprex/core/cpp/luasnap.cpp +++ b/luprex/core/cpp/luasnap.cpp @@ -64,9 +64,9 @@ void LuaSnap::serialize(StreamBuffer *sb) { // Write dummy length, use eris to write data, then overwrite length. sb->write_int64(0); - int64_t pos1 = sb->write_count(); + int64_t pos1 = sb->total_writes(); eris_dump(state_, sb->lua_writer, sb->lua_writer_ud()); - int64_t pos2 = sb->write_count(); + int64_t pos2 = sb->total_writes(); sb->overwrite_int64(pos1, pos2 - pos1); lua_settop(state_, 0); std::cerr << "Eris dump is " << pos2-pos1 << " bytes." << std::endl; diff --git a/luprex/core/cpp/streambuffer.cpp b/luprex/core/cpp/streambuffer.cpp index 5834605b..6b9fb00e 100644 --- a/luprex/core/cpp/streambuffer.cpp +++ b/luprex/core/cpp/streambuffer.cpp @@ -33,11 +33,11 @@ StreamBuffer::~StreamBuffer() { if (owned_ && (buf_lo_ != 0)) delete buf_lo_; } -int64_t StreamBuffer::read_count() const { +int64_t StreamBuffer::total_reads() const { return (read_cursor_ - buf_lo_) + pre_read_count_; } -int64_t StreamBuffer::write_count() const { +int64_t StreamBuffer::total_writes() const { return (write_cursor_ - buf_lo_) + pre_read_count_; } @@ -83,8 +83,8 @@ void StreamBuffer::make_space_slow(int64_t bytes) { char *StreamBuffer::get_overwrite(int64_t size, int64_t write_count_after) { int64_t write_count_before = write_count_after - size; - assert(write_count_before >= read_count()); - assert(write_count_after <= write_count()); + assert(write_count_before >= total_reads()); + assert(write_count_after <= total_writes()); return buf_lo_ + (write_count_before - pre_read_count_); } @@ -386,13 +386,13 @@ void StreamBuffer::verify_eof() { void StreamBuffer::unread_to(int64_t rd_count) { assert(rd_count >= pre_read_count_); - assert(rd_count <= read_count()); + assert(rd_count <= total_reads()); read_cursor_ = buf_lo_ + (rd_count - pre_read_count_); } void StreamBuffer::unwrite_to(int64_t wr_count) { - assert(wr_count >= read_count()); - assert(wr_count <= write_count()); + assert(wr_count >= total_reads()); + assert(wr_count <= total_writes()); write_cursor_ = buf_lo_ + (wr_count - pre_read_count_); } @@ -514,13 +514,13 @@ LuaDefine(unittests_streambuffer, "c") { // Check the write count and read count accumulator ability. sb11.clear(); - assert(sb11.write_count() == 0); - assert(sb11.read_count() == 0); + assert(sb11.total_writes() == 0); + assert(sb11.total_reads() == 0); for (int i = 0; i < 10; i++) { - assert(sb11.write_count() == i * 8); + assert(sb11.total_writes() == i * 8); sb11.write_int32(i); sb11.write_int32(i+1000000); - assert(sb11.read_count() == i * 8); + assert(sb11.total_reads() == i * 8); assert(sb11.read_int32() == i); assert(sb11.read_int32() == i+1000000); } @@ -533,7 +533,7 @@ LuaDefine(unittests_streambuffer, "c") { for (int i = 0; i < 2; i++) { sb11.write_int16(12); sb11.write_int16(34); - int64_t wc = sb11.write_count(); + int64_t wc = sb11.total_writes(); sb11.write_int16(56); sb11.write_int16(78); sb11.overwrite_int16(wc, 90); diff --git a/luprex/core/cpp/streambuffer.hpp b/luprex/core/cpp/streambuffer.hpp index 9d9b0ade..41ae98ec 100644 --- a/luprex/core/cpp/streambuffer.hpp +++ b/luprex/core/cpp/streambuffer.hpp @@ -49,9 +49,9 @@ // streambuffer.write_int32(0); // // // Write the data, and calculate its length in bytes. -// int64_t write_count_1 = streambuffer.write_count(); +// int64_t write_count_1 = streambuffer.total_writes(); // write_data(stream); -// int64_t write_count_2 = streambuffer.write_count(); +// int64_t write_count_2 = streambuffer.total_writes(); // int64_t data_len = write_count_2 - write_count_1; // // // Overwrite the previously-written dummy length. @@ -130,7 +130,7 @@ // Here is the construction that accomplishes this: // // // Get the stream's read count before parsing the message. -// size_t read_count_before = streambuffer.read_count(); +// size_t read_count_before = streambuffer.total_reads(); // // // Parse the message, but if there's an EOF, deal with it: // try { @@ -164,7 +164,7 @@ // // A StreamBuffer that reads from an external block of bytes is read-only. // Attempts to write to this buffer will be caught and will cause an abort. The -// write_count for such a buffer returns the 'len' value that you initialized +// total_writes for such a buffer returns the 'len' value that you initialized // the buffer with. // // USING A STREAMBUFFER TO READ AN ENTIRE FILE @@ -251,13 +251,13 @@ public: ~StreamBuffer(); // Get the total number of bytes ever read from this buffer. - int64_t read_count() const; + int64_t total_reads() const; // Get the total number of bytes ever written to this buffer. - int64_t write_count() const; + int64_t total_writes() const; - // Delete all data and (if not fixed-size) free the buffer. - // Also resets the read and write counts. + // Discard all data. Reset total read and write counts. + // Frees up as much space as possible. void clear(); // Write block of bytes into the buffer. @@ -269,7 +269,7 @@ public: // Read a block of bytes from the buffer. // - // May throw StreamEof if the specified number of bytes aren't present. + // Throws StreamEof if the specified number of bytes aren't present. // const char *read_bytes(int64_t bytes); @@ -316,7 +316,7 @@ public: // Read other types from the buffer. // - // May throw StreamEof if the specified number of bytes aren't present. + // Throws StreamEof if the specified number of bytes aren't present. // Read string with a length limit will throw 'StreamCorruption' if the // length is too long. // @@ -345,10 +345,10 @@ public: void verify_eof(); // Rewind the read cursor to a previous position. - void unread_to(int64_t read_count); + void unread_to(int64_t total_reads); // Rewind the write cursor to a previous position. - void unwrite_to(int64_t write_count); + void unwrite_to(int64_t total_writes); // Calculate a noncryptographic but good hash of what's in the buffer. util::HashValue hash() const; diff --git a/luprex/core/cpp/table.cpp b/luprex/core/cpp/table.cpp index bf261bf6..41c0b3b3 100644 --- a/luprex/core/cpp/table.cpp +++ b/luprex/core/cpp/table.cpp @@ -316,6 +316,45 @@ LuaDefine(deque_nthr, "c") { return LS.result(); } +LuaDefine(deque_findl, "c") { + LuaArg deque, val; + LuaRet pos; + LuaVar check; + LuaStack LS(L, deque, val, pos, check); + int left, fill, max; + deque_get_info(L, deque.index(), &left, &fill, &max); + for (int i = 0; i < fill; i++) { + int index = (left + i) & (max - 1); + LS.rawgeti(check, deque, DEQUE_BASE + index); + if (LS.rawequal(check, val)) { + LS.set(pos, i + 1); + return LS.result(); + } + } + LS.set(pos, LuaNil); + return LS.result(); +} + +LuaDefine(deque_findr, "c") { + LuaArg deque, val; + LuaRet pos; + LuaVar check; + LuaStack LS(L, deque, val, pos, check); + int left, fill, max; + deque_get_info(L, deque.index(), &left, &fill, &max); + int base = left + fill - 1; + for (int i = 0; i < fill; i++) { + int index = (base - i) & (max - 1); + LS.rawgeti(check, deque, DEQUE_BASE + index); + if (LS.rawequal(check, val)) { + LS.set(pos, i + 1); + return LS.result(); + } + } + LS.set(pos, LuaNil); + return LS.result(); +} + LuaDefine(deque_size, "c") { LuaArg deque; LuaRet size; diff --git a/luprex/core/cpp/table.hpp b/luprex/core/cpp/table.hpp index 46c2ec0c..315c6cd9 100644 --- a/luprex/core/cpp/table.hpp +++ b/luprex/core/cpp/table.hpp @@ -1,30 +1,8 @@ //////////////////////////////////////////////////////////// // -// TABLE -// // This module contains a library of lua functions -// for manipulating tables. Some of the functions only -// work on vectors (ie, tables with integer keys starting -// at one). When a function only works on vectors, it -// is noted. -// -// QUEUE -// -// This module contains a library of lua functions for -// manipulating queues. Queues are represented as a table -// with a "head" and a "tail", and with integer-keyed values. -// For example: -// -// { -// "tail": 100, -// "head": 103, -// 100: "a", -// 101: "b", -// 102: "c" -// } -// -// Values are pushed onto the head, and values are popped -// from the tail. +// for manipulating tables. It also provides a library +// of useful classes based on tables. // //////////////////////////////////////////////////////////// @@ -80,7 +58,7 @@ int table_count(lua_State *L); int table_clear(lua_State *L); // -// Create and return an empty queue. Queues are implemented +// Create and return an empty deque. Queues are implemented // as tables which are used as dynamically-expandable circular // buffers. // @@ -107,6 +85,15 @@ int deque_popr(lua_State *L); int deque_nthl(lua_State *L); int deque_nthr(lua_State *L); +// +// Search a deque for a value. +// +// Search starts on the specified end and indices are relative +// to specified end. +// +int deque_findl(lua_State *L); +int deque_findr(lua_State *L); + // // Return the number of values in the deque. // diff --git a/luprex/core/cpp/viewer.cpp b/luprex/core/cpp/viewer.cpp deleted file mode 100644 index 0be28186..00000000 --- a/luprex/core/cpp/viewer.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -#include "viewer.hpp" - -Viewer::Viewer() { - world_.reset(new World); - world_->init_standalone(); -} - -Viewer::~Viewer() { -} - -int64_t Viewer::get_player_id() { - return 1; -} - -void Viewer::update_gui(int64_t place, Gui *gui) { - world_->update_gui(get_player_id(), place, gui); -} - diff --git a/luprex/core/cpp/viewer.hpp b/luprex/core/cpp/viewer.hpp deleted file mode 100644 index 85f7c5fa..00000000 --- a/luprex/core/cpp/viewer.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef VIEWER_HPP -#define VIEWER_HPP - -#include "world.hpp" -#include "animqueue.hpp" -#include "gui.hpp" -#include -#include -#include - -class Viewer { -private: - std::unique_ptr world_; - -public: - Viewer(); - ~Viewer(); - - // Snapshot/rollback the lua state (temporary hack) - void snapshot() { world_->lua_snap_.snapshot(); } - void rollback() { world_->lua_snap_.rollback(); } - - // Get the lua state for interaction. - // - lua_State *state() { return world_->state(); } - - // Get the player ID of the current player. - // - int64_t get_player_id(); - - // Get the list of tangibles near the player. - // - std::vector get_near() { return world_->get_near(1, 100); } - - // Get the specified tangible. - // - const Tangible *tangible_get(int64_t id) { return world_->tangible_get(id); } - - // Update the GUI for the specified sprite. - // - // The gui passed in will be overwritten. - // - void update_gui(int64_t id, Gui *g); -}; - -#endif // VIEWER_HPP diff --git a/luprex/core/cpp/world.cpp b/luprex/core/cpp/world.cpp index d0bfb255..45c91fbb 100644 --- a/luprex/core/cpp/world.cpp +++ b/luprex/core/cpp/world.cpp @@ -429,7 +429,7 @@ void World::run_scheduled_threads(int64_t clk) { void World::serialize(StreamBuffer *sb) { assert(stack_is_clear()); assert(redirects_.empty()); - int64_t wc0 = sb->write_count(); + int64_t wc0 = sb->total_writes(); lua_snap_.serialize(sb); id_global_pool_.serialize(sb); thread_sched_.serialize(sb); @@ -438,7 +438,7 @@ void World::serialize(StreamBuffer *sb) { sb->write_int64(p.first); p.second->serialize(sb); } - int64_t wc1 = sb->write_count(); + int64_t wc1 = sb->total_writes(); std::cerr << "World serialized to " << wc1-wc0 << " bytes." << std::endl; assert(stack_is_clear()); }