mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 10:31:50 +00:00
Merge pull request #847 from MihailRis/client-side-tests
client-side `--script`, `--test` support (part 1)
This commit is contained in:
commit
4295af15cc
55 changed files with 1660 additions and 590 deletions
|
|
@ -42,6 +42,7 @@ Subsections:
|
|||
- [utf8](scripting/builtins/libutf8.md)
|
||||
- [vec2, vec3, vec4](scripting/builtins/libvecn.md)
|
||||
- [world](scripting/builtins/libworld.md)
|
||||
- [Extensions for standard libraries](scripting/extensions.md)
|
||||
- [Module core:bit_converter](scripting/modules/core_bit_converter.md)
|
||||
- [Module core:data_buffer](scripting/modules/core_data_buffer.md)
|
||||
- [Module core:vector2, core:vector3](scripting/modules/core_vector2_vector3.md)
|
||||
|
|
|
|||
204
doc/en/scripting/extensions.md
Normal file
204
doc/en/scripting/extensions.md
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
# Standard Library Extensions
|
||||
|
||||
The **stdmin.lua** kernel script defines functions that extend and complement some of the standard **Lua** libraries.
|
||||
|
||||
## Contents:
|
||||
- [table extensions](#table-extensions)
|
||||
- [string extensions](#string-extensions)
|
||||
- [math extensions](#math-extensions)
|
||||
- [bit extensions](#bit-extensions)
|
||||
- [additional global functions](#additional-global-functions)
|
||||
|
||||
## Table Extensions
|
||||
```lua
|
||||
-- Creates and returns a copy of the given table by creating a new one and copying all elements from the given table into it.
|
||||
table.copy(t: table) -> table
|
||||
|
||||
-- The deep copy function creates a full copy of the source table, including all its subtables.
|
||||
table.deep_copy(t: table) -> table
|
||||
|
||||
-- Returns the number of pairs in the given table.
|
||||
table.count_pairs(t: table) -> int
|
||||
|
||||
-- Returns one element from the given table at a random position.
|
||||
table.random(t: table) -> any
|
||||
|
||||
-- Returns true if x is contained in t.
|
||||
table.has(t: table, x: any) -> boolean
|
||||
|
||||
-- Returns the index of x in t. If the given object is not contained in the table, the function returns -1.
|
||||
table.index(t: table, x: any) -> int
|
||||
|
||||
-- Removes element x from t.
|
||||
table.remove_value(t: table, x: any)
|
||||
|
||||
-- Shuffles values in the table.
|
||||
table.shuffle(t: table) -> table
|
||||
|
||||
-- Adds values from table t2 to table t1. If table t2 contains a key from t1, the key's value will not be changed.
|
||||
table.merge(t1: table, t2: table) -> table
|
||||
|
||||
-- Iterates through the table and applies a func to all its elements, returning the new value of the element.
|
||||
table.map(t: table, func: function(indx, value)) -> table
|
||||
|
||||
-- Iterates through the table using a func that returns true if the element should be kept and false if it should be deleted.
|
||||
table.filter(t: table, func: function(indx, value)) -> table
|
||||
|
||||
-- Allows you to safely retrieve the value for the specified key. If the key exists in the table, the method will return its value.
|
||||
-- If the key is missing, the method will set it to the default value and return it.
|
||||
table.set_default(t: table, key: int | string, default: any) -> any
|
||||
|
||||
-- Returns a "flattened" version of the original table.
|
||||
table.flat(t: table) -> table
|
||||
|
||||
-- Returns a deep "flat" version of the original table.
|
||||
table.deep_flat(t: table) -> table
|
||||
|
||||
-- Returns a truncated version of the table from index start to index stop, inclusive. Key-value pairs
|
||||
-- are not preserved in the new table. For nil values, the value starts at 1 and ends at #arr, respectively.
|
||||
table.sub(arr: table, start: number | nil, stop: number | nil) -> table
|
||||
|
||||
-- Adds a value to the table only if it was not originally there.
|
||||
table.insert_unique(t: table, val: any)
|
||||
table.insert_unique(t: table, pos: int, val: any)
|
||||
|
||||
-- Returns a table containing all keys of the given table, including numeric ones. table.keys(t: table) -> table
|
||||
|
||||
-- Adds all key-value pairs from table extension to table t. If a key from t is present in extension, its value will be overwritten.
|
||||
table.extend(t: table, extension: table) -> table
|
||||
|
||||
-- Converts the passed table to a string.
|
||||
table.tostring(t: table) -> string
|
||||
```
|
||||
|
||||
## String extensions
|
||||
|
||||
It's important to note that all of the functions listed below that extend **string** can be used as meta-methods on string instances, i.e.:
|
||||
|
||||
```lua
|
||||
local str = "ABA str BAB"
|
||||
|
||||
if str:starts_with("ABA") and str:ends_with("BAB") then
|
||||
print(str:replace("BA", "DC"))
|
||||
end
|
||||
```
|
||||
|
||||
```lua
|
||||
-- Splits the string into parts based on the specified separator/expression and returns the result as a table of strings. If withpattern is true, the separator parameter will be evaluated as a regular expression. string.explode(separator: string, str: string, withpattern: boolean) -> table<string>
|
||||
|
||||
-- Splits the string into parts based on the specified delimiter and returns the result as a table of strings.
|
||||
string.split(str: string, delimiter: string) -> table<string>
|
||||
|
||||
-- Escapes special characters in the string, such as `()[]+-.$%^?*`, into `%character` format. The `NUL` character (`\0`) will be converted to `%z`.
|
||||
string.pattern_safe(str: string) -> string
|
||||
|
||||
-- Splits seconds into hours, minutes, and milliseconds and formats them using the following parameter order: `minutes, seconds, milliseconds`, and then returns the result. If format is not specified, it returns a table where:
|
||||
-- h - hours,
|
||||
-- m - minutes,
|
||||
-- s - seconds,
|
||||
-- ms - milliseconds.
|
||||
string.formatted_time(seconds: number, format: string) -> string | table
|
||||
|
||||
-- Replaces all substrings in str equal to tofind with toreplace and returns a string with all the modified substrings.
|
||||
string.replace(str: string, tofind: string, toreplace: string) -> string
|
||||
|
||||
-- Removes all characters equal to char from the string from the left and right ends and returns the result.
|
||||
-- If the char parameter is undefined, all empty characters will be selected.
|
||||
string.trim(str: string, char: string) -> string
|
||||
|
||||
-- Removes all characters equal to char from the string from the left end and returns the result.
|
||||
-- If the char parameter is undefined, all empty characters will be selected.
|
||||
string.trim_left(str: string, char: string) -> string
|
||||
|
||||
-- Removes all characters equal to char from the right end of the string and returns the result.
|
||||
-- If the char parameter is undefined, all empty characters will be selected.
|
||||
string.trim_right(str: string, char: string) -> string
|
||||
|
||||
-- Returns true if the string begins with the substring start.
|
||||
string.starts_with(str: string, start: string) -> boolean
|
||||
|
||||
-- Returns true if the string ends with the substring endStr.
|
||||
string.ends_with(str: string, endStr: string) -> boolean
|
||||
|
||||
-- The string.lower and string.upper functions are also overridden by utf8.lower and utf8.upper.
|
||||
|
||||
-- Escapes a string. It is an alias for utf8.escape.
|
||||
string.escape(str: string) -> string
|
||||
|
||||
-- Escapes special XML characters. An alias for utf8.escape_xml.
|
||||
string.escape_xml(text: string) -> string
|
||||
|
||||
-- Adds a char to the left and right of the string until its size equals size.
|
||||
-- By default, char is equal to the space character.
|
||||
string.pad(str: string, size: int, char: string) -> string
|
||||
|
||||
-- Adds a char to the left of the string until its size equals size.
|
||||
-- By default, char is equal to the space character.
|
||||
string.left_pad(str: string, size: int, char: string) -> string
|
||||
|
||||
-- Adds a char to the right of the string until its size equals size.
|
||||
-- By default, char is equal to the space character.
|
||||
string.right_pad(str: string, size: int, char: string) -> string
|
||||
```
|
||||
|
||||
## Math extensions
|
||||
|
||||
```lua
|
||||
-- Returns _in if it is in the range low <= _in <= high
|
||||
-- Otherwise, returns the boundary to which _in is closest.
|
||||
math.clamp(_in: number, low: number, high: number) -> number
|
||||
|
||||
-- Returns a random fractional number in the range low to high.
|
||||
math.rand(low: number, high: number) -> number
|
||||
|
||||
-- Returns the normalized value of num relative to conf.
|
||||
math.normalize(num: number, [optional] conf: number) -> number
|
||||
|
||||
-- Returns the rounded value of num to the specified number of decimal places.
|
||||
math.round(num: number, [optional] places: number) -> number
|
||||
|
||||
-- Returns the sum of all received arguments. If a table was passed as an argument, the method will return the sum of all its elements.
|
||||
math.sum(x: number, ... | t: table) -> number
|
||||
|
||||
```
|
||||
|
||||
## Bit extensions
|
||||
```lua
|
||||
|
||||
-- Common arguments:
|
||||
-- * expr: A string containing a bitwise expression, conforming to the Lua 5.3 bitwise operations format
|
||||
-- * args: A list of names of the expression arguments. If nil, the list is automatically generated based on the detected identifiers.
|
||||
|
||||
- Compiles the function to perform bitwise operations
|
||||
-- * asFunction: If true, returns the function; otherwise, returns a string of function code
|
||||
bit.compile(expr: string, args: table | nil, asFunction: boolean=true) -> function | string
|
||||
|
||||
-- Compiles the function to perform bitwise operations and executes it in place
|
||||
-- * ...: Values to be passed to the compiled function. bit.execute(expr: string, args: table | nil, ...) -> number
|
||||
```
|
||||
## Additional Global Functions
|
||||
|
||||
This script also defines other global functions that are available for use. Their list is below.
|
||||
|
||||
```lua
|
||||
-- Returns true if the passed table is an array, that is, if each key is an integer greater than or equal to one
|
||||
-- and if each key follows the previous one.
|
||||
is_array(x: table) -> boolean
|
||||
|
||||
-- Splits the path into two parts and returns them: the entry point and the file path.
|
||||
parse_path(path: string) -> string, string
|
||||
|
||||
-- Calls the function func iters times, passing it the arguments ..., and then prints to the console the time in microseconds that has elapsed
|
||||
-- since the call to timeit. timeit(iters: int, func: function, ...)
|
||||
|
||||
-- Causes the coroutine to pause until the number of seconds specified in timesec has elapsed.
|
||||
-- The function can only be used inside a coroutine.
|
||||
sleep(timesec: number)
|
||||
|
||||
-- Waits for the passed coroutine to complete, returning the control flow. The function can only be used inside a coroutine.
|
||||
-- Returns values similar to those returned by pcall.
|
||||
await(co: coroutine) -> result, error
|
||||
|
||||
-- A constant storing the PID of the current engine instance.
|
||||
os.pid -> number
|
||||
```
|
||||
|
|
@ -92,6 +92,11 @@ socket:recv_async(
|
|||
[опционально] usetable: boolean=false
|
||||
) -> nil|table|Bytearray
|
||||
|
||||
-- Оборачивает сокет в io_stream (см. ../io_stream.md)
|
||||
socket:as_stream(
|
||||
[опционально] binary_mode: boolean=true
|
||||
) -> io_stream
|
||||
|
||||
-- Закрывает соединение
|
||||
socket:close()
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
- [расширения для string](#расширения-для-string)
|
||||
- [расширения для math](#расширения-для-math)
|
||||
- [расширения для bit](#расширения-для-bit)
|
||||
- [Дополнительные глобальные функции](#дополнительные-глобальные-функции)
|
||||
- [дополнительные глобальные функции](#дополнительные-глобальные-функции)
|
||||
|
||||
## Расширения для table
|
||||
```lua
|
||||
|
|
@ -62,6 +62,12 @@ table.sub(arr: table, start: number | nil, stop: number | nil) -> table
|
|||
table.insert_unique(t: table, val: any)
|
||||
table.insert_unique(t: table, pos: int, val: any)
|
||||
|
||||
-- Возвращает таблицу, содержащую все ключи переданной таблицы, включая числовые.
|
||||
table.keys(t: table) -> table
|
||||
|
||||
-- Добавляет в таблицу t все пары ключ-значение из таблицы extension, при этом если в extension присутствует ключ из t, то его значение будет перезаписано.
|
||||
table.extend(t: table, extension: table) -> table
|
||||
|
||||
-- Конвертирует переданную таблицу в строку.
|
||||
table.tostring(t: table) -> string
|
||||
```
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
Поток имеет три различных вида режима:
|
||||
- Режим общего поведения (`general` / `mode`)
|
||||
|
||||
- Режим сброса (`flush` / `flushMode`)
|
||||
- Режим сброса (`flush` / `flush_mode`)
|
||||
|
||||
- Двоичный режим (`binary`)
|
||||
|
||||
|
|
@ -27,34 +27,34 @@
|
|||
Определяет, как поток обрабатывает чтение и запись,
|
||||
имеет три подрежима:
|
||||
|
||||
| Режим | Описание |
|
||||
|---------------|--------|
|
||||
| `"default"` | Прямой режим. `read` может вернуть меньше байт, чем запрошено. `write` сразу отправляет данные в низкоуровневый дескриптор. Нет буферизации. |
|
||||
| Режим | Описание |
|
||||
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `"default"` | Прямой режим. `read` может вернуть меньше байт, чем запрошено. `write` сразу отправляет данные в низкоуровневый дескриптор. Нет буферизации. |
|
||||
| `"yield"` | Как `default`, но при нехватке данных в `read(n)` поток будет вызывать `coroutine.yield()`, пока не соберёт ровно `n` байт. Удобно для корутин. |
|
||||
| `"buffered"` | Включает внутренние буферы чтения и записи. `read` берёт данные из буфера, `write` — складывает в буфер. При превышении `maxBufferSize` — ошибка `buffer overflow`. |
|
||||
| `"buffered"` | Включает внутренние буферы чтения и записи. `read` берёт данные из буфера , `write` — складывает в буфер. |
|
||||
|
||||
### flush
|
||||
|
||||
Работает только в режиме `"buffered"`,
|
||||
имеет два подрежима:
|
||||
|
||||
| Режим | Что делает `flush()` |
|
||||
|------------------|----------------------|
|
||||
| `"all"` (по умолчанию) | Сначала сбрасывает буфер записи → низкоуровневый `write`, затем вызывает `ioLib.flush(descriptor)` |
|
||||
| `"buffer"` | Сбрасывает только буфер записи, без вызова системного `flush` |
|
||||
| Режим | Что делает `flush()` |
|
||||
|------------------------|-----------------------------------------------------------------------------------------------------|
|
||||
| `"all"` (по умолчанию) | Сначала сбрасывает буфер записи → низкоуровневый `write`, затем вызывает `io_lib.flush(descriptor)` |
|
||||
| `"buffer"` | Сбрасывает только буфер записи, без вызова системного `flush` |
|
||||
|
||||
|
||||
### binary
|
||||
**Независимый флаг** (включается через `set_binary_mode(true)` или при создании потока).
|
||||
Определяет, в каком виде методы `read` и `write` принимают и возвращают данные:
|
||||
|
||||
| binary = true | binary = false (по умолчанию) |
|
||||
|-----------------------------------------|----------------------------------------|
|
||||
| binary = true | binary = false (по умолчанию) |
|
||||
|------------------------------------------------------------|----------------------------------------|
|
||||
| Данные — это **байты** (`Bytearray`, таблица чисел 0..255) | Данные — это **текстовые строки** |
|
||||
| `read(n)` → `Bytearray` или `table<number>`| `read()` → одна строка |
|
||||
| `read("i4 f")` → распаковка через `byteutil.unpack` | `read(n)` → n строк в таблице |
|
||||
| `write(Bytearray)` → запись байтов | `write("hello")` → строка + `\n` |
|
||||
| `write("i4", 42)` → `byteutil.pack` | `write({"a","b"})` → две строки с `\n`|
|
||||
| `read(n)` → `Bytearray` или `table<int>` | `read()` → одна строка |
|
||||
| `read("i4 f")` → распаковка через `byteutil.unpack` | `read(n)` → n строк в таблице |
|
||||
| `write(Bytearray)` → запись байтов | `write("hello")` → строка + `\n` |
|
||||
| `write("i4", 42)` → `byteutil.pack` | `write({"a","b"})` → две строки с `\n` |
|
||||
|
||||
`read_line` / `write_line` — работают как в текстовом режиме
|
||||
|
||||
|
|
@ -90,25 +90,25 @@ io_stream:set_flush_mode(string)
|
|||
--[[
|
||||
Читает данные из потока
|
||||
В двоичном режиме:
|
||||
Если arg - number, то читает из потока arg байт и возвращает ввиде Bytearray или таблицы, если useTable = true
|
||||
Если arg - int, то читает из потока arg байт и возвращает ввиде Bytearray или таблицы, если use_table = true
|
||||
|
||||
Если arg - string, то функция интерпретирует arg как шаблон для byteutil. Прочитает кол-во байт, которое определено шаблоном, передаст их в byteutil.unpack и вернёт результат
|
||||
В текстовом режиме:
|
||||
Если arg - number, то читает нужное кол-во строк с окончанием CRLF/LF из arg и возвращает ввиде таблицы. Также, если trimEmptyLines = true, то удаляет пустые строки с начала и конца из итоговой таблицы
|
||||
Если arg - int, то читает нужное кол-во строк с окончанием CRLF/LF из arg и возвращает ввиде таблицы. Также, если trim_empty_lines = true, то удаляет пустые строки с начала и конца из итоговой таблицы
|
||||
|
||||
Если arg не определён, то читает одну строку с окончанием CRLF/LF и возвращает её.
|
||||
--]]
|
||||
io_stream:read(
|
||||
[опционально] arg: number | string,
|
||||
[опционально] useTable | trimEmptyLines: boolean
|
||||
) -> Bytearray | table<number> | string | table<string> | ...
|
||||
[опционально] arg: int | string,
|
||||
[опционально] use_table = false | trim_empty_lines = true: boolean
|
||||
) -> Bytearray | table<int> | string | table<string> | ...
|
||||
|
||||
--[[
|
||||
Записывает данные в поток
|
||||
В двоичном режиме:
|
||||
Если arg - string, то функция интерпретирует arg как шаблон для byteutil, передаст его и ... в byteutil.pack и результат запишет в поток
|
||||
|
||||
Если arg - Bytearray | table<number>, то записывает байты в поток
|
||||
Если arg - Bytearray | table<int>, то записывает байты в поток
|
||||
|
||||
В текстовом режиме:
|
||||
Если arg - string, то записывает строку в поток (вместе с окончанием LF)
|
||||
|
|
@ -116,7 +116,7 @@ io_stream:read(
|
|||
Если arg - table<string>, то записывает каждую строку из таблицы отдельно
|
||||
--]]
|
||||
io_stream:write(
|
||||
arg: Bytearray | table<number> | string | table<string>,
|
||||
arg: Bytearray | table<int> | string | table<string>,
|
||||
[опционально] ...
|
||||
)
|
||||
|
||||
|
|
@ -128,53 +128,59 @@ io_stream:write_line(string)
|
|||
|
||||
--[[
|
||||
В двоичном режиме:
|
||||
Читает все доступные байты из потока и возвращает ввиде Bytearray или table<number>, если useTable = true
|
||||
Читает все доступные байты из потока и возвращает ввиде Bytearray или table<int>, если use_table = true
|
||||
|
||||
В текстовом режиме:
|
||||
Читает все доступные строки из потока в table<string> если useTable = true, или в одну строку вместе с окончаниями, если нет
|
||||
Читает все доступные строки из потока в table<string> если use_table = true, или в одну строку вместе с окончаниями, если нет
|
||||
|
||||
--]]
|
||||
io_stream:read_fully(
|
||||
[опционально] useTable: boolean
|
||||
) -> Bytearray | table<number> | table<string> | string
|
||||
[опционально] use_table: boolean
|
||||
) -> Bytearray | table<int> | table<string> | string
|
||||
|
||||
--[[
|
||||
Устанавливает позицию в потоке
|
||||
Если length определён, то возвращает true, если length байт доступно к чтению. Иначе возвращает false.
|
||||
|
||||
Если не определён, то возвращает количество байт, которое можно прочитать.
|
||||
|
||||
В не буферизированном режиме потока может всегда возвращать 0 или false, если поток не поддерживает available.
|
||||
--]]
|
||||
io_stream:available(
|
||||
[опционально] length: int
|
||||
) -> int | boolean
|
||||
|
||||
--[[
|
||||
Устанавливает позицию в потоке (всегда в байтах)
|
||||
Режимы:
|
||||
b - Задаёт позицию относительно начало файла
|
||||
c - Задаёт позицию относительно текущей позиции
|
||||
e - Задаёт позицию относительно конца файла
|
||||
|
||||
Может бросать ошибку, если поток не поддерживает seek.
|
||||
--]]
|
||||
io_stream:seek(
|
||||
mode: string
|
||||
offset: number
|
||||
offset: int
|
||||
)
|
||||
|
||||
-- Возвращает текущую позицию в потоке от начала.
|
||||
-- Может бросать ошибку, если поток не поддерживает tell.
|
||||
io_stream:tell() -> int
|
||||
```
|
||||
|
||||
## Методы Buffered-режима
|
||||
|
||||
```lua
|
||||
--[[
|
||||
Если length определён, то возвращает true, если length байт доступно к чтению. Иначе возвращает false
|
||||
|
||||
Если не определён, то возвращает количество байт, которое можно прочитать
|
||||
|
||||
--]]
|
||||
io_stream:available(
|
||||
[опционально] length: number
|
||||
) -> number | boolean
|
||||
|
||||
-- Возвращает максимальный размер буферов
|
||||
io_stream:get_max_buffer_size() -> number
|
||||
io_stream:get_max_buffer_size() -> int
|
||||
|
||||
-- Задаёт новый максимальный размер буферов
|
||||
io_stream:set_max_buffer_size(max_size: number)
|
||||
io_stream:set_max_buffer_size(max_size: int)
|
||||
```
|
||||
|
||||
## Методы контроля состояния потока
|
||||
|
||||
```lua
|
||||
|
||||
-- Возвращает true, если поток открыт на данный момент
|
||||
io_stream:is_alive() -> bool
|
||||
|
||||
|
|
@ -185,16 +191,27 @@ io_stream:is_closed() -> bool
|
|||
io_stream:close()
|
||||
|
||||
-- Записывает все данные из write-буфера в поток в buffer/all flush-режимах
|
||||
-- Вызывает ioLib.flush() в all flush-режиме
|
||||
-- Вызывает ioLib.flush() в all flush-режиме, или ничего не делает, если
|
||||
-- ioLib не поддерживает flush.
|
||||
io_stream:flush()
|
||||
|
||||
-- Создаёт новый поток из Bytearray.
|
||||
-- Может использоваться одновременно как для чтения, так и для записи.
|
||||
-- Результат записи будет записан в тот же Bytearray, что был передан в функцию.
|
||||
io_stream.wrap_bytearray(
|
||||
buffer: Bytearray,
|
||||
|
||||
-- по-умолчанию равен true, поскольку функция из вводных аргументов
|
||||
-- будет использоваться преимущественно для работы с двоичными данными.
|
||||
[опционально] binary_mode: boolean = true
|
||||
) -> io_stream
|
||||
|
||||
-- Создаёт новый поток с переданным дескриптором и использующим переданную I/O библиотеку. (Более подробно в core:io_stream.lua)
|
||||
io_stream.new(
|
||||
descriptor: int,
|
||||
binaryMode: bool,
|
||||
ioLib: table,
|
||||
binary_mode: boolean,
|
||||
io_lib: table,
|
||||
[опционально] mode: string = "default",
|
||||
[опционально] flushMode: string = "all"
|
||||
[опционально] flush_mode: string = "all"
|
||||
) -> io_stream
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue