diff --git a/README.md b/README.md index 30925fefd..8503dd651 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Latest release - [Download](https://github.com/MihailRis/VoxelCore/releases/latest) | [Скачать](https://github.com/MihailRis/VoxelCore/releases/latest) -- [Documentation](https://github.com/MihailRis/VoxelCore/blob/release-0.28/doc/en/main-page.md) | [Документация](https://github.com/MihailRis/VoxelCore/blob/release-0.28/doc/ru/main-page.md) +- [Documentation](https://github.com/MihailRis/VoxelCore/blob/release-0.29/doc/en/main-page.md) | [Документация](https://github.com/MihailRis/VoxelCore/blob/release-0.29/doc/ru/main-page.md) --- diff --git a/dev/tests/filesystem.lua b/dev/tests/filesystem.lua index a9ff58ce0..38e7c4a04 100644 --- a/dev/tests/filesystem.lua +++ b/dev/tests/filesystem.lua @@ -4,6 +4,7 @@ assert(file.exists("config:")) debug.log("write text file") assert(file.write("config:text.txt", "example, пример")) assert(file.exists("config:text.txt")) +assert(file.isfile("config:text.txt")) debug.log("read text file") assert(file.read("config:text.txt") == "example, пример") @@ -18,11 +19,23 @@ assert(file.isdir("config:dir")) debug.log("remove directory") file.remove("config:dir") +assert(not file.isdir("config:dir")) debug.log("create directories") file.mkdirs("config:dir/subdir/other") assert(file.isdir("config:dir/subdir/other")) +debug.log("list directory") +file.write("config:dir/subdir/a.txt", "helloworld") +file.write("config:dir/subdir/b.txt", "gfgsfhs") + +local entries = file.list("config:dir/subdir") +assert(#entries == 3) +table.sort(entries) +assert(entries[1] == "config:dir/subdir/a.txt") +assert(entries[2] == "config:dir/subdir/b.txt") +assert(entries[3] == "config:dir/subdir/other") + debug.log("remove tree") file.remove_tree("config:dir") assert(not file.isdir("config:dir")) diff --git a/dev/tests/memory_filesystem.lua b/dev/tests/memory_filesystem.lua new file mode 100644 index 000000000..e246279a7 --- /dev/null +++ b/dev/tests/memory_filesystem.lua @@ -0,0 +1,67 @@ +app.create_memory_device("memtest") +local tmp = file.create_memory_device() + +debug.log("check initial state") +assert(file.exists("memtest:")) +assert(file.is_writeable("memtest:")) +assert(file.is_writeable(tmp..":")) + +debug.log("write text file") +assert(file.write("memtest:text.txt", "example, пример")) +assert(file.exists("memtest:text.txt")) +assert(file.isfile("memtest:text.txt")) + +debug.log("read text file") +assert(file.read("memtest:text.txt") == "example, пример") + +debug.log("delete file") +file.remove("memtest:text.txt") +assert(not file.exists("memtest:text.txt")) + +debug.log("create directory") +file.mkdir("memtest:dir") +assert(file.isdir("memtest:dir")) + +debug.log("remove directory") +file.remove("memtest:dir") +assert(not file.isdir("memtest:dir")) + +debug.log("create directories") +file.mkdirs("memtest:dir/subdir/other") +assert(file.isdir("memtest:dir/subdir/other")) + +debug.log("list directory") +file.write("memtest:dir/subdir/a.txt", "helloworld") +file.write("memtest:dir/subdir/b.txt", "gfgsfhs") + +local entries = file.list("memtest:dir/subdir") +assert(#entries == 3) +table.sort(entries) +assert(entries[1] == "memtest:dir/subdir/a.txt") +assert(entries[2] == "memtest:dir/subdir/b.txt") +assert(entries[3] == "memtest:dir/subdir/other") + +debug.log("remove tree") +file.remove_tree("memtest:dir") +assert(not file.isdir("memtest:dir")) + +debug.log("write binary file") +local bytes = {0xDE, 0xAD, 0xC0, 0xDE} +file.write_bytes("memtest:binary", bytes) +assert(file.exists("memtest:binary")) + +debug.log("write binary file") +local bytes = {0xDE, 0xAD, 0xC0, 0xDE} +file.write_bytes("memtest:binary", bytes) +assert(file.exists("memtest:binary")) + +debug.log("read binary file") +local rbytes = file.read_bytes("memtest:binary") +assert(#rbytes == #bytes) +for i, b in ipairs(bytes) do + assert(rbytes[i] == b) +end + +debug.log("delete file") +file.remove("memtest:binary") +assert(not file.exists("memtest:binary")) diff --git a/doc/en/main-page.md b/doc/en/main-page.md index 5eb767f94..30cb106c5 100644 --- a/doc/en/main-page.md +++ b/doc/en/main-page.md @@ -1,8 +1,9 @@ # Documentation -Documentation for 0.30 (in development). +Documentation for 0.30. -[Documentation for 0.29.](https://github.com/MihailRis/voxelcore/blob/release-0.29/doc/ru/main-page.md) +> [!WARNING] +> Version is in development. Proceed to [Documentation for 0.29.](https://github.com/MihailRis/voxelcore/blob/release-0.29/doc/ru/main-page.md) ## Sections diff --git a/doc/en/scripting/builtins/libapp.md b/doc/en/scripting/builtins/libapp.md index 45414ba11..0ec755689 100644 --- a/doc/en/scripting/builtins/libapp.md +++ b/doc/en/scripting/builtins/libapp.md @@ -158,3 +158,36 @@ app.get_setting_info(name: str) -> { ``` Returns a table with information about a setting. Throws an exception if the setting does not exist. + +```lua +app.focus() +``` + +Brings the window to front and sets input focus. + +```lua +app.create_memory_device( + -- entry-point name + name: str +) +``` + +Creates an in-memory filesystem. + +```lua +app.get_content_sources() -> table +``` + +Returns a list of content sources (paths), in descending priority order. + +``lua +app.set_content_sources(sources: table) +``` + +Sets a list of content sources (paths). Specified in descending priority order. + +``lua +app.reset_content_sources() +``` + +Resets content sources. diff --git a/doc/en/scripting/builtins/libfile.md b/doc/en/scripting/builtins/libfile.md index 73d286af1..0d4374cac 100644 --- a/doc/en/scripting/builtins/libfile.md +++ b/doc/en/scripting/builtins/libfile.md @@ -139,6 +139,12 @@ file.create_zip(directory: str, output_file: str) --> str Creates a ZIP archive from the contents of the specified directory. +```lua +file.create_memory_device() --> str +``` + +Creates a memory file system and returns entry point name. Lives until content unload. + ```lua file.name(path: str) --> str ``` diff --git a/doc/en/scripting/builtins/libinput.md b/doc/en/scripting/builtins/libinput.md index 2c577389d..9856abc0b 100644 --- a/doc/en/scripting/builtins/libinput.md +++ b/doc/en/scripting/builtins/libinput.md @@ -13,7 +13,16 @@ input.mousecode(mousename: str) --> int Returns mouse button code or -1 if unknown ```lua -input.add_callback(bindname: str, callback: function) +input.add_callback( + -- Binding name + bindname: str, + -- Handler + callback: function + -- UI element that owns the handler (responsible for the handler's lifetime) + [optional] owner: Element, + -- Ignore input capture by UI elements + [optional] istoplevel: bool +) ``` Add binding activation callback. Example: diff --git a/doc/en/scripting/builtins/libnetwork.md b/doc/en/scripting/builtins/libnetwork.md index 0d32d8497..3ceac9c84 100644 --- a/doc/en/scripting/builtins/libnetwork.md +++ b/doc/en/scripting/builtins/libnetwork.md @@ -57,7 +57,10 @@ network.tcp_connect( -- Function called upon successful connection -- Sending will not work before connection -- Socket is passed as the only argument - callback: function(Socket) + callback: function(Socket), + -- Function called when a connection error occurs + -- Arguments passed: socket and error text + [optional] error_callback: function(Socket, str) ) --> Socket ``` @@ -79,6 +82,16 @@ socket:recv( -- Returns nil on error (socket is closed or does not exist). -- If there is no data yet, returns an empty byte array. +-- Asynchronous version for use in coroutines. +-- Waits for the entire specified number of bytes to be received. +-- If socket closes, function works like socket:recv +socket:recv_async( + -- Size of the byte array to read + length: int, + -- Use table instead of Bytearray + [optional] usetable: bool=false +) -> nil|table|Bytearray + -- Closes the connection socket:close() @@ -129,3 +142,10 @@ network.get_total_upload() --> int -- in bytes. network.get_total_download() --> int ``` + +## Other + +```lua +-- Looks for a free port to use. +network.find_free_port() --> int or nil +``` diff --git a/doc/en/scripting/builtins/libplayer.md b/doc/en/scripting/builtins/libplayer.md index 52503eeb9..7e27d817c 100644 --- a/doc/en/scripting/builtins/libplayer.md +++ b/doc/en/scripting/builtins/libplayer.md @@ -40,13 +40,13 @@ Sets x, y, z player linear velocity player.get_rot(playerid: int, interpolated: bool) -> number, number, number ``` -Returns x, y, z of camera rotation (radians). Interpolation is relevant in cases where the rotation refresh rate is lower than the frame rate. +Returns x, y, z of camera rotation (degrees). Interpolation is relevant in cases where the rotation refresh rate is lower than the frame rate. ```lua player.set_rot(playerid: int, x: number, y: number, z: number) ``` -Set camera rotation (radians) +Set camera rotation (degrees) ```lua player.get_inventory(playerid: int) -> int, int diff --git a/doc/en/scripting/events.md b/doc/en/scripting/events.md index fce3abfbd..fc8bb27f8 100644 --- a/doc/en/scripting/events.md +++ b/doc/en/scripting/events.md @@ -4,6 +4,10 @@ Callbacks specified in block script. +> [!WARNING] +> events such as on_block_tick, on_block_present, and on_block_removed +> can cause performance issues if used carelessly or excessively. + ```lua function on_placed(x, y, z, playerid) ``` @@ -53,6 +57,21 @@ function on_block_tick(x, y, z, tps: number) Called tps (20 / tick-interval) times per second for a block. Use 1/tps instead of `time.delta()`. +```lua +function on_block_present(x, y, z) +``` + +Called for a specific block when it appears in the world (generated/loaded/placed). +The call occurs within a time period that may depend on the event queue load. +Under light load, it occurs during the first tick interval of the block. +on_block_tick is not called until the event is called. + +```lua +function on_block_removed(x, y, z) +``` + +Called when chunk containing the block unloads. + ```lua function on_player_tick(playerid: int, tps: int) ``` diff --git a/doc/en/scripting/ui.md b/doc/en/scripting/ui.md index c35bf9088..7ce304b8c 100644 --- a/doc/en/scripting/ui.md +++ b/doc/en/scripting/ui.md @@ -194,13 +194,23 @@ Here, *color* can be specified in the following ways: | data:blit(src: Canvas, dst_x: int, dst_y: int) | draws the src canvas at the specified coordinates | | data:clear() | clears the canvas | | data:clear(*color*) | fills the canvas with the specified RGBA color | +| data:rect(x: int, y: int, w: int, h: int, *color*) | fills the rectangle with the specified RGBA color | | data:update() | applies changes to the canvas and uploads it to the GPU | -| data:set_data(data: table) | replaces pixel data (width * height * 4 numbers) | +| data:set_data(data: Bytearray | table) | replaces pixel data (width * height * 4 numbers) | +| data:get_data() | creates a Bytearray object with the image's pixel data | | data:create_texture(name: str) | creates and shares texture to renderer | | data:unbind_texture() | unbinds the texture from the canvas | | data:mul(*color* or Canvas) | multiplies a color by the specified color or canvas | | data:add(*color* or Canvas) | adds a color or another canvas to a color | | data:sub(*color* or Canvas) | subtracts a color or another canvas to a color | +| data:encode(format: str) | encodes image to specified format and returns bytearray | + +To decode a byte array into a Canvas, use the static method: +```lua +Canvas.decode(data: Bytearray, format: str) -> Canvas +``` + +Currently, only png is supported. ## Inline frame (iframe) diff --git a/doc/en/xml-ui-layouts.md b/doc/en/xml-ui-layouts.md index 1127d79fe..5a4d7be4e 100644 --- a/doc/en/xml-ui-layouts.md +++ b/doc/en/xml-ui-layouts.md @@ -136,6 +136,7 @@ The key code for comparison can be obtained via `input.keycode("key_name")` - `text-wrap` - allows automatic text wrapping (works only with multiline: "true") - `editable` - determines whether the text can be edited. - `line-numbers` - enables line numbers display. +- `keep-line-selection` - keep showing selected line after defocus. - `error-color` - color when entering incorrect data (the text does not pass the validator check). Type: RGBA color. - `text-color` - text color. Type: RGBA color. - `validator` - lua function that checks text for correctness. Takes a string as input, returns true if the text is correct. diff --git a/doc/ru/console.md b/doc/ru/console.md index b5f931f69..f87dd89f8 100644 --- a/doc/ru/console.md +++ b/doc/ru/console.md @@ -14,7 +14,7 @@ Для создания команды консоли используется следующая функция: ```python -console.add_command(схема: str, исполнитель: function) +console.add_command(схема: str, исполнитель: function, чит_команда: bool) ``` Схема имеет следующий синтаксис: @@ -106,7 +106,7 @@ console.add_command( "Teleport object", function (args, kwargs) player.set_pos(unpack(args)) - end + end, true ) ``` @@ -114,3 +114,23 @@ console.add_command( - В kwargs передается таблица значений именованных аргументов. Проверку и приведение типов интерпретатор команд производит автоматически. + +## Остальные методы + +```lua +console.set_cheat(name: String, cheat: Boolean) -> cheatIsChanged: Boolean +console.is_cheat(name: String) -> Boolean +``` +Сеттер и геттер статуса "чит" команды + + +```lua +console.log(...) -- Выводит информацию во внутриигровую консоль +console.chat(...) -- Выводит информацию во внутриигровой чат +console.get_commands_list() -> Table -- Возвращает таблицу со списком команд +console.get_command_info(name: String) -> Table -- Возвращает информацию о команде +console.execute(command: str) -- Выполняет команду +``` + + + diff --git a/doc/ru/main-page.md b/doc/ru/main-page.md index 60d0794d7..e74c29155 100644 --- a/doc/ru/main-page.md +++ b/doc/ru/main-page.md @@ -1,8 +1,9 @@ # Документация -Документация версии 0.30 (в разработке). +Документация версии 0.30. -[Документация 0.29.](https://github.com/MihailRis/voxelcore/blob/release-0.29/doc/ru/main-page.md) +> [!WARNING] +> Версия находится в разработке. Перейдите к [документации для 0.28](https://github.com/MihailRis/voxelcore/blob/release-0.29/doc/ru/main-page.md) ## Разделы diff --git a/doc/ru/scripting/builtins/libapp.md b/doc/ru/scripting/builtins/libapp.md index d2ddec725..d8a1e81ca 100644 --- a/doc/ru/scripting/builtins/libapp.md +++ b/doc/ru/scripting/builtins/libapp.md @@ -159,3 +159,35 @@ app.get_setting_info(name: str) -> { ``` Возвращает таблицу с информацией о настройке. Бросает исключение, если настройки не существует. + +```lua +app.focus() +``` + +Переводит окно на передний план и устанавливает фокус ввода. + +app.create_memory_device( + -- имя точки входа + name: str +) +``` + +Создаёт файловую систему в памяти. + +```lua +app.get_content_sources() -> table +``` + +Возвращает список источников контента (путей), в порядке убывания приоритета. + +```lua +app.set_content_sources(sources: table) +``` + +Устанавливает список источников контента (путей). Указывается в порядке убывания приоритета. + +```lua +app.reset_content_sources() +``` + +Сбрасывает список источников контента. diff --git a/doc/ru/scripting/builtins/libfile.md b/doc/ru/scripting/builtins/libfile.md index 4afbe23c9..67af51785 100644 --- a/doc/ru/scripting/builtins/libfile.md +++ b/doc/ru/scripting/builtins/libfile.md @@ -139,6 +139,12 @@ file.create_zip(директория: str, выходной_файл: str) --> s Создаёт ZIP-архив из содержимого указанной директории. +```lua +file.create_memory_device() --> str +``` + +Создаёт файловую систему в памяти, возвращает имя точки входа. Удаляется при выгрузке контента. + ```lua file.name(путь: str) --> str ``` diff --git a/doc/ru/scripting/builtins/libinput.md b/doc/ru/scripting/builtins/libinput.md index 96bc3105d..6aadbdc13 100644 --- a/doc/ru/scripting/builtins/libinput.md +++ b/doc/ru/scripting/builtins/libinput.md @@ -13,7 +13,16 @@ input.mousecode(mousename: str) --> int Возвращает код кнопки мыши по имени, либо -1 ```lua -input.add_callback(bindname: str, callback: function) +input.add_callback( + -- Имя привязки + bindname: str, + -- Обработчик + callback: function + -- UI элемент-владелец обработчика (отвечает за срок жизни) + [опционально] owner: Element, + -- Игнорировать захват ввода UI элементами + [опционально] istoplevel: bool +) ``` Назначает функцию, которая будет вызываться при активации привязки. Пример: diff --git a/doc/ru/scripting/builtins/libnetwork.md b/doc/ru/scripting/builtins/libnetwork.md index bef8967c5..8c574f361 100644 --- a/doc/ru/scripting/builtins/libnetwork.md +++ b/doc/ru/scripting/builtins/libnetwork.md @@ -58,6 +58,9 @@ network.tcp_connect( -- До подключения отправка работать не будет -- Как единственный аргумент передаётся сокет callback: function(Socket) + -- Функция, вызываемая при ошибке подключения + -- Как аргументы передаются сокет и текст ошибки + [опционально] error_callback: function(Socket, str) ) --> Socket ``` @@ -79,6 +82,16 @@ socket:recv( -- В случае ошибки возвращает nil (сокет закрыт или несуществует). -- Если данных пока нет, возвращает пустой массив байт. +-- Асинхронный вариант для использования в корутинах. +-- Ожидает получение всего указанного числа байт. +-- При закрытии сокета работает как socket:recv +socket:recv_async( + -- Размер читаемого массива байт + length: int, + -- Использовать таблицу вместо Bytearray + [опционально] usetable: bool=false +) -> nil|table|Bytearray + -- Закрывает соединение socket:close() @@ -194,3 +207,10 @@ network.get_total_upload() --> int -- в байтах. network.get_total_download() --> int ``` + +## Другое + +```lua +-- Ищет свободный для использования порт. +network.find_free_port() --> int или nil +``` diff --git a/doc/ru/scripting/builtins/libplayer.md b/doc/ru/scripting/builtins/libplayer.md index f635b6063..c789df8d2 100644 --- a/doc/ru/scripting/builtins/libplayer.md +++ b/doc/ru/scripting/builtins/libplayer.md @@ -40,13 +40,13 @@ player.set_vel(playerid: int, x: number, y: number, z: number) player.get_rot(playerid: int, interpolated: bool=false) -> number, number, number ``` -Возвращает x, y, z вращения камеры (в радианах). Интерполяция актуальна в случаях, когда частота обновления вращения ниже частоты кадров. +Возвращает x, y, z вращения камеры (в градусах). Интерполяция актуальна в случаях, когда частота обновления вращения ниже частоты кадров. ```lua player.set_rot(playerid: int, x: number, y: number, z: number) ``` -Устанавливает x, y вращения камеры (в радианах) +Устанавливает x, y вращения камеры (в градусах) ```lua player.get_inventory(playerid: int) -> int, int diff --git a/doc/ru/scripting/events.md b/doc/ru/scripting/events.md index 73a6bc0ce..83baef253 100644 --- a/doc/ru/scripting/events.md +++ b/doc/ru/scripting/events.md @@ -4,6 +4,10 @@ Функции для обработки событий, прописываемые в скрипте блока. +> [!WARNING] +> Mass events such as on_block_tick, on_block_present, and on_block_removed, +> if used carelessly or excessively, can lead to performance issues. + ```lua function on_placed(x, y, z, playerid) ``` @@ -53,6 +57,21 @@ function on_block_tick(x, y, z, tps: number) Вызывается tps (20 / tick-interval) раз в секунду для конкретного блока. Используйте 1/tps вместо `time.delta()`. +```lua +function on_block_present(x, y, z) +``` + +Вызывается для конкретного блока при появлении (генерации/загрузке/размещении). +Вызов происходит в течение времени, которое может зависеть от нагрузки очереди событий. +При малой нагрузке происходит в течение первого такта блока (tick-interval). +До вызова события on_block_tick не вызывается. + +```lua +function on_block_removed(x, y, z) +``` + +Вызывается при выгрузке чанка, в котором находится блок. + ```lua function on_player_tick(playerid: int, tps: int) ``` diff --git a/doc/ru/scripting/extensions.md b/doc/ru/scripting/extensions.md index 7ef835f46..2d7f0a1d5 100644 --- a/doc/ru/scripting/extensions.md +++ b/doc/ru/scripting/extensions.md @@ -94,6 +94,13 @@ table.sub(arr: table, start: number | nil, stop: number | nil) -> table Возвращает обрезанную версию таблицы с индекса **start** до индекса **stop** включительно, при этом пары ключ-значение не сохраняются в новой таблице. При значениях **nil** начинает с **1** и заканчивает **#arr** соответственно. +```lua +table.insert_unique(t: table, val: any) +table.insert_unique(t: table, pos: number, val: any) +``` + +Добавляет значение в таблицу, только если его там не было. + ```lua table.tostring(t: table) -> string ``` diff --git a/doc/ru/scripting/ui.md b/doc/ru/scripting/ui.md index a6d6006da..963e8b004 100644 --- a/doc/ru/scripting/ui.md +++ b/doc/ru/scripting/ui.md @@ -186,21 +186,31 @@ document["worlds-panel"]:clear() - r: int, g: int, b: int - r: int, g: int, b: int, a: int -| Метод | Описание | -|----------------------------------------------------------|------------------------------------------------------| -| data:at(x: int, y: int) | возвращает RGBA пиксель по указанным координатам | -| data:set(x: int, y: int, *цвет*) | изменяет RGBA пиксель по указанным координатам | -| data:line(x1: int, y1: int, x2: int, y2: int, *цвет*) | рисует линию с указанным RGBA цветом | -| data:blit(src: Canvas, dst_x: int, dst_y: int) | рисует src-холст на указанных координатах | -| data:clear() | очищает холст | -| data:clear(*цвет*) | заполняет холст указанным RGBA цветом | -| data:update() | применяет изменения и загружает холст в видеопамять | -| data:set_data(data: table) | заменяет данные пикселей (ширина * высота * 4 чисел) | -| data:create_texture(name: str) | создаёт и делится текстурой с рендерером | -| data:unbind_texture() | отвязывает текстуру от холста | -| data:mul(*цвет* или Canvas) | умножает увет на указанный цвет или холст | -| data:add(*цвет* или Canvas) | прибавляет цвет или другой холст к цвету | -| data:sub(*цвет* или Canvas) | вычитает цвет или другой холст к цвету | +| Метод | Описание | +|----------------------------------------------------------|-----------------------------------------------------------------| +| data:at(x: int, y: int) | возвращает RGBA пиксель по указанным координатам | +| data:set(x: int, y: int, *цвет*) | изменяет RGBA пиксель по указанным координатам | +| data:line(x1: int, y1: int, x2: int, y2: int, *цвет*) | рисует линию с указанным RGBA цветом | +| data:blit(src: Canvas, dst_x: int, dst_y: int) | рисует src-холст на указанных координатах | +| data:clear() | очищает холст | +| data:clear(*цвет*) | заполняет холст указанным RGBA цветом | +| data:rect(x: int, y: int, w: int, h: int, *цвет*) | заполняет прямоугольник указанным RGBA цветом | +| data:update() | применяет изменения и загружает холст в видеопамять | +| data:set_data(data: bytearray | table) | заменяет данные пикселей (ширина * высота * 4 чисел) | +| data:get_data() | создаёт объект Bytearray с пиксельными данными изображения | +| data:create_texture(name: str) | создаёт и делится текстурой с рендерером | +| data:unbind_texture() | отвязывает текстуру от холста | +| data:mul(*цвет* или Canvas) | умножает увет на указанный цвет или холст | +| data:add(*цвет* или Canvas) | прибавляет цвет или другой холст к цвету | +| data:sub(*цвет* или Canvas) | вычитает цвет или другой холст к цвету | +| data:encode(format: str) | кодирует изображение в указанный формат и возращает массив байт | + +Для декодирования массива байт в Canvas используйте статический метод: +```lua +Canvas.decode(data: Bytearray, format: str) -> Canvas +``` + +На данный момент, из форматов поддерживается только png. ## Рамка встраивания (iframe) diff --git a/doc/ru/xml-ui-layouts.md b/doc/ru/xml-ui-layouts.md index a2f068cab..b6efa7b29 100644 --- a/doc/ru/xml-ui-layouts.md +++ b/doc/ru/xml-ui-layouts.md @@ -137,6 +137,7 @@ - `text-wrap` - разрешает автоматический перенос текста (работает только при multiline: "true") - `editable`- определяет возможность редактирования текста. - `line-numbers` - включает отображение номеров строк. +- `keep-line-selection` - продолжать отображать выбранную строку при потере фокуса. - `error-color` - цвет при вводе некорректных данных (текст не проходит проверку валидатора). Тип: RGBA цвет. - `text-color` - цвет текста. Тип: RGBA цвет. - `validator` - lua функция, проверяющая текст на корректность. Принимает на вход строку, возвращает true если текст корректен. diff --git a/doc/specs/debugging_protocol.md b/doc/specs/debugging_protocol.md new file mode 100644 index 000000000..ba4cf96a8 --- /dev/null +++ b/doc/specs/debugging_protocol.md @@ -0,0 +1,153 @@ +# VC-DBG protocol v1 + +## Notes + +- '?' in name means that the attribute is optional. + +## Connecting + +### Step 1 + +Connection initiating with binary header exchange: + +``` +'v' 'c' '-' 'd' 'b' 'g' NUL XX +76 63 2D 64 62 67 00 XX +``` + +XX - protocol version number + +Client sends header to the server. Then server responds. +Server closes connection after sending header if it mismatches. + +### Step 2 + +Client sends 'connect' command. + +## Messages + +Message is: +- 32 bit little-endian unsigned integer - number of encoded message bytes. +- message itself (UTF-8 encoded json). + +## Client-to-server + +### Establishing connection + +```json +{ + "type": "connect", + "?disconnect-action": "resume|detach|terminate" +} +``` + +Configuring connection. Disconnect-action is action that debugged instance must perform on debugging client connection closed/refused. + +- `resume` - Resume from pause mode and start listening for client. +- `detach` - Resume from pause mode and stop server. +- `terminate` - Stop the debugged application. + + +### Specific action signals. + +```json +{ + "type": "pause|resume|terminate|detach" +} +``` + +### Breakpoints management + +```json +{ + "type": "set-breakpoint|remove-breakpoint", + "source": "entry_point:path", + "line": 1 +} +``` + +### Local value details request + +```json +{ + "type": "get-value", + "frame": 0, + "local": 1, + "path": ["path", "to", 1, "value"] +} +``` + +- `frame` - Call stack frame index (indexing from most recent call) +- `local` - Local variable index (based on `paused` event stack trace) +- `path` - Requsted value path segments. Example: `['a', 'b', 5]` is `local_variable.a.b[5]` + +Responds with: + +```json +{ + "type": "value", + "frame": 0, + "local": 1, + "path": ["path", "to", 1, "value"], + "value": "value itself" +} +``` + +Example: actual value is table: +```lua +{a=5, b="test", 2={}} +``` + +Then `value` is: +```json +{ + "a": { + "type": "number", + "short": "5" + }, + "b": { + "type": "string", + "short": "test" + }, + "1": { + "type": "table", + "short": "{...}" + } +} +``` + +## Server-to-client + +### Response signals + +```json +{ + "type": "success|resumed" +} +``` + +### Pause event + +```json +{ + "type": "paused", + "?reason": "breakpoint|exception|step", + "?message": "...", + "?stack": [ + { + "?function": "function name", + "source": "source name", + "what": "what", + "line": 1, + "locals": [ + "name": { + "type": "local type", + "index": 1, + "short": "short value", + "size": 0 + } + ] + } + ] +} +``` diff --git a/res/devtools/syntax/lua.toml b/res/devtools/syntax/lua.toml index cbccce751..d2469d2fb 100644 --- a/res/devtools/syntax/lua.toml +++ b/res/devtools/syntax/lua.toml @@ -8,5 +8,5 @@ multiline-string-end = "]]" keywords = [ "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", - "until", "while" + "until", "while", "self", "error" ] diff --git a/res/layouts/pages/scripts.xml.lua b/res/layouts/pages/scripts.xml.lua index 72c3246f4..7e8a266f7 100644 --- a/res/layouts/pages/scripts.xml.lua +++ b/res/layouts/pages/scripts.xml.lua @@ -1,5 +1,5 @@ function run_script(path) - __vc_start_app_script(path) + __vc_start_app_script(path, path) end function refresh() diff --git a/res/layouts/pages/settings_audio.xml.lua b/res/layouts/pages/settings_audio.xml.lua index 298598190..eaa8b3fb1 100644 --- a/res/layouts/pages/settings_audio.xml.lua +++ b/res/layouts/pages/settings_audio.xml.lua @@ -29,7 +29,7 @@ local initialized = false function on_open() if not initialized then initialized = true - local token = audio.input.__get_core_token() + local token = core.get_core_token() document.root:add("") local prev_amplitude = 0.0 document.tm:setInterval(16, function() @@ -54,16 +54,18 @@ function on_open() create_setting("audio.volume-music", "Music", 0.01) document.root:add("") document.root:add("