mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
Merge branch 'main' into animation
This commit is contained in:
commit
d20e9fcb40
18 changed files with 242 additions and 124 deletions
|
|
@ -9,21 +9,22 @@ local filename = "script:"..app.script..".lua"
|
||||||
|
|
||||||
Since the control script may not belong to any of the packs, it does not belongs to its own package and has its own global namespace in which all global functions and tables are available, as well as the `app` library.
|
Since the control script may not belong to any of the packs, it does not belongs to its own package and has its own global namespace in which all global functions and tables are available, as well as the `app` library.
|
||||||
|
|
||||||
## Functions
|
|
||||||
|
## Common functions
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
-- Performs one tick of the main engine loop.
|
||||||
app.tick()
|
app.tick()
|
||||||
```
|
|
||||||
|
|
||||||
Performs one tick of the main engine loop.
|
-- Waits for the specified time in seconds, performing the main engine loop.
|
||||||
|
|
||||||
```lua
|
|
||||||
app.sleep(time: number)
|
app.sleep(time: number)
|
||||||
```
|
|
||||||
|
|
||||||
Waits for the specified time in seconds, performing the main engine loop.
|
-- Terminates the engine, printing the call stack
|
||||||
|
-- to trace the function call location.
|
||||||
|
app.quit()
|
||||||
|
|
||||||
```lua
|
-- Waits for the condition checked by the function to be true,
|
||||||
|
-- performing the main engine loop.
|
||||||
app.sleep_until(
|
app.sleep_until(
|
||||||
-- function that checks the condition for ending the wait
|
-- function that checks the condition for ending the wait
|
||||||
predicate: function() -> bool,
|
predicate: function() -> bool,
|
||||||
|
|
@ -36,51 +37,54 @@ app.sleep_until(
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Waits for the condition checked by the function to be true, performing the main engine loop.
|
## Content
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
app.quit()
|
-- Checks if content is loaded.
|
||||||
```
|
app.is_content_loaded() -> bool
|
||||||
|
|
||||||
Terminates the engine, printing the call stack to trace the function call location.
|
-- Returns the current content configuration
|
||||||
|
-- (list of packs IDs in loading order)
|
||||||
|
app.get_content() -> table<string>
|
||||||
|
|
||||||
```lua
|
-- Loads content based on the current configuration.
|
||||||
|
-- Cannot be used if content is already loaded (see app.reset_content).
|
||||||
|
app.load_content()
|
||||||
|
|
||||||
|
-- Unloads all content, resetting it to a single core pack.
|
||||||
|
app.reset_content(
|
||||||
|
-- Packs for which modules, events, and environment will not be reset
|
||||||
|
[optional] non_reset_packs: table
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Updates the packs configuration, checking its correctness
|
||||||
|
-- (dependencies and availability of packs).
|
||||||
|
-- Automatically adds and reorders packs based on dependencies.
|
||||||
app.reconfig_packs(
|
app.reconfig_packs(
|
||||||
-- packs to add
|
-- packs to add
|
||||||
add_packs: table,
|
add_packs: table,
|
||||||
-- packs to remove
|
-- packs to remove
|
||||||
remove_packs: table
|
remove_packs: table
|
||||||
)
|
)
|
||||||
```
|
|
||||||
|
|
||||||
Updates the packs configuration, checking its correctness (dependencies and availability of packs).
|
-- To remove all packs from the configuration,you can use `pack.get_installed()`:
|
||||||
Automatically adds dependencies.
|
|
||||||
|
|
||||||
To remove all packs from the configuration, you can use `pack.get_installed()`:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
app.reconfig_packs({}, pack.get_installed())
|
app.reconfig_packs({}, pack.get_installed())
|
||||||
```
|
-- In this case, `base` will also be removed from the configuration.
|
||||||
|
|
||||||
In this case, `base` will also be removed from the configuration.
|
-- Updates the packs configuration, automatically removing unspecified ones,
|
||||||
|
-- adding those missing in the previous configuration.
|
||||||
```lua
|
-- Uses app.reconfig_packs.
|
||||||
app.config_packs(
|
app.config_packs(
|
||||||
-- expected set of packs (excluding dependencies)
|
-- expected set of packs (excluding dependencies)
|
||||||
packs: table
|
packs: table
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Updates the packs configuration, automatically removing unspecified ones, adding those missing in the previous configuration.
|
## Worlds
|
||||||
Uses app.reconfig_packs.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
app.is_content_loaded() -> bool
|
|
||||||
```
|
|
||||||
|
|
||||||
Checks if content is loaded.
|
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
-- Creates a new world and opens it.
|
||||||
app.new_world(
|
app.new_world(
|
||||||
-- world name, empty string will create a nameless world
|
-- world name, empty string will create a nameless world
|
||||||
name: str,
|
name: str,
|
||||||
|
|
@ -91,62 +95,42 @@ app.new_world(
|
||||||
-- local player id
|
-- local player id
|
||||||
[optional] local_player: int=0
|
[optional] local_player: int=0
|
||||||
)
|
)
|
||||||
```
|
|
||||||
|
|
||||||
Creates a new world and opens it.
|
-- Deletes a world by name.
|
||||||
|
app.delete_world(name: str)
|
||||||
|
|
||||||
```lua
|
-- Opens a world by name.
|
||||||
app.open_world(name: str)
|
app.open_world(name: str)
|
||||||
```
|
|
||||||
|
|
||||||
Opens a world by name.
|
-- Reopens the world.
|
||||||
|
|
||||||
```lua
|
|
||||||
app.reopen_world()
|
app.reopen_world()
|
||||||
```
|
|
||||||
|
|
||||||
Reopens the world.
|
-- Saves the world.
|
||||||
|
|
||||||
```lua
|
|
||||||
app.save_world()
|
app.save_world()
|
||||||
```
|
|
||||||
|
|
||||||
Saves the world.
|
-- Closes the world.
|
||||||
|
|
||||||
```lua
|
|
||||||
app.close_world(
|
app.close_world(
|
||||||
-- save the world before closing
|
-- save the world before closing
|
||||||
[optional] save_world: bool=false
|
[optional] save_world: bool=false
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Closes the world.
|
## Engine settings and information
|
||||||
|
|
||||||
```lua
|
|
||||||
app.delete_world(name: str)
|
|
||||||
```
|
|
||||||
|
|
||||||
Deletes a world by name.
|
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
-- Returns the major and minor versions of the engine.
|
||||||
app.get_version() -> int, int
|
app.get_version() -> int, int
|
||||||
```
|
|
||||||
|
|
||||||
Returns the major and minor versions of the engine.
|
-- Returns the value of a setting.
|
||||||
|
-- Throws an exception if the setting does not exist.
|
||||||
```lua
|
|
||||||
app.get_setting(name: str) -> value
|
app.get_setting(name: str) -> value
|
||||||
```
|
|
||||||
|
|
||||||
Returns the value of a setting. Throws an exception if the setting does not exist.
|
-- Sets the value of a setting.
|
||||||
|
-- Throws an exception if the setting does not exist.
|
||||||
```lua
|
|
||||||
app.set_setting(name: str, value: value)
|
app.set_setting(name: str, value: value)
|
||||||
```
|
|
||||||
|
|
||||||
Sets the value of a setting. Throws an exception if the setting does not exist.
|
-- Returns a table with information about a setting.
|
||||||
|
-- Throws an exception if the setting does not exist.
|
||||||
```lua
|
|
||||||
app.get_setting_info(name: str) -> {
|
app.get_setting_info(name: str) -> {
|
||||||
-- default value
|
-- default value
|
||||||
def: value,
|
def: value,
|
||||||
|
|
@ -155,43 +139,30 @@ app.get_setting_info(name: str) -> {
|
||||||
-- maximum value
|
-- maximum value
|
||||||
[only for numeric settings] max: number
|
[only for numeric settings] max: number
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
Returns a table with information about a setting. Throws an exception if the setting does not exist.
|
-- Brings the window to front and sets input focus.
|
||||||
|
|
||||||
```lua
|
|
||||||
app.focus()
|
app.focus()
|
||||||
```
|
```
|
||||||
|
|
||||||
Brings the window to front and sets input focus.
|
## Paths and entry points
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
-- Creates an in-memory filesystem.
|
||||||
app.create_memory_device(
|
app.create_memory_device(
|
||||||
-- entry-point name
|
-- entry-point name
|
||||||
name: str
|
name: str
|
||||||
)
|
)
|
||||||
```
|
|
||||||
|
|
||||||
Creates an in-memory filesystem.
|
-- Returns a list of content sources (paths), in descending priority order.
|
||||||
|
|
||||||
```lua
|
|
||||||
app.get_content_sources() -> table<string>
|
app.get_content_sources() -> table<string>
|
||||||
```
|
|
||||||
|
|
||||||
Returns a list of content sources (paths), in descending priority order.
|
-- Sets a list of content sources (paths). Specified in descending priority order.
|
||||||
|
|
||||||
```lua
|
|
||||||
app.set_content_sources(sources: table<string>)
|
app.set_content_sources(sources: table<string>)
|
||||||
```
|
|
||||||
|
|
||||||
Sets a list of content sources (paths). Specified in descending priority order.
|
-- Resets content sources.
|
||||||
|
|
||||||
```lua
|
|
||||||
app.reset_content_sources()
|
app.reset_content_sources()
|
||||||
```
|
```
|
||||||
|
|
||||||
Resets content sources.
|
|
||||||
|
|
||||||
## Sub-instances
|
## Sub-instances
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
|
@ -209,5 +180,5 @@ app.is_instance_alive(handle: int) -> boolean
|
||||||
|
|
||||||
-- Stops the engine sub-instance.
|
-- Stops the engine sub-instance.
|
||||||
-- Returns true if the instance was alive at the time of the call.
|
-- Returns true if the instance was alive at the time of the call.
|
||||||
app.terminate(handle: int) -> boolean
|
app.terminate_instance(handle: int) -> boolean
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ time.delta() -> number
|
||||||
-- Returns UTC time in seconds
|
-- Returns UTC time in seconds
|
||||||
time.utc_time() -> int
|
time.utc_time() -> int
|
||||||
|
|
||||||
|
-- Returns UTC time in seconds with millisecond precision
|
||||||
|
time.precise_utc_time() -> number
|
||||||
|
|
||||||
-- Returns local (system) time in seconds
|
-- Returns local (system) time in seconds
|
||||||
time.local_time() -> int
|
time.local_time() -> int
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ app.sleep(time: number)
|
||||||
-- Завершает выполнение движка, выводя стек вызовов для ослеживания места вызова функции.
|
-- Завершает выполнение движка, выводя стек вызовов для ослеживания места вызова функции.
|
||||||
app.quit()
|
app.quit()
|
||||||
|
|
||||||
-- Ожидает истинности утверждения (условия), проверяемого функцией, выполняя основной цикл движка.
|
-- Ожидает истинности утверждения (условия), проверяемого функцией,
|
||||||
|
-- выполняя основной цикл движка.
|
||||||
app.sleep_until(
|
app.sleep_until(
|
||||||
-- функция, проверяющее условия завершения ожидания
|
-- функция, проверяющее условия завершения ожидания
|
||||||
predicate: function() -> boolean,
|
predicate: function() -> boolean,
|
||||||
|
|
@ -46,7 +47,11 @@ app.sleep_until(
|
||||||
-- Проверяет, загружен ли контент.
|
-- Проверяет, загружен ли контент.
|
||||||
app.is_content_loaded() -> boolean
|
app.is_content_loaded() -> boolean
|
||||||
|
|
||||||
-- Загружает контент из конфига, нельзя использовать, если контент уже загружен
|
-- Возвращает текущую конфигурацию контента (список id паков в порядке загрузки)
|
||||||
|
app.get_content() -> table<string>
|
||||||
|
|
||||||
|
-- Загружает контент на основе текущей конфигурации.
|
||||||
|
-- Не может быть использован, если контент уже загружен (см. app.reset_content).
|
||||||
app.load_content()
|
app.load_content()
|
||||||
|
|
||||||
-- Выгружает весь контент, сбрасывая до единственного пака ядра (`core`).
|
-- Выгружает весь контент, сбрасывая до единственного пака ядра (`core`).
|
||||||
|
|
@ -56,7 +61,7 @@ app.reset_content(
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Обновляет конфигурацию паков, проверяя её корректность (зависимости и доступность паков).
|
-- Обновляет конфигурацию паков, проверяя её корректность (зависимости и доступность паков).
|
||||||
-- Автоматически добавляет зависимости.
|
-- Автоматически добавляет и упорядочивает паки в соответствии с зависимостями.
|
||||||
-- Для удаления ВСЕХ паков из конфигурации можно использовать `pack.get_installed()`
|
-- Для удаления ВСЕХ паков из конфигурации можно использовать `pack.get_installed()`
|
||||||
app.reconfig_packs(
|
app.reconfig_packs(
|
||||||
-- добавляемые паки
|
-- добавляемые паки
|
||||||
|
|
@ -107,19 +112,22 @@ app.close_world(
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Свойства и настройки движка
|
## Свойства и настройки движка
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
-- Возвращает мажорную и минорную версии движка.
|
-- Возвращает мажорную и минорную версии движка.
|
||||||
app.get_version() -> int, int
|
app.get_version() -> int, int
|
||||||
|
|
||||||
-- Возвращает значение настройки. Бросает исключение, если настройки не существует.
|
-- Возвращает значение настройки.
|
||||||
|
-- Бросает исключение, если настройки не существует.
|
||||||
app.get_setting(name: string) -> any
|
app.get_setting(name: string) -> any
|
||||||
|
|
||||||
-- Устанавливает значение настройки. Бросает исключение, если настройки не существует.
|
-- Устанавливает значение настройки.
|
||||||
|
-- Бросает исключение, если настройки не существует.
|
||||||
app.set_setting(name: string, value: any)
|
app.set_setting(name: string, value: any)
|
||||||
|
|
||||||
-- Возвращает таблицу с информацией о настройке. Бросает исключение, если настройки не существует.
|
-- Возвращает таблицу с информацией о настройке.
|
||||||
|
-- Бросает исключение, если настройки не существует.
|
||||||
app.get_setting_info(name: string) -> table
|
app.get_setting_info(name: string) -> table
|
||||||
|
|
||||||
-- Переводит окно на передний план и устанавливает фокус ввода.
|
-- Переводит окно на передний план и устанавливает фокус ввода.
|
||||||
|
|
@ -127,6 +135,7 @@ app.focus()
|
||||||
```
|
```
|
||||||
|
|
||||||
## Точки входа и пути
|
## Точки входа и пути
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
-- Создаёт файловую систему в памяти.
|
-- Создаёт файловую систему в памяти.
|
||||||
app.create_memory_device(
|
app.create_memory_device(
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,18 @@
|
||||||
# Библиотека *time*
|
# Библиотека *time*
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
-- Возвращает время с момента запуска движка в секундах и милисекундах.
|
-- Возвращает время с момента запуска движка в секундах и миллисекундах.
|
||||||
time.uptime() -> number
|
time.uptime() -> number
|
||||||
|
|
||||||
-- Возвращает дельту времени в секундах и милисекундах (время прошедшее с предыдущего кадра)
|
-- Возвращает дельту времени в секундах и миллисекундах (время прошедшее с предыдущего кадра)
|
||||||
time.delta() -> number
|
time.delta() -> number
|
||||||
|
|
||||||
-- Возвращает время UTC в секундах
|
-- Возвращает время UTC (секунды с 1970-01-01 UTC)
|
||||||
time.utc_time() -> int
|
time.utc_time() -> int
|
||||||
|
|
||||||
|
-- Возвращает время UTC (секунды с 1970-01-01 UTC) с точностью до миллисекунд
|
||||||
|
time.precise_utc_time() -> number
|
||||||
|
|
||||||
-- Возвращает локальное (системное) время в секундах
|
-- Возвращает локальное (системное) время в секундах
|
||||||
time.local_time() -> int
|
time.local_time() -> int
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,14 @@ function update_checkbox_setting(id, value)
|
||||||
document.input_device_select.enabled = recording_enabled
|
document.input_device_select.enabled = recording_enabled
|
||||||
document.input_volume_inner.enabled = recording_enabled
|
document.input_volume_inner.enabled = recording_enabled
|
||||||
document.input_volume_outer.enabled = recording_enabled
|
document.input_volume_outer.enabled = recording_enabled
|
||||||
|
|
||||||
|
local selectbox = document.input_device_select
|
||||||
|
local info = audio.input.get_input_info()
|
||||||
|
if info then
|
||||||
|
selectbox.value = info.device_specifier
|
||||||
|
else
|
||||||
|
selectbox.value = app.get_setting("audio.input-device")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function create_checkbox(id, name, tooltip)
|
function create_checkbox(id, name, tooltip)
|
||||||
|
|
@ -84,6 +92,7 @@ function on_open()
|
||||||
table.insert(devices, {value=name, text=name})
|
table.insert(devices, {value=name, text=name})
|
||||||
end
|
end
|
||||||
selectbox.options = devices
|
selectbox.options = devices
|
||||||
|
|
||||||
local info = audio.input.get_input_info()
|
local info = audio.input.get_input_info()
|
||||||
if info then
|
if info then
|
||||||
selectbox.value = info.device_specifier
|
selectbox.value = info.device_specifier
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
local app = __vc_app
|
||||||
|
local internals = __vc_internals
|
||||||
|
|
||||||
local user_props = file.read_combined_object("config/user-props.toml")
|
local user_props = file.read_combined_object("config/user-props.toml")
|
||||||
local names = {
|
local names = {
|
||||||
"parent", "caption", "texture", "texture-faces", "model", "model-name",
|
"parent", "caption", "texture", "texture-faces", "model", "model-name",
|
||||||
|
|
@ -85,3 +88,33 @@ cache_names(block)
|
||||||
cache_names(item)
|
cache_names(item)
|
||||||
|
|
||||||
__vc_scripts_registry.build_registry()
|
__vc_scripts_registry.build_registry()
|
||||||
|
|
||||||
|
local packs = app.get_content()
|
||||||
|
table.insert(packs, 1, "core")
|
||||||
|
|
||||||
|
for i, packid in ipairs(packs) do
|
||||||
|
local loaders_dir = packid..":scripts/loaders"
|
||||||
|
if not file.isdir(loaders_dir) then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
local files = file.list(loaders_dir)
|
||||||
|
for _, path in ipairs(files) do
|
||||||
|
if file.ext(path) == "json" then
|
||||||
|
debug.log("registering loader "..path)
|
||||||
|
local dto = json.parse(file.read(path))
|
||||||
|
local module = setmetatable({}, {__index=internals.get_pack_env(packid)})
|
||||||
|
local module_path = file.join(file.parent(path), file.stem(path)..".lua")
|
||||||
|
if not file.exists(module_path) then
|
||||||
|
error("loader "..path.." missing module "..module_path)
|
||||||
|
end
|
||||||
|
load(file.read(module_path), module_path, "t", module)()
|
||||||
|
if rawget(module, "execute") == nil then
|
||||||
|
error("loader "..path.." missing function 'execute'")
|
||||||
|
end
|
||||||
|
if dto.type == "compiler" then
|
||||||
|
internals.register_compiler(packid, dto.extensions, module)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
|
|
||||||
|
|
@ -392,6 +392,7 @@ end
|
||||||
|
|
||||||
ffi = nil
|
ffi = nil
|
||||||
__vc_app = nil
|
__vc_app = nil
|
||||||
|
__vc_internals = nil
|
||||||
__vc_lock_internal_modules()
|
__vc_lock_internal_modules()
|
||||||
__vc_lock_internal_modules = nil
|
__vc_lock_internal_modules = nil
|
||||||
__vc_update_coroutines = nil
|
__vc_update_coroutines = nil
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,20 @@ package = {
|
||||||
}
|
}
|
||||||
local __cached_scripts = {}
|
local __cached_scripts = {}
|
||||||
local __warnings_hidden = {}
|
local __warnings_hidden = {}
|
||||||
|
local __compilers = {}
|
||||||
|
|
||||||
|
function __vc_internals.register_compiler(sourcepack, extensions, module)
|
||||||
|
local compiler = {
|
||||||
|
packid = sourcepack,
|
||||||
|
extensions = extensions,
|
||||||
|
module = module,
|
||||||
|
}
|
||||||
|
for i, ext in ipairs(extensions) do
|
||||||
|
if not __compilers[ext] then
|
||||||
|
__compilers[ext] = compiler
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function on_deprecated_call(name, alternatives)
|
function on_deprecated_call(name, alternatives)
|
||||||
if __warnings_hidden[name] then
|
if __warnings_hidden[name] then
|
||||||
|
|
@ -200,6 +214,21 @@ end
|
||||||
|
|
||||||
local __internal_locked = false
|
local __internal_locked = false
|
||||||
|
|
||||||
|
local default_compiler = {
|
||||||
|
module = {
|
||||||
|
execute = function(code, path, env)
|
||||||
|
local script, err = load(code, path)
|
||||||
|
if script == nil then
|
||||||
|
error(err)
|
||||||
|
end
|
||||||
|
if env then
|
||||||
|
script = setfenv(script, env)
|
||||||
|
end
|
||||||
|
return script
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
-- Load script with caching
|
-- Load script with caching
|
||||||
--
|
--
|
||||||
-- path - script path `contentpack:filename`.
|
-- path - script path `contentpack:filename`.
|
||||||
|
|
@ -211,6 +240,9 @@ function __load_script(path, nocache, env)
|
||||||
local is_internal = (packname == "res" or packname == "core")
|
local is_internal = (packname == "res" or packname == "core")
|
||||||
and filename:find("modules/internal") == 1
|
and filename:find("modules/internal") == 1
|
||||||
|
|
||||||
|
local ext = path:match("%.([^:/\\]+)$")
|
||||||
|
local compiler = __compilers[ext] or default_compiler
|
||||||
|
|
||||||
nocache = nocache or is_internal
|
nocache = nocache or is_internal
|
||||||
|
|
||||||
if is_internal and __internal_locked then
|
if is_internal and __internal_locked then
|
||||||
|
|
@ -225,13 +257,7 @@ function __load_script(path, nocache, env)
|
||||||
error("script '"..filename.."' not found in '"..packname.."'")
|
error("script '"..filename.."' not found in '"..packname.."'")
|
||||||
end
|
end
|
||||||
|
|
||||||
local script, err = load(file.read(path), path)
|
local script = compiler.module.execute(file.read(path), path, env)
|
||||||
if script == nil then
|
|
||||||
error(err)
|
|
||||||
end
|
|
||||||
if env then
|
|
||||||
script = setfenv(script, env)
|
|
||||||
end
|
|
||||||
local result = script()
|
local result = script()
|
||||||
if not nocache then
|
if not nocache then
|
||||||
__cached_scripts[path] = script
|
__cached_scripts[path] = script
|
||||||
|
|
@ -245,6 +271,9 @@ function __vc_lock_internal_modules()
|
||||||
end
|
end
|
||||||
|
|
||||||
local __pack_envs = __vc__pack_envs
|
local __pack_envs = __vc__pack_envs
|
||||||
|
function __vc_internals.get_pack_env(packid)
|
||||||
|
return __pack_envs[packid]
|
||||||
|
end
|
||||||
__vc__pack_envs = nil
|
__vc__pack_envs = nil
|
||||||
|
|
||||||
function require(path)
|
function require(path)
|
||||||
|
|
@ -277,6 +306,13 @@ function __scripts_cleanup(non_reset_packs)
|
||||||
__pack_envs[packname] = nil
|
__pack_envs[packname] = nil
|
||||||
::continue::
|
::continue::
|
||||||
end
|
end
|
||||||
|
for ext, compiler in pairs(__compilers) do
|
||||||
|
if table.has(non_reset_packs, compiler.packid) then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
__compilers[ext] = nil
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function __vc__error(msg, frame, n, lastn)
|
function __vc__error(msg, frame, n, lastn)
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,10 @@ void AssetsLoader::add(
|
||||||
AssetType tag,
|
AssetType tag,
|
||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const std::string& alias,
|
const std::string& alias,
|
||||||
std::shared_ptr<AssetCfg> settings
|
std::shared_ptr<AssetCfg> settings,
|
||||||
|
bool overwrite
|
||||||
) {
|
) {
|
||||||
if (enqueued.find({tag, alias}) != enqueued.end()){
|
if (!overwrite && enqueued.find({tag, alias}) != enqueued.end()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entries.push(aloader_entry {tag, filename, alias, std::move(settings)});
|
entries.push(aloader_entry {tag, filename, alias, std::move(settings)});
|
||||||
|
|
@ -154,11 +155,12 @@ void AssetsLoader::processPreload(
|
||||||
std::string defFolder = assets_def_folder(tag);
|
std::string defFolder = assets_def_folder(tag);
|
||||||
std::string path = defFolder + "/" + name;
|
std::string path = defFolder + "/" + name;
|
||||||
if (map == nullptr) {
|
if (map == nullptr) {
|
||||||
add(tag, path, name);
|
add(tag, path, name, nullptr, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::shared_ptr<AssetCfg> config = nullptr;
|
std::shared_ptr<AssetCfg> config = nullptr;
|
||||||
map.at("path").get(path);
|
map.at("path").get(path);
|
||||||
|
logger.debug() << "processing preload " << util::quote(name) << " path: " << util::quote(path);
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case AssetType::SOUND: {
|
case AssetType::SOUND: {
|
||||||
bool keepPCM = false;
|
bool keepPCM = false;
|
||||||
|
|
@ -196,7 +198,7 @@ void AssetsLoader::processPreload(
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
add(tag, path, name, std::move(config));
|
add(tag, path, name, std::move(config), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetsLoader::processPreloadList(AssetType tag, const dv::value& list) {
|
void AssetsLoader::processPreloadList(AssetType tag, const dv::value& list) {
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,8 @@ public:
|
||||||
AssetType tag,
|
AssetType tag,
|
||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const std::string& alias,
|
const std::string& alias,
|
||||||
std::shared_ptr<AssetCfg> settings = nullptr
|
std::shared_ptr<AssetCfg> settings = nullptr,
|
||||||
|
bool overwrite = false
|
||||||
);
|
);
|
||||||
|
|
||||||
bool hasNext() const;
|
bool hasNext() const;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "debug/Logger.hpp"
|
#include "debug/Logger.hpp"
|
||||||
#include "alutil.hpp"
|
#include "alutil.hpp"
|
||||||
|
#include "util/stringutil.hpp"
|
||||||
#include "../MemoryPCMStream.hpp"
|
#include "../MemoryPCMStream.hpp"
|
||||||
|
|
||||||
static debug::Logger logger("al-audio");
|
static debug::Logger logger("al-audio");
|
||||||
|
|
@ -99,6 +100,8 @@ ALInputDevice::ALInputDevice(
|
||||||
|
|
||||||
if (deviceName) {
|
if (deviceName) {
|
||||||
deviceSpecifier = std::string(deviceName);
|
deviceSpecifier = std::string(deviceName);
|
||||||
|
logger.info() << "created input device with specifier "
|
||||||
|
<< util::quote(deviceSpecifier);
|
||||||
} else {
|
} else {
|
||||||
logger.warning() << "could not retrieve input device specifier";
|
logger.warning() << "could not retrieve input device specifier";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -211,12 +211,15 @@ void audio::initialize(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
logger.info() << "recording enabled; input device is "
|
const auto& targetDevice = settings.inputDevice.get();
|
||||||
<< settings.inputDevice.get();
|
logger.info() << "recording enabled; target input device is "
|
||||||
|
<< (targetDevice.empty() ? "not specified"
|
||||||
|
: targetDevice);
|
||||||
::input_device = backend->openInputDevice(
|
::input_device = backend->openInputDevice(
|
||||||
settings.inputDevice.get(), 44100, 1, 16
|
settings.inputDevice.get(), 44100, 1, 16
|
||||||
);
|
);
|
||||||
if (::input_device != nullptr) {
|
if (::input_device != nullptr) {
|
||||||
|
logger.error() << "could not create input device";
|
||||||
::input_device->startCapture();
|
::input_device->startCapture();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -78,9 +78,10 @@ void Panel::refresh() {
|
||||||
glm::vec2 size = getSize();
|
glm::vec2 size = getSize();
|
||||||
if (orientation == Orientation::VERTICAL) {
|
if (orientation == Orientation::VERTICAL) {
|
||||||
float maxw = size.x;
|
float maxw = size.x;
|
||||||
for (auto& node : nodes) {
|
for (size_t i = 0; i < nodes.size(); i++) {
|
||||||
|
const auto& node = nodes[i];
|
||||||
const glm::vec4 margin = node->getMargin();
|
const glm::vec4 margin = node->getMargin();
|
||||||
y += margin.y;
|
y += margin.y + (i > 0 ? interval : 0);
|
||||||
|
|
||||||
float ex = x + margin.x;
|
float ex = x + margin.x;
|
||||||
node->setPos(glm::vec2(ex, y));
|
node->setPos(glm::vec2(ex, y));
|
||||||
|
|
@ -94,16 +95,17 @@ void Panel::refresh() {
|
||||||
}
|
}
|
||||||
node->refresh();
|
node->refresh();
|
||||||
glm::vec2 nodeSize = node->getSize();
|
glm::vec2 nodeSize = node->getSize();
|
||||||
y += nodeSize.y + margin.w + interval;
|
y += nodeSize.y + margin.w;
|
||||||
maxw = fmax(maxw, ex + nodeSize.x + margin.z + padding.z);
|
maxw = fmax(maxw, ex + nodeSize.x + margin.z + padding.z);
|
||||||
}
|
}
|
||||||
actualLengthX = size.x;
|
actualLengthX = size.x;
|
||||||
actualLengthY = y + padding.w;
|
actualLengthY = y + padding.w;
|
||||||
} else {
|
} else {
|
||||||
float maxh = size.y;
|
float maxh = size.y;
|
||||||
for (auto& node : nodes) {
|
for (size_t i = 0; i < nodes.size(); i++) {
|
||||||
|
const auto& node = nodes[i];
|
||||||
const glm::vec4 margin = node->getMargin();
|
const glm::vec4 margin = node->getMargin();
|
||||||
x += margin.x;
|
x += margin.x + (i > 0 ? interval : 0);
|
||||||
|
|
||||||
float ey = y + margin.y;
|
float ey = y + margin.y;
|
||||||
node->setPos(glm::vec2(x, ey));
|
node->setPos(glm::vec2(x, ey));
|
||||||
|
|
@ -117,7 +119,7 @@ void Panel::refresh() {
|
||||||
}
|
}
|
||||||
node->refresh();
|
node->refresh();
|
||||||
glm::vec2 nodesize = node->getSize();
|
glm::vec2 nodesize = node->getSize();
|
||||||
x += nodesize.x + margin.z + interval;
|
x += nodesize.x + margin.z;
|
||||||
maxh = fmax(maxh, ey + nodesize.y + margin.w + padding.w);
|
maxh = fmax(maxh, ey + nodesize.y + margin.w + padding.w);
|
||||||
}
|
}
|
||||||
actualLengthY = size.y;
|
actualLengthY = size.y;
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,17 @@ static int l_reconfig_packs(lua::State* L) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Get current content packs configuration
|
||||||
|
static int l_get_content(lua::State* L) {
|
||||||
|
const auto& configuration = content_control->getContentPacks();
|
||||||
|
lua::createtable(L, configuration.size(), 0);
|
||||||
|
for (int i = 0; i < configuration.size(); i++) {
|
||||||
|
lua::pushlstring(L, configuration[i].id);
|
||||||
|
lua::rawseti(L, i + 1);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Get content sources list
|
/// @brief Get content sources list
|
||||||
static int l_get_content_sources(lua::State* L) {
|
static int l_get_content_sources(lua::State* L) {
|
||||||
const auto& sources = engine->getContentControl().getContentSources();
|
const auto& sources = engine->getContentControl().getContentSources();
|
||||||
|
|
@ -453,6 +464,7 @@ const luaL_Reg applib[] = {
|
||||||
{"load_content", lua::wrap<l_load_content>},
|
{"load_content", lua::wrap<l_load_content>},
|
||||||
{"reset_content", lua::wrap<l_reset_content>},
|
{"reset_content", lua::wrap<l_reset_content>},
|
||||||
{"reconfig_packs", lua::wrap<l_reconfig_packs>},
|
{"reconfig_packs", lua::wrap<l_reconfig_packs>},
|
||||||
|
{"get_content", lua::wrap<l_get_content>},
|
||||||
{"get_content_sources", lua::wrap<l_get_content_sources>},
|
{"get_content_sources", lua::wrap<l_get_content_sources>},
|
||||||
{"set_content_sources", lua::wrap<l_set_content_sources>},
|
{"set_content_sources", lua::wrap<l_set_content_sources>},
|
||||||
{"reset_content_sources", lua::wrap<l_reset_content_sources>},
|
{"reset_content_sources", lua::wrap<l_reset_content_sources>},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "engine/Engine.hpp"
|
|
||||||
#include "api_lua.hpp"
|
#include "api_lua.hpp"
|
||||||
|
#include "engine/Engine.hpp"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
using namespace scripting;
|
using namespace scripting;
|
||||||
|
|
@ -20,11 +21,18 @@ static int l_utc_time(lua::State* L) {
|
||||||
return lua::pushnumber(L, std::time(nullptr));
|
return lua::pushnumber(L, std::time(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_precise_utc_time(lua::State* L) {
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
return lua::pushnumber(
|
||||||
|
L, std::chrono::duration<double>(now.time_since_epoch()).count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static int l_local_time(lua::State* L) {
|
static int l_local_time(lua::State* L) {
|
||||||
std::time_t t = std::time(nullptr);
|
std::time_t t = std::time(nullptr);
|
||||||
|
|
||||||
std::tm gmt_tm{};
|
std::tm gmt_tm {};
|
||||||
std::tm local_tm{};
|
std::tm local_tm {};
|
||||||
|
|
||||||
#if defined(USE_MSVC_TIME_SAFE)
|
#if defined(USE_MSVC_TIME_SAFE)
|
||||||
gmtime_s(&gmt_tm, &t);
|
gmtime_s(&gmt_tm, &t);
|
||||||
|
|
@ -44,8 +52,8 @@ static int l_local_time(lua::State* L) {
|
||||||
static int l_utc_offset(lua::State* L) {
|
static int l_utc_offset(lua::State* L) {
|
||||||
std::time_t t = std::time(nullptr);
|
std::time_t t = std::time(nullptr);
|
||||||
|
|
||||||
std::tm gmt_tm{};
|
std::tm gmt_tm {};
|
||||||
std::tm local_tm{};
|
std::tm local_tm {};
|
||||||
|
|
||||||
#if defined(USE_MSVC_TIME_SAFE)
|
#if defined(USE_MSVC_TIME_SAFE)
|
||||||
gmtime_s(&gmt_tm, &t);
|
gmtime_s(&gmt_tm, &t);
|
||||||
|
|
@ -74,6 +82,7 @@ const luaL_Reg timelib[] = {
|
||||||
{"uptime", lua::wrap<l_uptime>},
|
{"uptime", lua::wrap<l_uptime>},
|
||||||
{"delta", lua::wrap<l_delta>},
|
{"delta", lua::wrap<l_delta>},
|
||||||
{"utc_time", lua::wrap<l_utc_time>},
|
{"utc_time", lua::wrap<l_utc_time>},
|
||||||
|
{"precise_utc_time", lua::wrap<l_precise_utc_time>},
|
||||||
{"utc_offset", lua::wrap<l_utc_offset>},
|
{"utc_offset", lua::wrap<l_utc_offset>},
|
||||||
{"local_time", lua::wrap<l_local_time>},
|
{"local_time", lua::wrap<l_local_time>},
|
||||||
{"precise_time", lua::wrap<l_precise_time>},
|
{"precise_time", lua::wrap<l_precise_time>},
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,11 @@ static void create_libs(State* L, StateType stateType) {
|
||||||
getglobal(L, "__vc_app");
|
getglobal(L, "__vc_app");
|
||||||
setregistry(L, "app");
|
setregistry(L, "app");
|
||||||
|
|
||||||
|
createtable(L, 0, 0);
|
||||||
|
pushvalue(L, -1);
|
||||||
|
setglobal(L, "__vc_internals");
|
||||||
|
setregistry(L, "internals");
|
||||||
|
|
||||||
if (stateType == StateType::SCRIPT) {
|
if (stateType == StateType::SCRIPT) {
|
||||||
getregistry(L, "app");
|
getregistry(L, "app");
|
||||||
setglobal(L, "app");
|
setglobal(L, "app");
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,23 @@ void scripting::on_content_load(Content* content) {
|
||||||
lua::setfield(L, "properties");
|
lua::setfield(L, "properties");
|
||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
}
|
}
|
||||||
load_script("post_content.lua", true);
|
|
||||||
|
lua::getregistry(L, "app");
|
||||||
|
lua::setglobal(L, "__vc_app");
|
||||||
|
lua::getregistry(L, "internals");
|
||||||
|
lua::setglobal(L, "__vc_internals");
|
||||||
|
try {
|
||||||
|
load_script("post_content.lua", true);
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
lua::pushnil(L);
|
||||||
|
lua::setglobal(L, "__vc_app");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
lua::pushnil(L);
|
||||||
|
lua::setglobal(L, "__vc_app");
|
||||||
|
lua::pushnil(L);
|
||||||
|
lua::setglobal(L, "__vc_internals");
|
||||||
|
|
||||||
load_script("stdcmd.lua", true);
|
load_script("stdcmd.lua", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ struct AudioSettings {
|
||||||
NumberSetting volumeAmbient {1.0f, 0.0f, 1.0f, setting_format::percent};
|
NumberSetting volumeAmbient {1.0f, 0.0f, 1.0f, setting_format::percent};
|
||||||
NumberSetting volumeMusic {1.0f, 0.0f, 1.0f, setting_format::percent};
|
NumberSetting volumeMusic {1.0f, 0.0f, 1.0f, setting_format::percent};
|
||||||
|
|
||||||
StringSetting inputDevice {"auto"};
|
StringSetting inputDevice {""};
|
||||||
|
|
||||||
FlagSetting acousticEffects {true};
|
FlagSetting acousticEffects {true};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue