From 29f5373d81853a1ac1397d0e07484978fa117100 Mon Sep 17 00:00:00 2001 From: RomanDonw Date: Wed, 22 Jul 2026 20:36:01 +1000 Subject: [PATCH 01/16] 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/16] 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/16] (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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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")