From 490727fdc0f7fc58bd8ab7420cdb9397465a37f6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 16 Jun 2024 20:15:26 +0300 Subject: [PATCH 1/7] add lua user types + bytearray --- src/logic/scripting/lua/lua_custom_types.cpp | 86 ++++++++++++++++++++ src/logic/scripting/lua/lua_custom_types.hpp | 39 +++++++++ src/logic/scripting/lua/lua_engine.cpp | 4 +- src/logic/scripting/lua/lua_util.cpp | 9 ++ src/logic/scripting/lua/lua_util.hpp | 58 +++++++++++-- 5 files changed, 186 insertions(+), 10 deletions(-) create mode 100644 src/logic/scripting/lua/lua_custom_types.cpp create mode 100644 src/logic/scripting/lua/lua_custom_types.hpp diff --git a/src/logic/scripting/lua/lua_custom_types.cpp b/src/logic/scripting/lua/lua_custom_types.cpp new file mode 100644 index 00000000..4571f32a --- /dev/null +++ b/src/logic/scripting/lua/lua_custom_types.cpp @@ -0,0 +1,86 @@ +#include "lua_custom_types.hpp" + +#include "lua_util.hpp" + +#include + +using namespace lua; + + +Bytearray::Bytearray(size_t capacity) + : buffer(std::make_unique(capacity)), capacity(capacity) { +} + +Bytearray::~Bytearray() { +} + +static int l_bytearray_meta_meta_call(lua::State* L) { + auto size = tointeger(L, 2); + if (size < 0) { + throw std::runtime_error("size can not be less than 0"); + } + return newuserdata(L, static_cast(size)); +} + +static int l_bytearray_meta_index(lua::State* L) { + auto buffer = touserdata(L, 1); + auto index = tointeger(L, 2)-1; + if (buffer == nullptr || static_cast(index) > buffer->size()) { + return 0; + } + return pushinteger(L, (*buffer)[index]); +} + +static int l_bytearray_meta_newindex(lua::State* L) { + auto buffer = touserdata(L, 1); + auto index = tointeger(L, 2)-1; + if (buffer == nullptr || static_cast(index) > buffer->size()) { + return 0; + } + auto value = tointeger(L, 3); + (*buffer)[index] = static_cast(value); + return 0; +} + +static int l_bytearray_meta_len(lua::State* L) { + if (auto buffer = touserdata(L, 1)) { + return pushinteger(L, buffer->size()); + } + return 0; +} + +static int l_bytearray_meta_tostring(lua::State* L) { + auto& buffer = *touserdata(L, 1); + if (buffer.size() > 128) { + return pushstring(L, "bytearray["+std::to_string(buffer.size())+"]{...}"); + } else { + std::stringstream ss; + ss << "bytearray[" << std::to_string(buffer.size()) << "]{"; + for (size_t i = 0; i < buffer.size(); i++) { + if (i > 0) { + ss << " "; + } + ss << static_cast(buffer[i]); + } + ss << "}"; + return pushstring(L, ss.str()); + } +} + +int Bytearray::createMetatable(lua::State* L) { + createtable(L, 0, 5); + pushcfunction(L, lua::wrap); + setfield(L, "__index"); + pushcfunction(L, lua::wrap); + setfield(L, "__newindex"); + pushcfunction(L, lua::wrap); + setfield(L, "__len"); + pushcfunction(L, lua::wrap); + setfield(L, "__tostring"); + + createtable(L, 0, 1); + pushcfunction(L, lua::wrap); + setfield(L, "__call"); + setmetatable(L); + return 1; +} diff --git a/src/logic/scripting/lua/lua_custom_types.hpp b/src/logic/scripting/lua/lua_custom_types.hpp new file mode 100644 index 00000000..e095e8a3 --- /dev/null +++ b/src/logic/scripting/lua/lua_custom_types.hpp @@ -0,0 +1,39 @@ +#ifndef LOGIC_SCRIPTING_LUA_LUA_CUSTOM_TYPES_HPP_ +#define LOGIC_SCRIPTING_LUA_LUA_CUSTOM_TYPES_HPP_ + +#include "lua_commons.hpp" + +#include +#include + +namespace lua { + class Userdata { + public: + virtual ~Userdata() {}; + virtual const std::string& getTypeName() const = 0; + }; + + class Bytearray : public Userdata { + std::unique_ptr buffer; + size_t capacity; + public: + Bytearray(size_t capacity); + virtual ~Bytearray(); + + inline ubyte& operator[](size_t index) { + return buffer[index]; + } + + const std::string& getTypeName() const override { + return TYPENAME; + } + + inline size_t size() const { + return capacity; + } + static int createMetatable(lua::State*); + inline static std::string TYPENAME = "bytearray"; + }; +} + +#endif // LOGIC_SCRIPTING_LUA_LUA_CUSTOM_TYPES_HPP_ diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index 096109df..75ef541f 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -1,6 +1,7 @@ #include "lua_engine.hpp" #include "api_lua.hpp" +#include "lua_custom_types.hpp" #include "../../../debug/Logger.hpp" #include "../../../util/stringutil.hpp" @@ -45,7 +46,6 @@ static void create_libs(lua::State* L) { addfunc(L, "print", lua::wrap); } -#include void lua::initialize() { logger.info() << LUA_VERSION; logger.info() << LUAJIT_VERSION; @@ -81,6 +81,8 @@ void lua::initialize() { createtable(L, 0, 0); setglobal(L, LAMBDAS_TABLE); + + newusertype(L, "bytearray"); } void lua::finalize() { diff --git a/src/logic/scripting/lua/lua_util.cpp b/src/logic/scripting/lua/lua_util.cpp index 198ba280..745889d2 100644 --- a/src/logic/scripting/lua/lua_util.cpp +++ b/src/logic/scripting/lua/lua_util.cpp @@ -9,6 +9,15 @@ using namespace lua; static int nextEnvironment = 1; +std::unordered_map lua::usertypeNames; + +int lua::userdata_destructor(lua::State* L) { + if (auto obj = touserdata(L, 1)) { + obj->~Userdata(); + } + return 0; +} + std::string lua::env_name(int env) { return "_ENV"+util::mangleid(env); } diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index 3c705eb3..a51d784c 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -2,9 +2,16 @@ #define LOGIC_SCRIPTING_LUA_UTIL_HPP_ #include "lua_commons.hpp" +#include "lua_custom_types.hpp" + +#include +#include +#include namespace lua { inline std::string LAMBDAS_TABLE = "$L"; + extern std::unordered_map usertypeNames; + int userdata_destructor(lua::State* L); std::string env_name(int env); @@ -230,6 +237,12 @@ namespace lua { inline bool isfunction(lua::State* L, int idx) { return lua_isfunction(L, idx); } + inline bool isuserdata(lua::State* L, int idx) { + return lua_isuserdata(L, idx); + } + inline void setfield(lua::State* L, const std::string& name, int idx=-2) { + lua_setfield(L, idx, name.c_str()); + } inline bool toboolean(lua::State* L, int idx) { return lua_toboolean(L, idx); } @@ -245,7 +258,42 @@ namespace lua { inline const void* topointer(lua::State* L, int idx) { return lua_topointer(L, idx); } - inline glm::vec2 tovec2(lua::State* L, int idx) { + inline void setglobal(lua::State* L, const std::string& name) { + lua_setglobal(L, name.c_str()); + } + template + inline T* touserdata(lua::State* L, int idx) { + if (void* rawptr = lua_touserdata(L, idx)) { + return static_cast(rawptr); + } + return nullptr; + } + template + inline int newuserdata(lua::State* L, Args&&... args) { + const auto& found = usertypeNames.find(typeid(T)); + void* ptr = lua_newuserdata(L, sizeof(T)); + new (ptr) T(args...); + + if (found == usertypeNames.end()) { + log_error("usertype is not registred: "+std::string(typeid(T).name())); + } else if (getglobal(L, found->second)) { + setmetatable(L); + } + return 1; + } + + template + inline void newusertype(lua::State* L, const std::string& name) { + usertypeNames[typeid(T)] = name; + func(L); + + pushcfunction(L, userdata_destructor); + setfield(L, "__gc"); + + setglobal(L, name); + } + + inline glm::vec2 tovec2(lua::State* L, int idx) { pushvalue(L, idx); if (!istable(L, idx) || objlen(L, idx) < 2) { throw std::runtime_error("value must be an array of two numbers"); @@ -287,14 +335,6 @@ namespace lua { return true; } - inline void setfield(lua::State* L, const std::string& name, int idx=-2) { - lua_setfield(L, idx, name.c_str()); - } - - inline void setglobal(lua::State* L, const std::string& name) { - lua_setglobal(L, name.c_str()); - } - inline const char* require_string(lua::State* L, int idx) { if (!isstring(L, idx)) { throw luaerror("string expected at "+std::to_string(idx)); From 22328a9f64c2a6198e44434885645969e2159b95 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 16 Jun 2024 20:40:59 +0300 Subject: [PATCH 2/7] update Bytearray to vector use --- src/logic/scripting/lua/lua_custom_types.cpp | 6 +++++- src/logic/scripting/lua/lua_custom_types.hpp | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/logic/scripting/lua/lua_custom_types.cpp b/src/logic/scripting/lua/lua_custom_types.cpp index 4571f32a..91d44745 100644 --- a/src/logic/scripting/lua/lua_custom_types.cpp +++ b/src/logic/scripting/lua/lua_custom_types.cpp @@ -8,7 +8,11 @@ using namespace lua; Bytearray::Bytearray(size_t capacity) - : buffer(std::make_unique(capacity)), capacity(capacity) { + : buffer(capacity) { + buffer.resize(capacity); +} + +Bytearray::Bytearray(std::vector buffer) : buffer(std::move(buffer)) { } Bytearray::~Bytearray() { diff --git a/src/logic/scripting/lua/lua_custom_types.hpp b/src/logic/scripting/lua/lua_custom_types.hpp index e095e8a3..4ea4960d 100644 --- a/src/logic/scripting/lua/lua_custom_types.hpp +++ b/src/logic/scripting/lua/lua_custom_types.hpp @@ -4,7 +4,7 @@ #include "lua_commons.hpp" #include -#include +#include namespace lua { class Userdata { @@ -14,10 +14,10 @@ namespace lua { }; class Bytearray : public Userdata { - std::unique_ptr buffer; - size_t capacity; + std::vector buffer; public: Bytearray(size_t capacity); + Bytearray(std::vector buffer); virtual ~Bytearray(); inline ubyte& operator[](size_t index) { @@ -29,7 +29,7 @@ namespace lua { } inline size_t size() const { - return capacity; + return buffer.size(); } static int createMetatable(lua::State*); inline static std::string TYPENAME = "bytearray"; From 20ef11e5a2dce1fe78739c39675c730030ee040b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 16 Jun 2024 21:00:50 +0300 Subject: [PATCH 3/7] add bytearray:append(b) --- src/files/files.cpp | 15 +++++++++++++++ src/files/files.hpp | 1 + src/logic/scripting/lua/libfile.cpp | 14 ++------------ src/logic/scripting/lua/lua_custom_types.cpp | 16 +++++++++++++++- src/logic/scripting/lua/lua_custom_types.hpp | 5 +++++ src/logic/scripting/lua/lua_util.hpp | 4 ++++ 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/files/files.cpp b/src/files/files.cpp index 644e8716..8b66fa55 100644 --- a/src/files/files.cpp +++ b/src/files/files.cpp @@ -78,6 +78,21 @@ std::unique_ptr files::read_bytes(const fs::path& filename, size_t& len return data; } +std::vector files::read_bytes(const fs::path& filename) { + std::ifstream input(filename, std::ios::binary); + if (!input.is_open()) + return {}; + input.seekg(0, std::ios_base::end); + size_t length = input.tellg(); + input.seekg(0, std::ios_base::beg); + + std::vector data(length); + data.resize(length); + input.read((char*)data.data(), length); + input.close(); + return data; +} + std::string files::read_string(const fs::path& filename) { size_t size; std::unique_ptr bytes (read_bytes(filename, size)); diff --git a/src/files/files.hpp b/src/files/files.hpp index 4e6ad960..1a124b25 100644 --- a/src/files/files.hpp +++ b/src/files/files.hpp @@ -57,6 +57,7 @@ namespace files { bool read(const fs::path&, char* data, size_t size); std::unique_ptr read_bytes(const fs::path&, size_t& length); + std::vector read_bytes(const fs::path&); std::string read_string(const fs::path& filename); /// @brief Read JSON or BJSON file diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index 87e9af7a..e3e88d17 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -109,18 +109,8 @@ static int l_file_mkdirs(lua::State* L) { static int l_file_read_bytes(lua::State* L) { fs::path path = resolve_path(lua::require_string(L, 1)); if (fs::is_regular_file(path)) { - size_t length = static_cast(fs::file_size(path)); - - auto bytes = files::read_bytes(path, length); - - lua::createtable(L, length, 0); - int newTable = lua::gettop(L); - - for(size_t i = 0; i < length; i++) { - lua::pushinteger(L, bytes[i]); - lua::rawseti(L, i+1, newTable); - } - return 1; + auto bytes = files::read_bytes(path); + return lua::newuserdata(L, std::move(bytes)); } throw std::runtime_error("file does not exists "+util::quote(path.u8string())); } diff --git a/src/logic/scripting/lua/lua_custom_types.cpp b/src/logic/scripting/lua/lua_custom_types.cpp index 91d44745..e3cdc643 100644 --- a/src/logic/scripting/lua/lua_custom_types.cpp +++ b/src/logic/scripting/lua/lua_custom_types.cpp @@ -18,6 +18,14 @@ Bytearray::Bytearray(std::vector buffer) : buffer(std::move(buffer)) { Bytearray::~Bytearray() { } +static int l_bytearray_append(lua::State* L) { + if (auto buffer = touserdata(L, 1)) { + auto value = tointeger(L, 2); + buffer->append(static_cast(value)); + } + return 0; +} + static int l_bytearray_meta_meta_call(lua::State* L) { auto size = tointeger(L, 2); if (size < 0) { @@ -28,6 +36,12 @@ static int l_bytearray_meta_meta_call(lua::State* L) { static int l_bytearray_meta_index(lua::State* L) { auto buffer = touserdata(L, 1); + if (isstring(L, 2)) { + std::string member = tostring(L, 2); + if (member == "append") { + return pushcfunction(L, l_bytearray_append); + } + } auto index = tointeger(L, 2)-1; if (buffer == nullptr || static_cast(index) > buffer->size()) { return 0; @@ -55,7 +69,7 @@ static int l_bytearray_meta_len(lua::State* L) { static int l_bytearray_meta_tostring(lua::State* L) { auto& buffer = *touserdata(L, 1); - if (buffer.size() > 128) { + if (buffer.size() > 512) { return pushstring(L, "bytearray["+std::to_string(buffer.size())+"]{...}"); } else { std::stringstream ss; diff --git a/src/logic/scripting/lua/lua_custom_types.hpp b/src/logic/scripting/lua/lua_custom_types.hpp index 4ea4960d..8f6d61e6 100644 --- a/src/logic/scripting/lua/lua_custom_types.hpp +++ b/src/logic/scripting/lua/lua_custom_types.hpp @@ -31,6 +31,11 @@ namespace lua { inline size_t size() const { return buffer.size(); } + + inline void append(ubyte b) { + buffer.push_back(b); + } + static int createMetatable(lua::State*); inline static std::string TYPENAME = "bytearray"; }; diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index a51d784c..af58ea11 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -49,6 +49,10 @@ namespace lua { inline const char* type_name(lua::State* L, int idx) { return lua_typename(L, idx); } + inline int rawget(lua::State* L, int idx=-2) { + lua_rawget(L, idx); + return 1; + } inline int rawgeti(lua::State* L, int n, int idx=-1) { lua_rawgeti(L, idx, n); return 1; From 19a012f9c6c09ebb2bff19d9e9806263dd450e4b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 16 Jun 2024 21:19:49 +0300 Subject: [PATCH 4/7] add bytearray.remove, .insert and constructor using array --- src/logic/scripting/lua/lua_custom_types.cpp | 88 ++++++++++++++++---- src/logic/scripting/lua/lua_custom_types.hpp | 15 +--- 2 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/logic/scripting/lua/lua_custom_types.cpp b/src/logic/scripting/lua/lua_custom_types.cpp index e3cdc643..f1e87dd1 100644 --- a/src/logic/scripting/lua/lua_custom_types.cpp +++ b/src/logic/scripting/lua/lua_custom_types.cpp @@ -21,12 +21,58 @@ Bytearray::~Bytearray() { static int l_bytearray_append(lua::State* L) { if (auto buffer = touserdata(L, 1)) { auto value = tointeger(L, 2); - buffer->append(static_cast(value)); + buffer->data().push_back(static_cast(value)); } return 0; } +static int l_bytearray_insert(lua::State* L) { + auto buffer = touserdata(L, 1); + if (buffer == nullptr) { + return 0; + } + auto& data = buffer->data(); + auto index = tointeger(L, 2)-1; + if (static_cast(index) > data.size()) { + return 0; + } + auto value = tointeger(L, 3); + data.insert(data.begin() + index, static_cast(value)); + return 0; +} + +static int l_bytearray_remove(lua::State* L) { + auto buffer = touserdata(L, 1); + if (buffer == nullptr) { + return 0; + } + auto& data = buffer->data(); + auto index = tointeger(L, 2)-1; + if (static_cast(index) > data.size()) { + return 0; + } + data.erase(data.begin()+index); + return 0; +} + +static std::unordered_map bytearray_methods { + {"append", lua::wrap}, + {"insert", lua::wrap}, + {"remove", lua::wrap}, +}; + static int l_bytearray_meta_meta_call(lua::State* L) { + if (lua_istable(L, 2)) { + size_t len = objlen(L, 2); + std::vector buffer(len); + buffer.resize(len); + for (size_t i = 0; i < len; i++) { + rawgeti(L, i+1); + buffer[i] = static_cast(tointeger(L, -1)); + pop(L); + } + return newuserdata(L, std::move(buffer)); + } auto size = tointeger(L, 2); if (size < 0) { throw std::runtime_error("size can not be less than 0"); @@ -36,49 +82,61 @@ static int l_bytearray_meta_meta_call(lua::State* L) { static int l_bytearray_meta_index(lua::State* L) { auto buffer = touserdata(L, 1); + if (buffer == nullptr) { + return 0; + } + auto& data = buffer->data(); if (isstring(L, 2)) { - std::string member = tostring(L, 2); - if (member == "append") { - return pushcfunction(L, l_bytearray_append); + auto found = bytearray_methods.find(tostring(L, 2)); + if (found != bytearray_methods.end()) { + return pushcfunction(L, found->second); } } auto index = tointeger(L, 2)-1; - if (buffer == nullptr || static_cast(index) > buffer->size()) { + if (static_cast(index) > data.size()) { return 0; } - return pushinteger(L, (*buffer)[index]); + return pushinteger(L, data[index]); } static int l_bytearray_meta_newindex(lua::State* L) { auto buffer = touserdata(L, 1); + if (buffer == nullptr) { + return 0; + } + auto& data = buffer->data(); auto index = tointeger(L, 2)-1; - if (buffer == nullptr || static_cast(index) > buffer->size()) { + if (static_cast(index) > data.size()) { return 0; } auto value = tointeger(L, 3); - (*buffer)[index] = static_cast(value); + data[index] = static_cast(value); return 0; } static int l_bytearray_meta_len(lua::State* L) { if (auto buffer = touserdata(L, 1)) { - return pushinteger(L, buffer->size()); + return pushinteger(L, buffer->data().size()); } return 0; } static int l_bytearray_meta_tostring(lua::State* L) { - auto& buffer = *touserdata(L, 1); - if (buffer.size() > 512) { - return pushstring(L, "bytearray["+std::to_string(buffer.size())+"]{...}"); + auto buffer = touserdata(L, 1); + if (buffer == nullptr) { + return 0; + } + auto& data = buffer->data(); + if (data.size() > 512) { + return pushstring(L, "bytearray["+std::to_string(data.size())+"]{...}"); } else { std::stringstream ss; - ss << "bytearray[" << std::to_string(buffer.size()) << "]{"; - for (size_t i = 0; i < buffer.size(); i++) { + ss << "bytearray[" << std::to_string(data.size()) << "]{"; + for (size_t i = 0; i < data.size(); i++) { if (i > 0) { ss << " "; } - ss << static_cast(buffer[i]); + ss << static_cast(data[i]); } ss << "}"; return pushstring(L, ss.str()); diff --git a/src/logic/scripting/lua/lua_custom_types.hpp b/src/logic/scripting/lua/lua_custom_types.hpp index 8f6d61e6..c69bd2b0 100644 --- a/src/logic/scripting/lua/lua_custom_types.hpp +++ b/src/logic/scripting/lua/lua_custom_types.hpp @@ -19,21 +19,12 @@ namespace lua { Bytearray(size_t capacity); Bytearray(std::vector buffer); virtual ~Bytearray(); - - inline ubyte& operator[](size_t index) { - return buffer[index]; - } - + const std::string& getTypeName() const override { return TYPENAME; } - - inline size_t size() const { - return buffer.size(); - } - - inline void append(ubyte b) { - buffer.push_back(b); + inline std::vector& data() { + return buffer; } static int createMetatable(lua::State*); From 487189f4a6e97fa55c38fe9b62c65f27a331ccfe Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 16 Jun 2024 21:35:40 +0300 Subject: [PATCH 5/7] add bytearrays concatenation support --- src/logic/scripting/lua/lua_custom_types.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/logic/scripting/lua/lua_custom_types.cpp b/src/logic/scripting/lua/lua_custom_types.cpp index f1e87dd1..03162449 100644 --- a/src/logic/scripting/lua/lua_custom_types.cpp +++ b/src/logic/scripting/lua/lua_custom_types.cpp @@ -143,8 +143,24 @@ static int l_bytearray_meta_tostring(lua::State* L) { } } +static int l_bytearray_meta_add(lua::State* L) { + auto bufferA = touserdata(L, 1); + auto bufferB = touserdata(L, 2); + if (bufferA == nullptr || bufferB == nullptr) { + return 0; + } + auto& dataA = bufferA->data(); + auto& dataB = bufferB->data(); + + std::vector ab; + ab.reserve(dataA.size() + dataB.size()); + ab.insert(ab.end(), dataA.begin(), dataA.end()); + ab.insert(ab.end(), dataB.begin(), dataB.end()); + return newuserdata(L, std::move(ab)); +} + int Bytearray::createMetatable(lua::State* L) { - createtable(L, 0, 5); + createtable(L, 0, 6); pushcfunction(L, lua::wrap); setfield(L, "__index"); pushcfunction(L, lua::wrap); @@ -153,6 +169,8 @@ int Bytearray::createMetatable(lua::State* L) { setfield(L, "__len"); pushcfunction(L, lua::wrap); setfield(L, "__tostring"); + pushcfunction(L, lua::wrap); + setfield(L, "__add"); createtable(L, 0, 1); pushcfunction(L, lua::wrap); From 6bf23e5cac1e02a0d66771869a1e54b40c883cb7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 16 Jun 2024 22:07:42 +0300 Subject: [PATCH 6/7] add bytearray lua-style appending support --- src/logic/scripting/lua/lua_custom_types.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/logic/scripting/lua/lua_custom_types.cpp b/src/logic/scripting/lua/lua_custom_types.cpp index 03162449..2983e1b1 100644 --- a/src/logic/scripting/lua/lua_custom_types.cpp +++ b/src/logic/scripting/lua/lua_custom_types.cpp @@ -105,11 +105,14 @@ static int l_bytearray_meta_newindex(lua::State* L) { return 0; } auto& data = buffer->data(); - auto index = tointeger(L, 2)-1; - if (static_cast(index) > data.size()) { + auto index = static_cast(tointeger(L, 2)-1); + auto value = tointeger(L, 3); + if (index >= data.size()) { + if (index == data.size()) { + data.push_back(static_cast(value)); + } return 0; } - auto value = tointeger(L, 3); data[index] = static_cast(value); return 0; } From bfdd92ca5127090e6a4cbd0ee1a97669dff01d02 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 16 Jun 2024 22:55:56 +0300 Subject: [PATCH 7/7] update file.write_bytes to support bytearray + bit_converter bytearray support --- res/modules/bit_converter.lua | 10 +++++----- src/logic/scripting/lua/libfile.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/res/modules/bit_converter.lua b/res/modules/bit_converter.lua index 2686c2c2..86afa334 100644 --- a/res/modules/bit_converter.lua +++ b/res/modules/bit_converter.lua @@ -68,19 +68,19 @@ local function floatOrDoubleToBytes(val, opt) if opt == 'd' then val = mantissa for i = 1, 6 do - table.insert(bytes, math.floor(val) % (2 ^ 8)) + bytes[#bytes + 1] = math.floor(val) % (2 ^ 8) val = math.floor(val / (2 ^ 8)) end else - table.insert(bytes, math.floor(mantissa) % (2 ^ 8)) + bytes[#bytes + 1] = math.floor(mantissa) % (2 ^ 8) val = math.floor(mantissa / (2 ^ 8)) - table.insert(bytes, math.floor(val) % (2 ^ 8)) + bytes[#bytes + 1] = math.floor(val) % (2 ^ 8) val = math.floor(val / (2 ^ 8)) end - table.insert(bytes, math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8)) + bytes[#bytes + 1] = math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8) val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8)) - table.insert(bytes, math.floor(sign * 128 + val) % (2 ^ 8)) + bytes[#bytes + 1] = math.floor(sign * 128 + val) % (2 ^ 8) val = math.floor((sign * 128 + val) / (2 ^ 8)) if not endianness then diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index e3e88d17..3a00e0dd 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -141,10 +141,13 @@ static int l_file_write_bytes(lua::State* L) { fs::path path = resolve_path(lua::require_string(L, pathIndex)); + if (auto bytearray = lua::touserdata(L, -1)) { + auto& bytes = bytearray->data(); + return lua::pushboolean(L, files::write_bytes(path, bytes.data(), bytes.size())); + } + std::vector bytes; - int result = read_bytes_from_table(L, -1, bytes); - if(result != 1) { return result; } else {