From 29f5373d81853a1ac1397d0e07484978fa117100 Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Wed, 22 Jul 2026 20:36:01 +1000 Subject: [PATCH 01/23] added bytearray view wrapper for float (float32) --- res/modules/internal/bytearray.lua | 2 ++ res/scripts/stdmin.lua | 1 + 2 files changed, 3 insertions(+) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 58b33a520..a90595979 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -305,6 +305,7 @@ local FFII16view = create_FFIview_class("FFII16view", "int16_t", 2) local FFIU16view = create_FFIview_class("FFIU16view", "uint16_t", 2) local FFII32view = create_FFIview_class("FFII32view", "int32_t", 4) local FFIU32view = create_FFIview_class("FFIU32view", "uint32_t", 4) +local FFIF32view = create_FFIview_class("FFIF32view", "float", 4) return { FFIBytearray = setmetatable(FFIBytearray, FFIBytearray), @@ -314,4 +315,5 @@ return { FFII16view = FFII16view, FFIU32view = FFIU32view, FFII32view = FFII32view, + FFIF32view = FFIF32view, } diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 2868dd634..01b61efc6 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -314,6 +314,7 @@ U16view = bytearray.FFIU16view I16view = bytearray.FFII16view U32view = bytearray.FFIU32view I32view = bytearray.FFII32view +F32view = bytearray.FFIF32view Bytearray_construct = function(...) return Bytearray(...) end bit.compile = require "core:bitwise/compiler" From 27bb3015e4793e21f27a40476b832ab0548a2eb7 Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Thu, 23 Jul 2026 17:08:32 +1000 Subject: [PATCH 02/23] improved bytearray --- res/modules/internal/bytearray.lua | 102 ++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 32 deletions(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index a90595979..f7cab06d9 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -4,6 +4,7 @@ local FFI = ffi FFI.cdef[[ void* malloc(size_t); + void *realloc(void *, size_t); void free(void*); typedef struct { unsigned char* bytes; @@ -22,12 +23,33 @@ local GC_THRESHOLD = 50 * 1024 * 1024 local function malloc(size) local raw = FFI.C.malloc(size) - if raw == nil then - return nil + if not raw then + error("failed memory allocation of " .. size .. " bytes") end allocated_bytes = allocated_bytes + size + if allocated_bytes >= GC_THRESHOLD then + collectgarbage("step", 200) + allocated_bytes = 0 + end + return raw +end + +local function realloc(buff, size, throwerror) + if throwerror == nil then throwerror = true end + + if size <= 0 then + free(buff) + return + end + + local raw = FFI.C.realloc(buff, size) + if not raw and throwerror then + error("failed memory reallocation of block " .. buff .. " to new size " .. size) + end + + allocated_bytes = allocated_bytes + size if allocated_bytes >= GC_THRESHOLD then collectgarbage("step", 200) allocated_bytes = 0 @@ -38,23 +60,17 @@ end local function grow_buffer(self, elems) local new_capacity = math.ceil(self.capacity / 0.75 + elems) - local prev = self.bytes - self.bytes = malloc(new_capacity) - FFI.copy(self.bytes, prev, self.size) + self.bytes = realloc(self.bytes, new_capacity) self.capacity = new_capacity - free(prev) end local function trim_buffer(self) - if self.size == self.capacity then - return + if self.size == self.capacity then return end + local new_bytes = realloc(self.bytes, self.size, false) + if new_bytes then + self.bytes = new_bytes + self.capacity = self.size end - local size = self.size - local prev = self.bytes - self.bytes = malloc(size) - FFI.copy(self.bytes, prev, self.size) - self.capacity = size - free(prev) end local function count_elements(b) @@ -125,15 +141,16 @@ local function clear(self) self.size = 0 end -local function reserve(self, new_capacity) - if new_capacity <= self.capacity then - return +local function fill(self, byte) + if self.size > 0 then + FFI.fill(self.bytes, self.size, byte) end - local prev = self.bytes - self.bytes = malloc(new_capacity) - FFI.copy(self.bytes, prev, self.size) +end + +local function reserve(self, new_capacity) + if new_capacity <= self.capacity then return end + self.bytes = realloc(self.bytes, new_capacity) self.capacity = new_capacity - free(prev) end local function get_capacity(self) @@ -150,22 +167,43 @@ local function slice(self, offset, length) length = self.size - offset + 1 end local buffer = malloc(length) - if not buffer then - error("malloc(" .. length .. ") returned NULL") - end FFI.copy(buffer, self.bytes + (offset - 1), length) return bytearray_type(buffer, length, length) end +local function copy(self, srcindex, dst, dstindex, size) + if srcindex > 0 and dstindex > 0 and size > 0 and + srcindex + size - 1 <= self.size and + dstindex + size - 1 <= dst.size + then + FFI.copy(dst.bytes + dstindex - 1, self.bytes + srcindex - 1, size) + end +end + +local function move(self, fromindex, toindex, size) + if fromindex > 0 and toindex > 0 and size > 0 and + fromindex + size - 1 <= self.size and + toindex + size - 1 <= self.size + then + local buff = malloc(size) + FFI.copy(buff, self.bytes + fromindex - 1, size) + FFI.copy(self.bytes + toindex - 1, buff, size) + free(buff) + end +end + local bytearray_methods = { - append=append, - insert=insert, - remove=remove, - trim=trim_buffer, - clear=clear, - reserve=reserve, - get_capacity=get_capacity, - slice=slice, + append = append, + insert = insert, + remove = remove, + trim = trim_buffer, + clear = clear, + reserve = reserve, + get_capacity = get_capacity, + slice = slice, + fill = fill, + copy = copy, + move = move } local bytearray_mt = { From 0d641fa82fe3f16773a9cf643f38b12b32ee3caa Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Thu, 23 Jul 2026 17:47:32 +1000 Subject: [PATCH 03/23] (i hope that correctry) optimized bytearray:move method --- res/modules/internal/bytearray.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index f7cab06d9..04212d3e1 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -185,10 +185,15 @@ local function move(self, fromindex, toindex, size) fromindex + size - 1 <= self.size and toindex + size - 1 <= self.size then - local buff = malloc(size) - FFI.copy(buff, self.bytes + fromindex - 1, size) - FFI.copy(self.bytes + toindex - 1, buff, size) - free(buff) + if toindex >= fromindex and toindex < fromindex + size then + local buff = malloc(size) + FFI.copy(buff, self.bytes + fromindex - 1, size) + FFI.copy(self.bytes + toindex - 1, buff, size) + free(buff) + else + -- убери(-те) это ветвление, если FFI будет производить копирование не побайтово, и оставь(-те) только верхний блок без условия вообще. + FFI.copy(self.bytes + toindex - 1, self.bytes + fromindex - 1, size) + end end end From 67da57d8708375b05865b714db8e1e560b6546c3 Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Thu, 23 Jul 2026 19:29:19 +1000 Subject: [PATCH 04/23] upgraded/improved LuaCanvas::clear method --- .../scripting/lua/usertypes/lua_type_canvas.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/logic/scripting/lua/usertypes/lua_type_canvas.cpp b/src/logic/scripting/lua/usertypes/lua_type_canvas.cpp index c670e23df..d03b4e855 100644 --- a/src/logic/scripting/lua/usertypes/lua_type_canvas.cpp +++ b/src/logic/scripting/lua/usertypes/lua_type_canvas.cpp @@ -161,18 +161,11 @@ static LuaCanvas& require_canvas(State* L, int idx) { static int l_clear(State* L) { auto& canvas = require_canvas(L, 1); auto& image = canvas.getData(); - ubyte* data = image.getData(); - RGBA rgba {}; - if (gettop(L) == 1) { - std::fill(data, data + image.getDataSize(), 0); - return 0; - } - rgba = get_rgba(L, 2); - size_t pixels = image.getWidth() * image.getHeight(); - const size_t channels = 4; - for (size_t i = 0; i < pixels * channels; i++) { - data[i] = rgba.arr[i % channels]; - } + size_t pixelscount = image.getWidth() * image.getHeight(); + uint32_t* data = reinterpret_cast(image.getData()); + + if (gettop(L) == 1) std::fill(data, data + pixelscount, 0); + else std::fill(data, data + pixelscount, get_rgba(L, 2).rgba); return 0; } From f8a44c023f563f2adc511356a1e7865a20b9ab7b Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Mon, 3 Aug 2026 18:25:44 +1000 Subject: [PATCH 05/23] patched code after code review from MihailRis --- res/modules/internal/bytearray.lua | 37 +++++++++---------- .../lua/usertypes/lua_type_canvas.cpp | 7 +++- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 04212d3e1..1615d1a08 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -4,13 +4,14 @@ local FFI = ffi FFI.cdef[[ void* malloc(size_t); - void *realloc(void *, size_t); + void* realloc(void*, size_t); void free(void*); typedef struct { unsigned char* bytes; int size; int capacity; } bytearray_t; + void* memmove(void*, const void*, size_t); ]] local free = FFI.C.free @@ -172,29 +173,27 @@ local function slice(self, offset, length) end local function copy(self, srcindex, dst, dstindex, size) - if srcindex > 0 and dstindex > 0 and size > 0 and - srcindex + size - 1 <= self.size and - dstindex + size - 1 <= dst.size - then - FFI.copy(dst.bytes + dstindex - 1, self.bytes + srcindex - 1, size) + if size <= 0 then error("size of byte range must be positive non-zero integer") end + if srcindex < 1 or srcindex + size - 1 > self.size then + error("specified source byte range is out of source array bounds") end + if dstindex < 1 or dstindex + size - 1 > dst.size then + error("specified destination byte range is out of destination array bounds") + end + + FFI.copy(dst.bytes + dstindex - 1, self.bytes + srcindex - 1, size) end local function move(self, fromindex, toindex, size) - if fromindex > 0 and toindex > 0 and size > 0 and - fromindex + size - 1 <= self.size and - toindex + size - 1 <= self.size - then - if toindex >= fromindex and toindex < fromindex + size then - local buff = malloc(size) - FFI.copy(buff, self.bytes + fromindex - 1, size) - FFI.copy(self.bytes + toindex - 1, buff, size) - free(buff) - else - -- убери(-те) это ветвление, если FFI будет производить копирование не побайтово, и оставь(-те) только верхний блок без условия вообще. - FFI.copy(self.bytes + toindex - 1, self.bytes + fromindex - 1, size) - end + if size <= 0 then error("size of byte range must be positive non-zero integer") end + if fromindex < 1 or fromindex + size - 1 > self.size then + error("specified source byte range is out of array bounds") end + if toindex < 1 or toindex + size - 1 > self.size then + error("specified destination byte range is out of array bounds") + end + + FFI.C.memmove(self.bytes + self.toindex - 1, self.bytes + self.fromindex - 1, size) end local bytearray_methods = { diff --git a/src/logic/scripting/lua/usertypes/lua_type_canvas.cpp b/src/logic/scripting/lua/usertypes/lua_type_canvas.cpp index d03b4e855..928515e74 100644 --- a/src/logic/scripting/lua/usertypes/lua_type_canvas.cpp +++ b/src/logic/scripting/lua/usertypes/lua_type_canvas.cpp @@ -164,8 +164,11 @@ static int l_clear(State* L) { size_t pixelscount = image.getWidth() * image.getHeight(); uint32_t* data = reinterpret_cast(image.getData()); - if (gettop(L) == 1) std::fill(data, data + pixelscount, 0); - else std::fill(data, data + pixelscount, get_rgba(L, 2).rgba); + if (gettop(L) == 1) { + std::fill(data, data + pixelscount, 0); + } else { + std::fill(data, data + pixelscount, get_rgba(L, 2).rgba); + } return 0; } From 3eac247a6918398e6bbf92278d615eff8836c8d6 Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Mon, 3 Aug 2026 22:09:11 +1000 Subject: [PATCH 06/23] eliminated hardcoded types sizes in bytearray-viewers declaratons and replaced on usage ffi.sizeof function --- res/modules/internal/bytearray.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 1615d1a08..d58839f15 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -298,7 +298,8 @@ local function FFIBytearray_as_string(bytes) end end -local function create_FFIview_class(name, typename, typesize) +local function create_FFIview_class(name, typename) + local typesize = FFI.sizeof(typename) local ptrtype = typename .. "*" local FFIview_mt = { __index = function(self, key) @@ -343,11 +344,11 @@ local function create_FFIview_class(name, typename, typesize) end end -local FFII16view = create_FFIview_class("FFII16view", "int16_t", 2) -local FFIU16view = create_FFIview_class("FFIU16view", "uint16_t", 2) -local FFII32view = create_FFIview_class("FFII32view", "int32_t", 4) -local FFIU32view = create_FFIview_class("FFIU32view", "uint32_t", 4) -local FFIF32view = create_FFIview_class("FFIF32view", "float", 4) +local FFII16view = create_FFIview_class("FFII16view", "int16_t") +local FFIU16view = create_FFIview_class("FFIU16view", "uint16_t") +local FFII32view = create_FFIview_class("FFII32view", "int32_t") +local FFIU32view = create_FFIview_class("FFIU32view", "uint32_t") +local FFIF32view = create_FFIview_class("FFIF32view", "float") return { FFIBytearray = setmetatable(FFIBytearray, FFIBytearray), From 2c72d33485fd38b5b69b8d9f80bb1bd53f1b720f Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Mon, 3 Aug 2026 22:45:48 +1000 Subject: [PATCH 07/23] improved Bytearray:fill method --- res/modules/internal/bytearray.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index d58839f15..586fa8e25 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -142,8 +142,13 @@ local function clear(self) self.size = 0 end -local function fill(self, byte) - if self.size > 0 then +local function fill(self, index, size, byte) + if index ~= nil and size ~= nil and size > 0 then + if index < 1 or index + size - 1 > self.size then + error("selected fill range is out of array bounds") + end + FFI.fill(self.bytes + index - 1, size, byte) + else FFI.fill(self.bytes, self.size, byte) end end From 5a0f63061ffc866052fa7f0d0bd190987ab447ed Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Mon, 3 Aug 2026 23:41:57 +1000 Subject: [PATCH 08/23] added & upgraded Russian docs for new bytearray functions, new bytearray views (viewers) and other features --- doc/ru/scripting/bytearray.md | 37 ++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/doc/ru/scripting/bytearray.md b/doc/ru/scripting/bytearray.md index c90b6d67e..138eed347 100644 --- a/doc/ru/scripting/bytearray.md +++ b/doc/ru/scripting/bytearray.md @@ -22,11 +22,31 @@ bytes:insert(index: int, value: int) -- Удаляет элемент(ы), если передан `count`, удалит `count` кол-во элементов с выбранного индекса. bytes:remove(index: int, [опционально] count: int) --- Очищает массив +-- Очищает массив. bytes:clear() +--[[ +Заполняет массив определённым байтом полностью либо в определённом диапазоне. +Логика работы следующая: если параметр size или index равны nil, то указанным байтом будет заполнен весь массив, + иначе будет заполнен диапазон внутри массива начиная с индекса index и размером size. +В случае выхода заполняемого блока за границы массива генерирует соответствующую ошибку. +]] +bytes:fill(index: posint/nil, size: posint/nil, byte: uint8) + -- Создаёт новый Bytearray, содержащий копию части данных с offset до offset+length bytes:slice(offset: int, length: int) -> Bytearray + +--[[ +Копирует блок байт из исходного массива, начиная с индекса srcindex, в массив dst, начиная в нём с индекса dstindex. +В случае выхода за границы исходного, конечного массива, либо при некорректном значении параметра size генерирует соответствующую ошибку. +]] +bytes:copy(srcindex: posint, dst: Bytearray, dstindex: posint, size: posint) + +--[[ +Безопасно копирует перекрывающиеся области памяти (байт) в пределах одного массива. +В случае выхода за пределы массива начального или конечного диапазона байт генерирует соответствующую ошибку. +]] +bytes:move(fromindex: posint, toindex: posint, size: posint) ``` ## View @@ -35,12 +55,15 @@ bytes:slice(offset: int, length: int) -> Bytearray Не имеет своих методов, является просто объектной ссылкой на оригинальный Bytearray. -| Класс | Тип элементов | Размер | -| ------------ | ------------------ | ------- | -| `I16view` | `int16_t` | 2 байта | -| `U16view` | `uint16_t` | 2 байта | -| `I32view` | `int32_t` | 4 байта | -| `U32view` | `uint32_t` | 4 байта | +| Класс | Тип элементов | Размер* | +| ------------ | ------------------ | -------- | +| `I16view` | `int16_t` | 2 байта | +| `U16view` | `uint16_t` | 2 байта | +| `I32view` | `int32_t` | 4 байта | +| `U32view` | `uint32_t` | 4 байта | +| `F32view` | `float` | 4 байта | + +* Размеры C-шных типов являются платформозависимыми. В данной таблице предоставлены наиболее распространённые размеры типов. --- From b30207917fb614c941bf8c7b8675fb16f9dc4fb3 Mon Sep 17 00:00:00 2001 From: RomanDonw <126128023+RomanDonw@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:59:28 +1000 Subject: [PATCH 09/23] made Russian docs more exact --- doc/ru/scripting/bytearray.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/ru/scripting/bytearray.md b/doc/ru/scripting/bytearray.md index 138eed347..50ec15d9d 100644 --- a/doc/ru/scripting/bytearray.md +++ b/doc/ru/scripting/bytearray.md @@ -55,15 +55,15 @@ bytes:move(fromindex: posint, toindex: posint, size: posint) Не имеет своих методов, является просто объектной ссылкой на оригинальный Bytearray. -| Класс | Тип элементов | Размер* | -| ------------ | ------------------ | -------- | -| `I16view` | `int16_t` | 2 байта | -| `U16view` | `uint16_t` | 2 байта | -| `I32view` | `int32_t` | 4 байта | -| `U32view` | `uint32_t` | 4 байта | -| `F32view` | `float` | 4 байта | +| Класс | Тип элементов | Размер | +| ------------ | ------------------ | --------- | +| `I16view` | `int16_t` | 2 байта | +| `U16view` | `uint16_t` | 2 байта | +| `I32view` | `int32_t` | 4 байта | +| `U32view` | `uint32_t` | 4 байта | +| `F32view` | `float` | 4 байта* | -* Размеры C-шных типов являются платформозависимыми. В данной таблице предоставлены наиболее распространённые размеры типов. +* Размеры "оригинальных" C-шных типов являются платформозависимыми и их точный размер не описан в стандарте языка. В данной таблице предоставлены наиболее распространённые размеры типов. --- @@ -82,4 +82,4 @@ print(i16[3]) -- -6 (signed вьюшка) for _, num in ipairs(i16) do print(num) end -- 1; 2; -6 -``` \ No newline at end of file +``` From e0afe5c6499f7b24e3bad0b03efc7060b0e862ee Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Tue, 4 Aug 2026 17:18:58 +1000 Subject: [PATCH 10/23] added typesize method for bytearray views (viewers) (both to Lua and docs (only Russian for now)) --- doc/ru/scripting/bytearray.md | 7 +++++++ res/modules/internal/bytearray.lua | 3 +++ 2 files changed, 10 insertions(+) diff --git a/doc/ru/scripting/bytearray.md b/doc/ru/scripting/bytearray.md index 50ec15d9d..b16b3fd39 100644 --- a/doc/ru/scripting/bytearray.md +++ b/doc/ru/scripting/bytearray.md @@ -65,6 +65,13 @@ bytes:move(fromindex: posint, toindex: posint, size: posint) * Размеры "оригинальных" C-шных типов являются платформозависимыми и их точный размер не описан в стандарте языка. В данной таблице предоставлены наиболее распространённые размеры типов. +### Специфические методы "вьюшек" + +```lua +-- Возвращает размер типа вьюшки (полезно для вьюшек, использующих C-шные типы нефиксированного размера: те же float или double). +view:typesize() -> posint +``` + --- ### Пример использования diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 586fa8e25..556085515 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -339,6 +339,9 @@ local function create_FFIview_class(name, typename) return i, ptr[i - 1] end end + end, + typesize = function() + return typesize end } return function (bytes) From 9fc94e40b20f6f686b4113dcd7fe530f04020fba Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Tue, 4 Aug 2026 17:41:24 +1000 Subject: [PATCH 11/23] renamed bytearray F32view to FLT view & improved bytearray Russian docs --- doc/ru/scripting/bytearray.md | 9 +++++++-- res/modules/internal/bytearray.lua | 4 ++-- res/scripts/stdmin.lua | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/ru/scripting/bytearray.md b/doc/ru/scripting/bytearray.md index b16b3fd39..032182891 100644 --- a/doc/ru/scripting/bytearray.md +++ b/doc/ru/scripting/bytearray.md @@ -2,6 +2,8 @@ *Bytearray* - динамический байтовый массив, реализованный через LuaJIT FFI. По нему можно итерироваться стандартными функциями **pairs** и **ipairs** +Примечание касаемо условных обозначений в документации: псведотип `posint` означает натуральное (положительное ненулевое целое) число. + ## Основное ### Создание массива ```lua @@ -61,14 +63,17 @@ bytes:move(fromindex: posint, toindex: posint, size: posint) | `U16view` | `uint16_t` | 2 байта | | `I32view` | `int32_t` | 4 байта | | `U32view` | `uint32_t` | 4 байта | -| `F32view` | `float` | 4 байта* | +| `FLTview` | `float` | 4 байта* | * Размеры "оригинальных" C-шных типов являются платформозависимыми и их точный размер не описан в стандарте языка. В данной таблице предоставлены наиболее распространённые размеры типов. ### Специфические методы "вьюшек" ```lua --- Возвращает размер типа вьюшки (полезно для вьюшек, использующих C-шные типы нефиксированного размера: те же float или double). +--[[ +Возвращает размер типа вьюшки. Результат тот же, что и от применения оператора sizeof() из языка C для данного типа. + Полезно для вьюшек, использующих C-шные типы нефиксированного размера, например те же float или double. +]] view:typesize() -> posint ``` diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 556085515..27472f491 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -356,7 +356,7 @@ local FFII16view = create_FFIview_class("FFII16view", "int16_t") local FFIU16view = create_FFIview_class("FFIU16view", "uint16_t") local FFII32view = create_FFIview_class("FFII32view", "int32_t") local FFIU32view = create_FFIview_class("FFIU32view", "uint32_t") -local FFIF32view = create_FFIview_class("FFIF32view", "float") +local FFIFLTview = create_FFIview_class("FFIFLTview", "float") return { FFIBytearray = setmetatable(FFIBytearray, FFIBytearray), @@ -366,5 +366,5 @@ return { FFII16view = FFII16view, FFIU32view = FFIU32view, FFII32view = FFII32view, - FFIF32view = FFIF32view, + FFIFLTview = FFIFLTview, } diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 01b61efc6..a7c7bdbd2 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -314,7 +314,7 @@ U16view = bytearray.FFIU16view I16view = bytearray.FFII16view U32view = bytearray.FFIU32view I32view = bytearray.FFII32view -F32view = bytearray.FFIF32view +FLTview = bytearray.FFIFLTview Bytearray_construct = function(...) return Bytearray(...) end bit.compile = require "core:bitwise/compiler" From 457fc573492dd9ec2f9399386bd1e1070c723830 Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Tue, 4 Aug 2026 18:07:11 +1000 Subject: [PATCH 12/23] added more new views (viewers) for bytearray (again both to Lua & Russian docs) --- doc/ru/scripting/bytearray.md | 10 ++++++---- res/modules/internal/bytearray.lua | 8 ++++++++ res/scripts/stdmin.lua | 4 ++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/doc/ru/scripting/bytearray.md b/doc/ru/scripting/bytearray.md index 032182891..d15cd6a58 100644 --- a/doc/ru/scripting/bytearray.md +++ b/doc/ru/scripting/bytearray.md @@ -55,15 +55,19 @@ bytes:move(fromindex: posint, toindex: posint, size: posint) Это "вьюшки" поверх Bytearray, которые интерпретируют его байты как массив чисел другого размера - **без копирования данных**. -Не имеет своих методов, является просто объектной ссылкой на оригинальный Bytearray. +Практически не имеют своих методов, являются простыми объектными ссылками на оригинальный Bytearray. | Класс | Тип элементов | Размер | | ------------ | ------------------ | --------- | +| `I8view` | `int8_t` | 1 байт | | `I16view` | `int16_t` | 2 байта | | `U16view` | `uint16_t` | 2 байта | | `I32view` | `int32_t` | 4 байта | | `U32view` | `uint32_t` | 4 байта | +| `I64view` | `int64_t` | 8 байт | +| `U64view` | `uint64_t` | 8 байт | | `FLTview` | `float` | 4 байта* | +| `DBLview` | `double` | 8 байт* | * Размеры "оригинальных" C-шных типов являются платформозависимыми и их точный размер не описан в стандарте языка. В данной таблице предоставлены наиболее распространённые размеры типов. @@ -77,9 +81,7 @@ bytes:move(fromindex: posint, toindex: posint, size: posint) view:typesize() -> posint ``` ---- - -### Пример использования +## Пример использования ```lua local bytes = Bytearray({1, 0, 2, 0, 250, 255}) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 27472f491..42f6bddcd 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -352,19 +352,27 @@ local function create_FFIview_class(name, typename) end end +local FFII8view = create_FFIview_class("FFII8view", "int8_t") local FFII16view = create_FFIview_class("FFII16view", "int16_t") local FFIU16view = create_FFIview_class("FFIU16view", "uint16_t") local FFII32view = create_FFIview_class("FFII32view", "int32_t") local FFIU32view = create_FFIview_class("FFIU32view", "uint32_t") +local FFII64view = create_FFIview_class("FFII32view", "int64_t") +local FFIU64view = create_FFIview_class("FFIU32view", "uint64_t") local FFIFLTview = create_FFIview_class("FFIFLTview", "float") +local FFIDBLview = create_FFIview_class("FFIDBLview", "double") return { FFIBytearray = setmetatable(FFIBytearray, FFIBytearray), FFIBytearray_as_string = FFIBytearray_as_string, FFIBytearray_as_ptr = FFIBytearray_as_ptr, + FFII8view = FFII8view, FFIU16view = FFIU16view, FFII16view = FFII16view, FFIU32view = FFIU32view, FFII32view = FFII32view, + FFIU64view = FFIU64view, + FFII64view = FFII64view, FFIFLTview = FFIFLTview, + FFIDBLview = FFIDBLview, } diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index a7c7bdbd2..93bdf118e 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -310,11 +310,15 @@ local bytearray = require "core:internal/bytearray" Bytearray = bytearray.FFIBytearray Bytearray_as_string = bytearray.FFIBytearray_as_string Bytearray_as_ptr = bytearray.FFIBytearray_as_ptr +I8view = bytearray.FFII8view U16view = bytearray.FFIU16view I16view = bytearray.FFII16view U32view = bytearray.FFIU32view I32view = bytearray.FFII32view +U64view = bytearray.FFIU64view +I64view = bytearray.FFII64view FLTview = bytearray.FFIFLTview +DBLview = bytearray.FFIDBLview Bytearray_construct = function(...) return Bytearray(...) end bit.compile = require "core:bitwise/compiler" From e203b5ef4cc77fd812e5e8f0e3775064ab4cb5ab Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Tue, 4 Aug 2026 19:50:55 +1000 Subject: [PATCH 13/23] fixed two (2) typos in Bytearray:move method implementation --- res/modules/internal/bytearray.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 42f6bddcd..cfae8b53d 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -198,7 +198,7 @@ local function move(self, fromindex, toindex, size) error("specified destination byte range is out of array bounds") end - FFI.C.memmove(self.bytes + self.toindex - 1, self.bytes + self.fromindex - 1, size) + FFI.C.memmove(self.bytes + toindex - 1, self.bytes + fromindex - 1, size) end local bytearray_methods = { From 5843e5828b5e568ed271f55852eb1329e071e417 Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Tue, 4 Aug 2026 20:25:15 +1000 Subject: [PATCH 14/23] upgraded bytearray's test (added testing new bytearray functions and views/viewers) --- dev/tests/bytearray.lua | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/dev/tests/bytearray.lua b/dev/tests/bytearray.lua index 415768c65..2a3d6140b 100644 --- a/dev/tests/bytearray.lua +++ b/dev/tests/bytearray.lua @@ -34,3 +34,67 @@ arr:insert(2, {5, 6}) assert(arr[#arr] == 25) assert(arr[2] == 5) assert(arr[3] == 6) + +-- ============================= + +local arr2 = Bytearray({254, 255, 255, 255, 255, 255, 255, 255}) +--assert(U64view(arr2)[1] == 2 ^ 64 - 2) +assert(I64view(arr2)[1] == -2) +assert(U32view(arr2)[1] == 2 ^ 32 - 2) +assert(I32view(arr2)[1] == -2) +assert(U16view(arr2)[1] == 2 ^ 16 - 2) +assert(I16view(arr2)[1] == -2) +assert(I8view(arr2)[1] == -2) + +assert(I8view(arr2)[2] == -1) +assert(I32view(arr2)[2] == -1) + +local arr3 = Bytearray({0xFF, 0x7F}) +local arr3i16 = I16view(arr3) +local arr3u16 = U16view(arr3) +assert(arr3i16[1] == 32767) + +arr3u16[1] = arr3u16[1] + 1 +assert(arr3i16[1] == -32768) +assert(arr3u16[1] == 32768) + +local arr4 = Bytearray({0x9A, 0x99, 0x59, 0x40}) -- approx. equal 3.4 in hexadecimal representation of single-precision float number. +local arr4flt = FLTview(arr4) +local arr4u32 = U32view(arr4) +assert(arr4flt[1] == 3.4000000953674316) +assert(arr4u32[1] == 0x4059999A) + +arr4flt[1] = arr4flt[1] + 0.1 +assert(arr4flt[1] == 3.5) +assert(arr4u32[1] == 0x40600000) -- hexadecimal representation of 3.5 single-precision float number. + +-- ============================================= + +function barrtostr(barr) + local outstr = "" + for i = 1, #barr do + local lastfmt = "" + if i ~= #barr then lastfmt = "|" end + outstr = outstr .. barr[i] .. lastfmt + end + return outstr +end + +local arr5 = Bytearray({0, 5, 34, 87, 21, 0, 210}) +assert(barrtostr(arr5) == "0|5|34|87|21|0|210") +arr5:move(2, 3, 4) +assert(barrtostr(arr5) == "0|5|5|34|87|21|210") + +local arr6 = Bytearray({1, 2, 3, 4, 6, 7, 8}) +assert(barrtostr(arr6) == "1|2|3|4|6|7|8") +arr5:copy(4, arr6, 2, 3) +assert(barrtostr(arr6) == "1|34|87|21|6|7|8") + +arr5:fill(nil, nil, 192) +assert(barrtostr(arr5) == "192|192|192|192|192|192|192") +arr5:fill(nil, 3, 233) +assert(barrtostr(arr5) == "233|233|233|233|233|233|233") +arr5:fill(2, nil, 254) +assert(barrtostr(arr5) == "254|254|254|254|254|254|254") +arr5:fill(2, 2, 66) +assert(barrtostr(arr5) == "254|66|66|254|254|254|254") \ No newline at end of file From 074f01b1bb1fae161fd83d3f9061594af2c6ce71 Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Tue, 4 Aug 2026 22:40:59 +1000 Subject: [PATCH 15/23] upgraded bytearray test & added DBLview testing section --- dev/tests/bytearray.lua | 85 +++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/dev/tests/bytearray.lua b/dev/tests/bytearray.lua index 2a3d6140b..cbd537100 100644 --- a/dev/tests/bytearray.lua +++ b/dev/tests/bytearray.lua @@ -37,36 +37,39 @@ assert(arr[3] == 6) -- ============================= -local arr2 = Bytearray({254, 255, 255, 255, 255, 255, 255, 255}) ---assert(U64view(arr2)[1] == 2 ^ 64 - 2) -assert(I64view(arr2)[1] == -2) -assert(U32view(arr2)[1] == 2 ^ 32 - 2) -assert(I32view(arr2)[1] == -2) -assert(U16view(arr2)[1] == 2 ^ 16 - 2) -assert(I16view(arr2)[1] == -2) -assert(I8view(arr2)[1] == -2) +arr = Bytearray({254, 255, 255, 255, 255, 255, 255, 255}) +--assert(U64view(arr)[1] == 2 ^ 64 - 2) +assert(I64view(arr)[1] == -2) +assert(U32view(arr)[1] == 2 ^ 32 - 2) +assert(I32view(arr)[1] == -2) +assert(U16view(arr)[1] == 2 ^ 16 - 2) +assert(I16view(arr)[1] == -2) +assert(I8view(arr)[1] == -2) -assert(I8view(arr2)[2] == -1) -assert(I32view(arr2)[2] == -1) +assert(I8view(arr)[2] == -1) +assert(I32view(arr)[2] == -1) -local arr3 = Bytearray({0xFF, 0x7F}) -local arr3i16 = I16view(arr3) -local arr3u16 = U16view(arr3) -assert(arr3i16[1] == 32767) +arr = Bytearray({0xFF, 0x7F}) +local arri16 = I16view(arr) +local arru16 = U16view(arr) +assert(arri16[1] == 32767) -arr3u16[1] = arr3u16[1] + 1 -assert(arr3i16[1] == -32768) -assert(arr3u16[1] == 32768) +arru16[1] = arru16[1] + 1 +assert(arri16[1] == -32768) +assert(arru16[1] == 32768) -local arr4 = Bytearray({0x9A, 0x99, 0x59, 0x40}) -- approx. equal 3.4 in hexadecimal representation of single-precision float number. -local arr4flt = FLTview(arr4) -local arr4u32 = U32view(arr4) -assert(arr4flt[1] == 3.4000000953674316) -assert(arr4u32[1] == 0x4059999A) +arr = Bytearray({0x9A, 0x99, 0x59, 0x40}) -- approx. equal 3.4 in hexadecimal representation of single-precision float number. +local arrflt = FLTview(arr) +local arru32 = U32view(arr) +assert(arrflt[1] == 3.4000000953674316) +assert(arru32[1] == 0x4059999A) -arr4flt[1] = arr4flt[1] + 0.1 -assert(arr4flt[1] == 3.5) -assert(arr4u32[1] == 0x40600000) -- hexadecimal representation of 3.5 single-precision float number. +arrflt[1] = arrflt[1] + 0.1 +assert(arrflt[1] == 3.5) +assert(arru32[1] == 0x40600000) -- hexadecimal representation of 3.5 single-precision float number. + +arr = Bytearray({0x18, 0x2D, 0x44, 0x54, 0xFB, 0x21, 9, 64}) -- hexadecimal representation of 3.141592653589793 double-precision float number. +assert(DBLview(arr)[1] == 3.141592653589793) -- ============================================= @@ -80,21 +83,21 @@ function barrtostr(barr) return outstr end -local arr5 = Bytearray({0, 5, 34, 87, 21, 0, 210}) -assert(barrtostr(arr5) == "0|5|34|87|21|0|210") -arr5:move(2, 3, 4) -assert(barrtostr(arr5) == "0|5|5|34|87|21|210") +arr = Bytearray({0, 5, 34, 87, 21, 0, 210}) +assert(barrtostr(arr) == "0|5|34|87|21|0|210") +arr:move(2, 3, 4) +assert(barrtostr(arr) == "0|5|5|34|87|21|210") -local arr6 = Bytearray({1, 2, 3, 4, 6, 7, 8}) -assert(barrtostr(arr6) == "1|2|3|4|6|7|8") -arr5:copy(4, arr6, 2, 3) -assert(barrtostr(arr6) == "1|34|87|21|6|7|8") +local arr2 = Bytearray({1, 2, 3, 4, 6, 7, 8}) +assert(barrtostr(arr2) == "1|2|3|4|6|7|8") +arr:copy(4, arr2, 2, 3) +assert(barrtostr(arr2) == "1|34|87|21|6|7|8") -arr5:fill(nil, nil, 192) -assert(barrtostr(arr5) == "192|192|192|192|192|192|192") -arr5:fill(nil, 3, 233) -assert(barrtostr(arr5) == "233|233|233|233|233|233|233") -arr5:fill(2, nil, 254) -assert(barrtostr(arr5) == "254|254|254|254|254|254|254") -arr5:fill(2, 2, 66) -assert(barrtostr(arr5) == "254|66|66|254|254|254|254") \ No newline at end of file +arr:fill(nil, nil, 192) +assert(barrtostr(arr) == "192|192|192|192|192|192|192") +arr:fill(nil, 3, 233) +assert(barrtostr(arr) == "233|233|233|233|233|233|233") +arr:fill(2, nil, 254) +assert(barrtostr(arr) == "254|254|254|254|254|254|254") +arr:fill(2, 2, 66) +assert(barrtostr(arr) == "254|66|66|254|254|254|254") \ No newline at end of file From 7a88bd454a98bfc3ae8c71b4198e2f8dd16b7ca3 Mon Sep 17 00:00:00 2001 From: RomanDonw <126128023+RomanDonw@users.noreply.github.com> Date: Wed, 5 Aug 2026 00:39:21 +1000 Subject: [PATCH 16/23] fixed typo in FFIU64view & FFII64view bytearray views (viewers) declaration (bytearray.lua) --- res/modules/internal/bytearray.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index cfae8b53d..0908b8c9a 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -357,8 +357,8 @@ local FFII16view = create_FFIview_class("FFII16view", "int16_t") local FFIU16view = create_FFIview_class("FFIU16view", "uint16_t") local FFII32view = create_FFIview_class("FFII32view", "int32_t") local FFIU32view = create_FFIview_class("FFIU32view", "uint32_t") -local FFII64view = create_FFIview_class("FFII32view", "int64_t") -local FFIU64view = create_FFIview_class("FFIU32view", "uint64_t") +local FFII64view = create_FFIview_class("FFII64view", "int64_t") +local FFIU64view = create_FFIview_class("FFIU64view", "uint64_t") local FFIFLTview = create_FFIview_class("FFIFLTview", "float") local FFIDBLview = create_FFIview_class("FFIDBLview", "double") From 7f04d2884e7273f11ede01ef3f943aa139fca0c3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Aug 2026 18:54:37 +0300 Subject: [PATCH 17/23] fix view classes static typesize method --- res/modules/internal/bytearray.lua | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 0908b8c9a..896f43188 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -340,16 +340,20 @@ local function create_FFIview_class(name, typename) end end end, - typesize = function() - return typesize - end } - return function (bytes) - local x = setmetatable({ - bytes=bytes, - }, FFIview_mt) - return x - end + return setmetatable({}, { + __call = function (self, bytes) + local x = setmetatable({ + bytes=bytes, + }, FFIview_mt) + return x + end, + __index = { + typesize = function() + return typesize + end + } + }) end local FFII8view = create_FFIview_class("FFII8view", "int8_t") From 5f94e707ea9fdd53d6272b5c718b8c226222c8ee Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Aug 2026 18:55:10 +0300 Subject: [PATCH 18/23] update bytearray test --- dev/tests/bytearray.lua | 58 ++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/dev/tests/bytearray.lua b/dev/tests/bytearray.lua index cbd537100..0d1bdb6ae 100644 --- a/dev/tests/bytearray.lua +++ b/dev/tests/bytearray.lua @@ -18,55 +18,55 @@ Bytearray.insert(arr, {5, 3, 6}) assert(#arr == 12) Bytearray.insert(arr, 2, 8) -assert(#arr == 13) +asserts.equals(13, #arr) for i=1,10 do assert(arr[i] == 10 - i) end print(#arr, arr:get_capacity()) arr:trim() -assert(#arr == arr:get_capacity()) +asserts.equals(#arr, arr:get_capacity()) arr = Bytearray({0, 2, 7, 1, 16, 75, 25}) assert(arr[6] == 75) arr:insert(2, {5, 6}) -assert(arr[#arr] == 25) -assert(arr[2] == 5) -assert(arr[3] == 6) +asserts.equals(25, arr[#arr]) +asserts.equals(5, arr[2]) +asserts.equals(6, arr[3]) -- ============================= arr = Bytearray({254, 255, 255, 255, 255, 255, 255, 255}) ---assert(U64view(arr)[1] == 2 ^ 64 - 2) -assert(I64view(arr)[1] == -2) -assert(U32view(arr)[1] == 2 ^ 32 - 2) -assert(I32view(arr)[1] == -2) -assert(U16view(arr)[1] == 2 ^ 16 - 2) -assert(I16view(arr)[1] == -2) -assert(I8view(arr)[1] == -2) +-- asserts.equals(U64view(arr)[1], 2 ^ 64 - 2) +asserts.equals(I64view(arr)[1], -2) +asserts.equals(U32view(arr)[1], 2 ^ 32 - 2) +asserts.equals(I32view(arr)[1], -2) +asserts.equals(U16view(arr)[1], 2 ^ 16 - 2) +asserts.equals(I16view(arr)[1], -2) +asserts.equals(I8view(arr)[1], -2) -assert(I8view(arr)[2] == -1) -assert(I32view(arr)[2] == -1) +asserts.equals(I8view(arr)[2], -1) +asserts.equals(I32view(arr)[2], -1) arr = Bytearray({0xFF, 0x7F}) local arri16 = I16view(arr) local arru16 = U16view(arr) -assert(arri16[1] == 32767) +asserts.equals(arri16[1], 32767) arru16[1] = arru16[1] + 1 -assert(arri16[1] == -32768) -assert(arru16[1] == 32768) +asserts.equals(arri16[1], -32768) +asserts.equals(arru16[1], 32768) arr = Bytearray({0x9A, 0x99, 0x59, 0x40}) -- approx. equal 3.4 in hexadecimal representation of single-precision float number. local arrflt = FLTview(arr) local arru32 = U32view(arr) -assert(arrflt[1] == 3.4000000953674316) -assert(arru32[1] == 0x4059999A) +asserts.equals(arrflt[1], 3.4000000953674316) +asserts.equals(arru32[1], 0x4059999A) arrflt[1] = arrflt[1] + 0.1 -assert(arrflt[1] == 3.5) -assert(arru32[1] == 0x40600000) -- hexadecimal representation of 3.5 single-precision float number. +asserts.equals(arrflt[1], 3.5) +asserts.equals(arru32[1], 0x40600000) -- hexadecimal representation of 3.5 single-precision float number. arr = Bytearray({0x18, 0x2D, 0x44, 0x54, 0xFB, 0x21, 9, 64}) -- hexadecimal representation of 3.141592653589793 double-precision float number. assert(DBLview(arr)[1] == 3.141592653589793) @@ -84,20 +84,20 @@ function barrtostr(barr) end arr = Bytearray({0, 5, 34, 87, 21, 0, 210}) -assert(barrtostr(arr) == "0|5|34|87|21|0|210") +asserts.equals(barrtostr(arr), "0|5|34|87|21|0|210") arr:move(2, 3, 4) -assert(barrtostr(arr) == "0|5|5|34|87|21|210") +asserts.equals(barrtostr(arr), "0|5|5|34|87|21|210") local arr2 = Bytearray({1, 2, 3, 4, 6, 7, 8}) -assert(barrtostr(arr2) == "1|2|3|4|6|7|8") +asserts.equals(barrtostr(arr2), "1|2|3|4|6|7|8") arr:copy(4, arr2, 2, 3) -assert(barrtostr(arr2) == "1|34|87|21|6|7|8") +asserts.equals(barrtostr(arr2), "1|34|87|21|6|7|8") arr:fill(nil, nil, 192) -assert(barrtostr(arr) == "192|192|192|192|192|192|192") +asserts.equals(barrtostr(arr), "192|192|192|192|192|192|192") arr:fill(nil, 3, 233) -assert(barrtostr(arr) == "233|233|233|233|233|233|233") +asserts.equals(barrtostr(arr), "233|233|233|233|233|233|233") arr:fill(2, nil, 254) -assert(barrtostr(arr) == "254|254|254|254|254|254|254") +asserts.equals(barrtostr(arr), "254|254|254|254|254|254|254") arr:fill(2, 2, 66) -assert(barrtostr(arr) == "254|66|66|254|254|254|254") \ No newline at end of file +asserts.equals(barrtostr(arr), "254|66|66|254|254|254|254") From 5422eb7ccc4ce7b8cf69b30c2f58a57f23b0b271 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Aug 2026 19:19:50 +0300 Subject: [PATCH 19/23] add ctypes library --- res/modules/internal/ctypes.lua | 38 +++++++++++++++++++++++++++++++++ res/scripts/stdmin.lua | 2 ++ 2 files changed, 40 insertions(+) create mode 100644 res/modules/internal/ctypes.lua diff --git a/res/modules/internal/ctypes.lua b/res/modules/internal/ctypes.lua new file mode 100644 index 000000000..032ea34b5 --- /dev/null +++ b/res/modules/internal/ctypes.lua @@ -0,0 +1,38 @@ +local FFI = ffi + +FFI.cdef[[ + unsigned long long strtoull(const char* nptr, char** endptr, int base); + long long strtoll(const char* nptr, char** endptr, int base); +]] + +local this = {} + +local function create_integral_type(ctype_name, signed) + local parse_func = signed and FFI.C.strtoll or FFI.C.strtoull + return function(value, base) + value = value or 0 + local typename = type(value) + if typename == "number" then + return FFI.cast(ctype_name, value) + elseif typename == "string" then + if type(base) ~= "number" then + base = 10 + end + return parse_func(value, nil, base) + end + error(string.format("invalid value type: %s", typename)) + end +end + + +this.uint8 = create_integral_type("uint8_t", false) +this.uint16 = create_integral_type("uint16_t", false) +this.uint32 = create_integral_type("uint32_t", false) +this.uint64 = create_integral_type("uint64_t", false) + +this.int8 = create_integral_type("int8_t", true) +this.int16 = create_integral_type("int16_t", true) +this.int32 = create_integral_type("int32_t", true) +this.int64 = create_integral_type("int64_t", true) + +return this diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 196bf8942..03de8cbaa 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -322,6 +322,8 @@ FLTview = bytearray.FFIFLTview DBLview = bytearray.FFIDBLview Bytearray_construct = function(...) return Bytearray(...) end +ctypes = require "core:internal/ctypes" + bit.compile = require "core:bitwise/compiler" bit.execute = require "core:bitwise/executor" From 40a61307b32c9b2c386346c4f17f415cd1bede93 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Aug 2026 19:54:08 +0300 Subject: [PATCH 20/23] update bytearray test --- dev/tests/bytearray.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/bytearray.lua b/dev/tests/bytearray.lua index 0d1bdb6ae..71e895d37 100644 --- a/dev/tests/bytearray.lua +++ b/dev/tests/bytearray.lua @@ -38,7 +38,7 @@ asserts.equals(6, arr[3]) -- ============================= arr = Bytearray({254, 255, 255, 255, 255, 255, 255, 255}) --- asserts.equals(U64view(arr)[1], 2 ^ 64 - 2) +asserts.equals(U64view(arr)[1], ctypes.uint64(2) ^ 64 - 2) asserts.equals(I64view(arr)[1], -2) asserts.equals(U32view(arr)[1], 2 ^ 32 - 2) asserts.equals(I32view(arr)[1], -2) From 4a381ec2f4c5638659eaae7422e0b6648d1b8add Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Aug 2026 20:24:58 +0300 Subject: [PATCH 21/23] add ctypes docs (minimal) --- doc/en/scripting.md | 1 + doc/en/scripting/builtins/libctypes.md | 28 ++++++++++++++++++++++++++ doc/ru/scripting.md | 1 + doc/ru/scripting/builtins/libctypes.md | 28 ++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 doc/en/scripting/builtins/libctypes.md create mode 100644 doc/ru/scripting/builtins/libctypes.md diff --git a/doc/en/scripting.md b/doc/en/scripting.md index 09cf40ef4..2072d4353 100644 --- a/doc/en/scripting.md +++ b/doc/en/scripting.md @@ -16,6 +16,7 @@ Subsections: - [block](scripting/builtins/libblock.md) - [byteutil](scripting/builtins/libbyteutil.md) - [cameras](scripting/builtins/libcameras.md) + - [ctypes](scripting/builtins/libctypes.md) - [entities](scripting/builtins/libentities.md) - [file](scripting/builtins/libfile.md) - [gfx.blockwraps](scripting/builtins/libgfx-blockwraps.md) diff --git a/doc/en/scripting/builtins/libctypes.md b/doc/en/scripting/builtins/libctypes.md new file mode 100644 index 000000000..5517af0fa --- /dev/null +++ b/doc/en/scripting/builtins/libctypes.md @@ -0,0 +1,28 @@ +# *ctypes* Library + +A library for safe work with C types. + +| ctypes.\ | C-Type | Minimum | Maximum | +| --------------- | -------- | -------------------- | -------------------- | +| uint8 | uint8_t | 0 | 255 | +| uint16 | uint16_t | 0 | 65535 | +| uint32 | uint32_t | 0 | 4294967295 | +| uint64 | uint64_t | 0 | 18446744073709551615 | +| int8 | int8_t | -128 | 127 | +| int16 | int16_t | -32768 | 32767 | +| int32 | int32_t | -2147483648 | 2147483647 | +| int64 | int64_t | -9223372036854775808 | 9223372036854775807 | + + +Usage examples: + +```lua +local x = ctypes.uint64(1234) +print(x) --> 1234ULL (cdata) +local y = ctypes.uint64("18446744073709551615") +print(y) --> 18446744073709551615ULL (cdata) +print(x + y) --> 1233ULL + +local z = tonumber(x) +print(z) --> 1234 (number) +``` diff --git a/doc/ru/scripting.md b/doc/ru/scripting.md index db3fcd921..1e6d73098 100644 --- a/doc/ru/scripting.md +++ b/doc/ru/scripting.md @@ -16,6 +16,7 @@ - [block](scripting/builtins/libblock.md) - [byteutil](scripting/builtins/libbyteutil.md) - [cameras](scripting/builtins/libcameras.md) + - [ctypes](scripting/builtins/libctypes.md) - [entities](scripting/builtins/libentities.md) - [file](scripting/builtins/libfile.md) - [gfx.blockwraps](scripting/builtins/libgfx-blockwraps.md) diff --git a/doc/ru/scripting/builtins/libctypes.md b/doc/ru/scripting/builtins/libctypes.md new file mode 100644 index 000000000..d6c985b44 --- /dev/null +++ b/doc/ru/scripting/builtins/libctypes.md @@ -0,0 +1,28 @@ +# Библиотека *ctypes* + +Библиотека для безопасной работы с типами языка С. + +| ctypes.\ | С-тип | Минимум | Максимум | +| ------------- | -------- | -------------------- | -------------------- | +| uint8 | uint8_t | 0 | 255 | +| uint16 | uint16_t | 0 | 65535 | +| uint32 | uint32_t | 0 | 4294967295 | +| uint64 | uint64_t | 0 | 18446744073709551615 | +| int8 | int8_t | -128 | 127 | +| int16 | int16_t | -32768 | 32767 | +| int32 | int32_t | -2147483648 | 2147483647 | +| int64 | int64_t | -9223372036854775808 | 9223372036854775807 | + + +Примеры использования: + +```lua +local x = ctypes.uint64(1234) +print(x) --> 1234ULL (cdata) +local y = ctypes.uint64("18446744073709551615") +print(y) --> 18446744073709551615ULL (cdata) +print(x + y) --> 1233ULL + +local z = tonumber(x) +print(z) --> 1234 (number) +``` From f082d7608dac0fc9a6ebb4bef7a24a9c6ef7cd2d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Aug 2026 20:23:46 +0300 Subject: [PATCH 22/23] fix black screen in water --- src/graphics/render/WorldRenderer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 57cc90f24..4e2531d95 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -470,11 +470,16 @@ void WorldRenderer::renderFrame( setupWorldShader(entityShader, hudcam, engine.getSettings(), 0.0f); hands->render(camera); } - renderBlockOverlay(pctx); - + { + auto bctx = pctx.sub(); + bctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr); + renderBlockOverlay(pctx); + } glActiveTexture(GL_TEXTURE0); } +#include + void WorldRenderer::renderBlockOverlay(const DrawContext& wctx) { int x = std::floor(player.currentCamera->position.x); int y = std::floor(player.currentCamera->position.y); From 103bcb3751584fb25c19f6867485051231cf74f5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Aug 2026 20:24:32 +0300 Subject: [PATCH 23/23] remove trash --- src/graphics/render/WorldRenderer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 4e2531d95..a611c7ab6 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -478,8 +478,6 @@ void WorldRenderer::renderFrame( glActiveTexture(GL_TEXTURE0); } -#include - void WorldRenderer::renderBlockOverlay(const DrawContext& wctx) { int x = std::floor(player.currentCamera->position.x); int y = std::floor(player.currentCamera->position.y);