Merge branch 'main' into release-0.26
This commit is contained in:
commit
981b4a22b5
@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
To work with the command interpreter, use the **console** library.
|
To work with the command interpreter, use the **console** library.
|
||||||
|
|
||||||
|
When sending a command via the standard console (core:console layout):
|
||||||
|
1. the `allow-cheats` rule is checked
|
||||||
|
2. the `player`, `pos.x|y|z`, `entity.id`, `entity.selected` variables are automatically set.
|
||||||
|
3. the command handler is called - console.submit or the default one.
|
||||||
|
|
||||||
|
The default handler calls console.execute, passing the result to the console.log call.
|
||||||
|
|
||||||
## Commands creation
|
## Commands creation
|
||||||
|
|
||||||
To create a console command, use the following function:
|
To create a console command, use the following function:
|
||||||
|
|||||||
@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
Для работы с командным интерпретатором предоставляется библиотека **console**.
|
Для работы с командным интерпретатором предоставляется библиотека **console**.
|
||||||
|
|
||||||
|
При отправке команды через стандартную консоль (макет core:console):
|
||||||
|
1. проверяется правило `allow-cheats`
|
||||||
|
2. автоматически устанавливаются переменные `player`, `pos.x|y|z`, `entity.id`, `entity.selected`.
|
||||||
|
3. вызывается обработчик команд - console.submit или по-умолчанию.
|
||||||
|
|
||||||
|
Обработчик по-умолчанию вызывает console.execute, передавая результат в вызов console.log.
|
||||||
|
|
||||||
## Создание команд
|
## Создание команд
|
||||||
|
|
||||||
Для создания команды консоли используется следующая функция:
|
Для создания команды консоли используется следующая функция:
|
||||||
|
|||||||
@ -97,11 +97,12 @@ end)
|
|||||||
function setup_variables()
|
function setup_variables()
|
||||||
local pid = hud.get_player()
|
local pid = hud.get_player()
|
||||||
local x,y,z = player.get_pos(pid)
|
local x,y,z = player.get_pos(pid)
|
||||||
|
console.set("player", pid)
|
||||||
console.set('pos.x', x)
|
console.set('pos.x', x)
|
||||||
console.set('pos.y', y)
|
console.set('pos.y', y)
|
||||||
console.set('pos.z', z)
|
console.set('pos.z', z)
|
||||||
local pentity = player.get_entity(pid)
|
local pentity = player.get_entity(pid)
|
||||||
if pentity ~= 0 then
|
if pentity > 0 then
|
||||||
console.set('entity.id', pentity)
|
console.set('entity.id', pentity)
|
||||||
end
|
end
|
||||||
local sentity = player.get_selected_entity(pid)
|
local sentity = player.get_selected_entity(pid)
|
||||||
@ -148,8 +149,6 @@ function submit(text)
|
|||||||
text = text:sub(2)
|
text = text:sub(2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
setup_variables()
|
|
||||||
|
|
||||||
local name
|
local name
|
||||||
for s in text:gmatch("%S+") do
|
for s in text:gmatch("%S+") do
|
||||||
@ -167,12 +166,19 @@ function submit(text)
|
|||||||
end
|
end
|
||||||
|
|
||||||
document.log.caret = -1
|
document.log.caret = -1
|
||||||
local status, result = pcall(console.execute, text)
|
|
||||||
if result then
|
|
||||||
console.log(result)
|
|
||||||
end
|
|
||||||
document.prompt.text = ""
|
document.prompt.text = ""
|
||||||
document.prompt.focused = true
|
document.prompt.focused = true
|
||||||
|
|
||||||
|
setup_variables()
|
||||||
|
|
||||||
|
if console.submit then
|
||||||
|
console.submit(text)
|
||||||
|
else
|
||||||
|
local status, result = pcall(console.execute, text)
|
||||||
|
if result then
|
||||||
|
console.log(result)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function set_mode(mode)
|
function set_mode(mode)
|
||||||
|
|||||||
@ -9,19 +9,21 @@
|
|||||||
#include "AL/ALAudio.hpp"
|
#include "AL/ALAudio.hpp"
|
||||||
#include "NoAudio.hpp"
|
#include "NoAudio.hpp"
|
||||||
#include "debug/Logger.hpp"
|
#include "debug/Logger.hpp"
|
||||||
|
#include "util/ObjectsKeeper.hpp"
|
||||||
|
|
||||||
static debug::Logger logger("audio");
|
static debug::Logger logger("audio");
|
||||||
|
|
||||||
namespace audio {
|
using namespace audio;
|
||||||
|
|
||||||
|
namespace {
|
||||||
static speakerid_t nextId = 1;
|
static speakerid_t nextId = 1;
|
||||||
static Backend* backend;
|
static Backend* backend;
|
||||||
static std::unordered_map<speakerid_t, std::unique_ptr<Speaker>> speakers;
|
static std::unordered_map<speakerid_t, std::unique_ptr<Speaker>> speakers;
|
||||||
static std::unordered_map<speakerid_t, std::shared_ptr<Stream>> streams;
|
static std::unordered_map<speakerid_t, std::shared_ptr<Stream>> streams;
|
||||||
static std::vector<std::unique_ptr<Channel>> channels;
|
static std::vector<std::unique_ptr<Channel>> channels;
|
||||||
|
static util::ObjectsKeeper objects_keeper {};
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace audio;
|
|
||||||
|
|
||||||
Channel::Channel(std::string name) : name(std::move(name)) {
|
Channel::Channel(std::string name) : name(std::move(name)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +150,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void audio::initialize(bool enabled) {
|
void audio::initialize(bool enabled, AudioSettings& settings) {
|
||||||
|
enabled = enabled && settings.enabled.get();
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
logger.info() << "initializing ALAudio backend";
|
logger.info() << "initializing ALAudio backend";
|
||||||
backend = ALAudio::create().release();
|
backend = ALAudio::create().release();
|
||||||
@ -160,7 +163,22 @@ void audio::initialize(bool enabled) {
|
|||||||
logger.info() << "initializing NoAudio backend";
|
logger.info() << "initializing NoAudio backend";
|
||||||
backend = NoAudio::create().release();
|
backend = NoAudio::create().release();
|
||||||
}
|
}
|
||||||
create_channel("master");
|
struct {
|
||||||
|
std::string name;
|
||||||
|
NumberSetting* setting;
|
||||||
|
} builtin_channels[] {
|
||||||
|
{"master", &settings.volumeMaster},
|
||||||
|
{"regular", &settings.volumeRegular},
|
||||||
|
{"music", &settings.volumeMusic},
|
||||||
|
{"ambient", &settings.volumeAmbient},
|
||||||
|
{"ui", &settings.volumeUI}
|
||||||
|
};
|
||||||
|
for (auto& channel : builtin_channels) {
|
||||||
|
create_channel(channel.name);
|
||||||
|
objects_keeper.keepAlive(channel.setting->observe([=](auto value) {
|
||||||
|
audio::get_channel(channel.name)->setVolume(value * value);
|
||||||
|
}, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<PCM> audio::load_PCM(const fs::path& file, bool headerOnly) {
|
std::unique_ptr<PCM> audio::load_PCM(const fs::path& file, bool headerOnly) {
|
||||||
@ -442,4 +460,5 @@ void audio::close() {
|
|||||||
speakers.clear();
|
speakers.clear();
|
||||||
delete backend;
|
delete backend;
|
||||||
backend = nullptr;
|
backend = nullptr;
|
||||||
|
objects_keeper.clearKeepedObjects();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
|
#include "settings.hpp"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
@ -357,7 +358,7 @@ namespace audio {
|
|||||||
|
|
||||||
/// @brief Initialize audio system or use no audio mode
|
/// @brief Initialize audio system or use no audio mode
|
||||||
/// @param enabled try to initialize actual audio
|
/// @param enabled try to initialize actual audio
|
||||||
void initialize(bool enabled);
|
void initialize(bool enabled, AudioSettings& settings);
|
||||||
|
|
||||||
/// @brief Load audio file info and PCM data
|
/// @brief Load audio file info and PCM data
|
||||||
/// @param file audio file
|
/// @param file audio file
|
||||||
|
|||||||
@ -52,15 +52,6 @@ static debug::Logger logger("engine");
|
|||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
static void create_channel(Engine* engine, std::string name, NumberSetting& setting) {
|
|
||||||
if (name != "master") {
|
|
||||||
audio::create_channel(name);
|
|
||||||
}
|
|
||||||
engine->keepAlive(setting.observe([=](auto value) {
|
|
||||||
audio::get_channel(name)->setVolume(value*value);
|
|
||||||
}, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::unique_ptr<ImageData> load_icon(const fs::path& resdir) {
|
static std::unique_ptr<ImageData> load_icon(const fs::path& resdir) {
|
||||||
try {
|
try {
|
||||||
auto file = resdir / fs::u8path("textures/misc/icon.png");
|
auto file = resdir / fs::u8path("textures/misc/icon.png");
|
||||||
@ -73,12 +64,23 @@ static std::unique_ptr<ImageData> load_icon(const fs::path& resdir) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::Engine(CoreParameters coreParameters)
|
Engine::Engine() = default;
|
||||||
: params(std::move(coreParameters)),
|
|
||||||
settings(),
|
static std::unique_ptr<Engine> engine;
|
||||||
settingsHandler({settings}),
|
|
||||||
interpreter(std::make_unique<cmd::CommandsInterpreter>()),
|
Engine& Engine::getInstance() {
|
||||||
network(network::Network::create(settings.network)) {
|
if (!engine) {
|
||||||
|
engine = std::make_unique<Engine>();
|
||||||
|
}
|
||||||
|
return *engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::initialize(CoreParameters coreParameters) {
|
||||||
|
params = std::move(coreParameters);
|
||||||
|
settingsHandler = std::make_unique<SettingsHandler>(settings);
|
||||||
|
interpreter = std::make_unique<cmd::CommandsInterpreter>();
|
||||||
|
network = network::Network::create(settings.network);
|
||||||
|
|
||||||
logger.info() << "engine version: " << ENGINE_VERSION_STRING;
|
logger.info() << "engine version: " << ENGINE_VERSION_STRING;
|
||||||
if (params.headless) {
|
if (params.headless) {
|
||||||
logger.info() << "headless mode is enabled";
|
logger.info() << "headless mode is enabled";
|
||||||
@ -110,12 +112,7 @@ Engine::Engine(CoreParameters coreParameters)
|
|||||||
menus::create_version_label(*this);
|
menus::create_version_label(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
audio::initialize(settings.audio.enabled.get() && !params.headless);
|
audio::initialize(!params.headless, settings.audio);
|
||||||
create_channel(this, "master", settings.audio.volumeMaster);
|
|
||||||
create_channel(this, "regular", settings.audio.volumeRegular);
|
|
||||||
create_channel(this, "music", settings.audio.volumeMusic);
|
|
||||||
create_channel(this, "ambient", settings.audio.volumeAmbient);
|
|
||||||
create_channel(this, "ui", settings.audio.volumeUI);
|
|
||||||
|
|
||||||
bool langNotSet = settings.ui.language.get() == "auto";
|
bool langNotSet = settings.ui.language.get() == "auto";
|
||||||
if (langNotSet) {
|
if (langNotSet) {
|
||||||
@ -140,7 +137,7 @@ void Engine::loadSettings() {
|
|||||||
logger.info() << "loading settings";
|
logger.info() << "loading settings";
|
||||||
std::string text = files::read_string(settings_file);
|
std::string text = files::read_string(settings_file);
|
||||||
try {
|
try {
|
||||||
toml::parse(settingsHandler, settings_file.string(), text);
|
toml::parse(*settingsHandler, settings_file.string(), text);
|
||||||
} catch (const parsing_error& err) {
|
} catch (const parsing_error& err) {
|
||||||
logger.error() << err.errorLog();
|
logger.error() << err.errorLog();
|
||||||
throw;
|
throw;
|
||||||
@ -222,7 +219,7 @@ void Engine::renderFrame() {
|
|||||||
|
|
||||||
void Engine::saveSettings() {
|
void Engine::saveSettings() {
|
||||||
logger.info() << "saving settings";
|
logger.info() << "saving settings";
|
||||||
files::write_string(paths.getSettingsFile(), toml::stringify(settingsHandler));
|
files::write_string(paths.getSettingsFile(), toml::stringify(*settingsHandler));
|
||||||
if (!params.headless) {
|
if (!params.headless) {
|
||||||
logger.info() << "saving bindings";
|
logger.info() << "saving bindings";
|
||||||
files::write_string(paths.getControlsFile(), Events::writeBindings());
|
files::write_string(paths.getControlsFile(), Events::writeBindings());
|
||||||
@ -255,6 +252,10 @@ Engine::~Engine() {
|
|||||||
logger.info() << "engine finished";
|
logger.info() << "engine finished";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::terminate() {
|
||||||
|
engine.reset();
|
||||||
|
}
|
||||||
|
|
||||||
EngineController* Engine::getController() {
|
EngineController* Engine::getController() {
|
||||||
return controller.get();
|
return controller.get();
|
||||||
}
|
}
|
||||||
@ -511,7 +512,7 @@ std::shared_ptr<Screen> Engine::getScreen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsHandler& Engine::getSettingsHandler() {
|
SettingsHandler& Engine::getSettingsHandler() {
|
||||||
return settingsHandler;
|
return *settingsHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
network::Network& Engine::getNetwork() {
|
network::Network& Engine::getNetwork() {
|
||||||
|
|||||||
@ -58,9 +58,9 @@ using OnWorldOpen = std::function<void(std::unique_ptr<Level>, int64_t)>;
|
|||||||
class Engine : public util::ObjectsKeeper {
|
class Engine : public util::ObjectsKeeper {
|
||||||
CoreParameters params;
|
CoreParameters params;
|
||||||
EngineSettings settings;
|
EngineSettings settings;
|
||||||
SettingsHandler settingsHandler;
|
|
||||||
EnginePaths paths;
|
EnginePaths paths;
|
||||||
|
|
||||||
|
std::unique_ptr<SettingsHandler> settingsHandler;
|
||||||
std::unique_ptr<Assets> assets;
|
std::unique_ptr<Assets> assets;
|
||||||
std::shared_ptr<Screen> screen;
|
std::shared_ptr<Screen> screen;
|
||||||
std::vector<ContentPack> contentPacks;
|
std::vector<ContentPack> contentPacks;
|
||||||
@ -82,9 +82,15 @@ class Engine : public util::ObjectsKeeper {
|
|||||||
void updateHotkeys();
|
void updateHotkeys();
|
||||||
void loadAssets();
|
void loadAssets();
|
||||||
public:
|
public:
|
||||||
Engine(CoreParameters coreParameters);
|
Engine();
|
||||||
~Engine();
|
~Engine();
|
||||||
|
|
||||||
|
static Engine& getInstance();
|
||||||
|
|
||||||
|
void initialize(CoreParameters coreParameters);
|
||||||
|
|
||||||
|
static void terminate();
|
||||||
|
|
||||||
/// @brief Start the engine
|
/// @brief Start the engine
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
|||||||
@ -82,8 +82,8 @@ static onaction create_action(
|
|||||||
return [callback](GUI*) {callback();};
|
return [callback](GUI*) {callback();};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read basic UINode properties */
|
/// @brief Read basic UINode properties
|
||||||
static void _readUINode(
|
static void read_uinode(
|
||||||
const UiXmlReader& reader, const xml::xmlelement& element, UINode& node
|
const UiXmlReader& reader, const xml::xmlelement& element, UINode& node
|
||||||
) {
|
) {
|
||||||
if (element.has("id")) {
|
if (element.has("id")) {
|
||||||
@ -177,8 +177,8 @@ static void _readUINode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _readContainer(UiXmlReader& reader, const xml::xmlelement& element, Container& container) {
|
static void read_container_impl(UiXmlReader& reader, const xml::xmlelement& element, Container& container) {
|
||||||
_readUINode(reader, element, container);
|
read_uinode(reader, element, container);
|
||||||
|
|
||||||
if (element.has("scrollable")) {
|
if (element.has("scrollable")) {
|
||||||
container.setScrollable(element.attr("scrollable").asBool());
|
container.setScrollable(element.attr("scrollable").asBool());
|
||||||
@ -197,17 +197,22 @@ static void _readContainer(UiXmlReader& reader, const xml::xmlelement& element,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UiXmlReader::readUINode(UiXmlReader& reader, const xml::xmlelement& element, Container& container) {
|
void UiXmlReader::readUINode(UiXmlReader& reader, const xml::xmlelement& element, Container& container) {
|
||||||
_readContainer(reader, element, container);
|
read_container_impl(reader, element, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiXmlReader::readUINode(
|
void UiXmlReader::readUINode(
|
||||||
const UiXmlReader& reader, const xml::xmlelement& element, UINode& node
|
const UiXmlReader& reader, const xml::xmlelement& element, UINode& node
|
||||||
) {
|
) {
|
||||||
_readUINode(reader, element, node);
|
read_uinode(reader, element, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _readPanel(UiXmlReader& reader, const xml::xmlelement& element, Panel& panel, bool subnodes=true) {
|
static void read_panel_impl(
|
||||||
_readUINode(reader, element, panel);
|
UiXmlReader& reader,
|
||||||
|
const xml::xmlelement& element,
|
||||||
|
Panel& panel,
|
||||||
|
bool subnodes = true
|
||||||
|
) {
|
||||||
|
read_uinode(reader, element, panel);
|
||||||
|
|
||||||
if (element.has("padding")) {
|
if (element.has("padding")) {
|
||||||
glm::vec4 padding = element.attr("padding").asVec4();
|
glm::vec4 padding = element.attr("padding").asVec4();
|
||||||
@ -245,7 +250,9 @@ static void _readPanel(UiXmlReader& reader, const xml::xmlelement& element, Pane
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::wstring readAndProcessInnerText(const xml::xmlelement& element, const std::string& context) {
|
static std::wstring parse_inner_text(
|
||||||
|
const xml::xmlelement& element, const std::string& context
|
||||||
|
) {
|
||||||
std::wstring text = L"";
|
std::wstring text = L"";
|
||||||
if (element.size() == 1) {
|
if (element.size() == 1) {
|
||||||
std::string source = element.sub(0).attr("#").getText();
|
std::string source = element.sub(0).attr("#").getText();
|
||||||
@ -265,9 +272,9 @@ static std::wstring readAndProcessInnerText(const xml::xmlelement& element, cons
|
|||||||
static std::shared_ptr<UINode> readLabel(
|
static std::shared_ptr<UINode> readLabel(
|
||||||
const UiXmlReader& reader, const xml::xmlelement& element
|
const UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
std::wstring text = readAndProcessInnerText(element, reader.getContext());
|
std::wstring text = parse_inner_text(element, reader.getContext());
|
||||||
auto label = std::make_shared<Label>(text);
|
auto label = std::make_shared<Label>(text);
|
||||||
_readUINode(reader, element, *label);
|
read_uinode(reader, element, *label);
|
||||||
if (element.has("valign")) {
|
if (element.has("valign")) {
|
||||||
label->setVerticalAlign(
|
label->setVerticalAlign(
|
||||||
align_from_string(element.attr("valign").getText(), label->getVerticalAlign())
|
align_from_string(element.attr("valign").getText(), label->getVerticalAlign())
|
||||||
@ -298,20 +305,26 @@ static std::shared_ptr<UINode> readLabel(
|
|||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readContainer(UiXmlReader& reader, const xml::xmlelement& element) {
|
static std::shared_ptr<UINode> read_container(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
|
) {
|
||||||
auto container = std::make_shared<Container>(glm::vec2());
|
auto container = std::make_shared<Container>(glm::vec2());
|
||||||
_readContainer(reader, element, *container);
|
read_container_impl(reader, element, *container);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readPanel(UiXmlReader& reader, const xml::xmlelement& element) {
|
static std::shared_ptr<UINode> read_panel(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
|
) {
|
||||||
float interval = element.attr("interval", "2").asFloat();
|
float interval = element.attr("interval", "2").asFloat();
|
||||||
auto panel = std::make_shared<Panel>(glm::vec2(), glm::vec4(), interval);
|
auto panel = std::make_shared<Panel>(glm::vec2(), glm::vec4(), interval);
|
||||||
_readPanel(reader, element, *panel);
|
read_panel_impl(reader, element, *panel);
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readButton(UiXmlReader& reader, const xml::xmlelement& element) {
|
static std::shared_ptr<UINode> read_button(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
|
) {
|
||||||
glm::vec4 padding = element.attr("padding", "10").asVec4();
|
glm::vec4 padding = element.attr("padding", "10").asVec4();
|
||||||
|
|
||||||
std::shared_ptr<Button> button;
|
std::shared_ptr<Button> button;
|
||||||
@ -323,11 +336,11 @@ static std::shared_ptr<UINode> readButton(UiXmlReader& reader, const xml::xmlele
|
|||||||
} else {
|
} else {
|
||||||
button = std::make_shared<Button>(L"", padding, nullptr);
|
button = std::make_shared<Button>(L"", padding, nullptr);
|
||||||
}
|
}
|
||||||
_readPanel(reader, element, *button, false);
|
read_panel_impl(reader, element, *button, false);
|
||||||
} else {
|
} else {
|
||||||
std::wstring text = readAndProcessInnerText(element, reader.getContext());
|
std::wstring text = parse_inner_text(element, reader.getContext());
|
||||||
button = std::make_shared<Button>(text, padding, nullptr);
|
button = std::make_shared<Button>(text, padding, nullptr);
|
||||||
_readPanel(reader, element, *button, true);
|
read_panel_impl(reader, element, *button, true);
|
||||||
}
|
}
|
||||||
if (element.has("text-align")) {
|
if (element.has("text-align")) {
|
||||||
button->setTextAlign(align_from_string(
|
button->setTextAlign(align_from_string(
|
||||||
@ -337,11 +350,13 @@ static std::shared_ptr<UINode> readButton(UiXmlReader& reader, const xml::xmlele
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readCheckBox(UiXmlReader& reader, const xml::xmlelement& element) {
|
static std::shared_ptr<UINode> read_check_box(
|
||||||
auto text = readAndProcessInnerText(element, reader.getContext());
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
|
) {
|
||||||
|
auto text = parse_inner_text(element, reader.getContext());
|
||||||
bool checked = element.attr("checked", "false").asBool();
|
bool checked = element.attr("checked", "false").asBool();
|
||||||
auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(32), checked);
|
auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(32), checked);
|
||||||
_readPanel(reader, element, *checkbox);
|
read_panel_impl(reader, element, *checkbox);
|
||||||
|
|
||||||
if (element.has("consumer")) {
|
if (element.has("consumer")) {
|
||||||
checkbox->setConsumer(scripting::create_bool_consumer(
|
checkbox->setConsumer(scripting::create_bool_consumer(
|
||||||
@ -361,14 +376,16 @@ static std::shared_ptr<UINode> readCheckBox(UiXmlReader& reader, const xml::xmle
|
|||||||
return checkbox;
|
return checkbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, const xml::xmlelement& element) {
|
static std::shared_ptr<UINode> read_text_box(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
|
) {
|
||||||
auto placeholder = util::str2wstr_utf8(element.attr("placeholder", "").getText());
|
auto placeholder = util::str2wstr_utf8(element.attr("placeholder", "").getText());
|
||||||
auto hint = util::str2wstr_utf8(element.attr("hint", "").getText());
|
auto hint = util::str2wstr_utf8(element.attr("hint", "").getText());
|
||||||
auto text = readAndProcessInnerText(element, reader.getContext());
|
auto text = parse_inner_text(element, reader.getContext());
|
||||||
auto textbox = std::make_shared<TextBox>(placeholder, glm::vec4(0.0f));
|
auto textbox = std::make_shared<TextBox>(placeholder, glm::vec4(0.0f));
|
||||||
textbox->setHint(hint);
|
textbox->setHint(hint);
|
||||||
|
|
||||||
_readContainer(reader, element, *textbox);
|
read_container_impl(reader, element, *textbox);
|
||||||
if (element.has("padding")) {
|
if (element.has("padding")) {
|
||||||
glm::vec4 padding = element.attr("padding").asVec4();
|
glm::vec4 padding = element.attr("padding").asVec4();
|
||||||
textbox->setPadding(padding);
|
textbox->setPadding(padding);
|
||||||
@ -447,16 +464,16 @@ static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, const xml::xmlel
|
|||||||
return textbox;
|
return textbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readImage(
|
static std::shared_ptr<UINode> read_image(
|
||||||
const UiXmlReader& reader, const xml::xmlelement& element
|
const UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
std::string src = element.attr("src", "").getText();
|
std::string src = element.attr("src", "").getText();
|
||||||
auto image = std::make_shared<Image>(src);
|
auto image = std::make_shared<Image>(src);
|
||||||
_readUINode(reader, element, *image);
|
read_uinode(reader, element, *image);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readCanvas(
|
static std::shared_ptr<UINode> read_canvas(
|
||||||
const UiXmlReader& reader, const xml::xmlelement& element
|
const UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
auto size = glm::uvec2{32, 32};
|
auto size = glm::uvec2{32, 32};
|
||||||
@ -464,11 +481,11 @@ static std::shared_ptr<UINode> readCanvas(
|
|||||||
size = element.attr("size").asVec2();
|
size = element.attr("size").asVec2();
|
||||||
}
|
}
|
||||||
auto image = std::make_shared<Canvas>(ImageFormat::rgba8888, size);
|
auto image = std::make_shared<Canvas>(ImageFormat::rgba8888, size);
|
||||||
_readUINode(reader, element, *image);
|
read_uinode(reader, element, *image);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readTrackBar(
|
static std::shared_ptr<UINode> read_track_bar(
|
||||||
const UiXmlReader& reader, const xml::xmlelement& element
|
const UiXmlReader& reader, const xml::xmlelement& element
|
||||||
) {
|
) {
|
||||||
const auto& env = reader.getEnvironment();
|
const auto& env = reader.getEnvironment();
|
||||||
@ -479,7 +496,7 @@ static std::shared_ptr<UINode> readTrackBar(
|
|||||||
float step = element.attr("step", "1.0").asFloat();
|
float step = element.attr("step", "1.0").asFloat();
|
||||||
int trackWidth = element.attr("track-width", "12").asInt();
|
int trackWidth = element.attr("track-width", "12").asInt();
|
||||||
auto bar = std::make_shared<TrackBar>(minv, maxv, def, step, trackWidth);
|
auto bar = std::make_shared<TrackBar>(minv, maxv, def, step, trackWidth);
|
||||||
_readUINode(reader, element, *bar);
|
read_uinode(reader, element, *bar);
|
||||||
if (element.has("consumer")) {
|
if (element.has("consumer")) {
|
||||||
bar->setConsumer(scripting::create_number_consumer(
|
bar->setConsumer(scripting::create_number_consumer(
|
||||||
env, element.attr("consumer").getText(), file));
|
env, element.attr("consumer").getText(), file));
|
||||||
@ -501,7 +518,9 @@ static std::shared_ptr<UINode> readTrackBar(
|
|||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readInputBindBox(UiXmlReader& reader, const xml::xmlelement& element) {
|
static std::shared_ptr<UINode> read_input_bind_box(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
|
) {
|
||||||
auto bindname = element.attr("binding").getText();
|
auto bindname = element.attr("binding").getText();
|
||||||
auto found = Events::bindings.find(bindname);
|
auto found = Events::bindings.find(bindname);
|
||||||
if (found == Events::bindings.end()) {
|
if (found == Events::bindings.end()) {
|
||||||
@ -509,12 +528,12 @@ static std::shared_ptr<UINode> readInputBindBox(UiXmlReader& reader, const xml::
|
|||||||
}
|
}
|
||||||
glm::vec4 padding = element.attr("padding", "6").asVec4();
|
glm::vec4 padding = element.attr("padding", "6").asVec4();
|
||||||
auto bindbox = std::make_shared<InputBindBox>(found->second, padding);
|
auto bindbox = std::make_shared<InputBindBox>(found->second, padding);
|
||||||
_readPanel(reader, element, *bindbox);
|
read_panel_impl(reader, element, *bindbox);
|
||||||
|
|
||||||
return bindbox;
|
return bindbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
static slotcallback readSlotFunc(
|
static slotcallback read_slot_func(
|
||||||
InventoryView* view,
|
InventoryView* view,
|
||||||
const UiXmlReader& reader,
|
const UiXmlReader& reader,
|
||||||
const xml::xmlelement& element,
|
const xml::xmlelement& element,
|
||||||
@ -542,13 +561,13 @@ static void readSlot(
|
|||||||
layout.position = element.attr("pos").asVec2();
|
layout.position = element.attr("pos").asVec2();
|
||||||
}
|
}
|
||||||
if (element.has("updatefunc")) {
|
if (element.has("updatefunc")) {
|
||||||
layout.updateFunc = readSlotFunc(view, reader, element, "updatefunc");
|
layout.updateFunc = read_slot_func(view, reader, element, "updatefunc");
|
||||||
}
|
}
|
||||||
if (element.has("sharefunc")) {
|
if (element.has("sharefunc")) {
|
||||||
layout.shareFunc = readSlotFunc(view, reader, element, "sharefunc");
|
layout.shareFunc = read_slot_func(view, reader, element, "sharefunc");
|
||||||
}
|
}
|
||||||
if (element.has("onrightclick")) {
|
if (element.has("onrightclick")) {
|
||||||
layout.rightClick = readSlotFunc(view, reader, element, "onrightclick");
|
layout.rightClick = read_slot_func(view, reader, element, "onrightclick");
|
||||||
}
|
}
|
||||||
layout.taking = taking;
|
layout.taking = taking;
|
||||||
layout.placing = placing;
|
layout.placing = placing;
|
||||||
@ -588,13 +607,13 @@ static void readSlotsGrid(
|
|||||||
layout.position = element.attr("pos").asVec2();
|
layout.position = element.attr("pos").asVec2();
|
||||||
}
|
}
|
||||||
if (element.has("updatefunc")) {
|
if (element.has("updatefunc")) {
|
||||||
layout.updateFunc = readSlotFunc(view, reader, element, "updatefunc");
|
layout.updateFunc = read_slot_func(view, reader, element, "updatefunc");
|
||||||
}
|
}
|
||||||
if (element.has("sharefunc")) {
|
if (element.has("sharefunc")) {
|
||||||
layout.shareFunc = readSlotFunc(view, reader, element, "sharefunc");
|
layout.shareFunc = read_slot_func(view, reader, element, "sharefunc");
|
||||||
}
|
}
|
||||||
if (element.has("onrightclick")) {
|
if (element.has("onrightclick")) {
|
||||||
layout.rightClick = readSlotFunc(view, reader, element, "onrightclick");
|
layout.rightClick = read_slot_func(view, reader, element, "onrightclick");
|
||||||
}
|
}
|
||||||
layout.padding = padding;
|
layout.padding = padding;
|
||||||
layout.taking = taking;
|
layout.taking = taking;
|
||||||
@ -618,7 +637,9 @@ static void readSlotsGrid(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readInventory(UiXmlReader& reader, const xml::xmlelement& element) {
|
static std::shared_ptr<UINode> read_inventory(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
|
) {
|
||||||
auto view = std::make_shared<InventoryView>();
|
auto view = std::make_shared<InventoryView>();
|
||||||
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f)); // todo: fixme
|
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f)); // todo: fixme
|
||||||
reader.addIgnore("slot");
|
reader.addIgnore("slot");
|
||||||
@ -633,31 +654,34 @@ static std::shared_ptr<UINode> readInventory(UiXmlReader& reader, const xml::xml
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<UINode> readPageBox(UiXmlReader& reader, const xml::xmlelement& element) {
|
static std::shared_ptr<UINode> read_page_box(
|
||||||
|
UiXmlReader& reader, const xml::xmlelement& element
|
||||||
|
) {
|
||||||
auto menu = std::make_shared<Menu>();
|
auto menu = std::make_shared<Menu>();
|
||||||
// FIXME
|
menu->setPageLoader(
|
||||||
menu->setPageLoader(scripting::engine->getGUI()->getMenu()->getPageLoader());
|
Engine::getInstance().getGUI()->getMenu()->getPageLoader()
|
||||||
_readContainer(reader, element, *menu);
|
);
|
||||||
|
read_container_impl(reader, element, *menu);
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
UiXmlReader::UiXmlReader(const scriptenv& env) : env(env) {
|
UiXmlReader::UiXmlReader(const scriptenv& env) : env(env) {
|
||||||
contextStack.emplace("");
|
contextStack.emplace("");
|
||||||
add("image", readImage);
|
add("image", read_image);
|
||||||
add("canvas", readCanvas);
|
add("canvas", read_canvas);
|
||||||
add("label", readLabel);
|
add("label", readLabel);
|
||||||
add("panel", readPanel);
|
add("panel", read_panel);
|
||||||
add("button", readButton);
|
add("button", read_button);
|
||||||
add("textbox", readTextBox);
|
add("textbox", read_text_box);
|
||||||
add("pagebox", readPageBox);
|
add("pagebox", read_page_box);
|
||||||
add("checkbox", readCheckBox);
|
add("checkbox", read_check_box);
|
||||||
add("trackbar", readTrackBar);
|
add("trackbar", read_track_bar);
|
||||||
add("container", readContainer);
|
add("container", read_container);
|
||||||
add("bindbox", readInputBindBox);
|
add("bindbox", read_input_bind_box);
|
||||||
add("inventory", readInventory);
|
add("inventory", read_inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiXmlReader::add(const std::string& tag, uinode_reader reader) {
|
void UiXmlReader::add(const std::string& tag, uinode_reader reader) {
|
||||||
|
|||||||
@ -46,9 +46,10 @@ static glm::vec4 parse_color(const std::basic_string_view<CharT>& color_code) {
|
|||||||
|
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
static inline void apply_color(
|
static inline void apply_color(
|
||||||
const std::basic_string_view<CharT>& color_code, FontStylesScheme& styles
|
const std::basic_string_view<CharT>& color_code,
|
||||||
|
FontStylesScheme& styles,
|
||||||
|
FontStyle& style
|
||||||
) {
|
) {
|
||||||
FontStyle style = styles.palette.back();
|
|
||||||
style.color = parse_color(color_code);
|
style.color = parse_color(color_code);
|
||||||
styles.palette.push_back(style);
|
styles.palette.push_back(style);
|
||||||
}
|
}
|
||||||
@ -116,7 +117,7 @@ Result<CharT> process_markdown(
|
|||||||
}
|
}
|
||||||
} else if (first == '[' && pos + 9 <= source.size() && source[pos + 1] == '#' && source[pos + 8] == ']') {
|
} else if (first == '[' && pos + 9 <= source.size() && source[pos + 1] == '#' && source[pos + 8] == ']') {
|
||||||
std::basic_string_view<CharT> color_code = source.substr(pos + 1, 8);
|
std::basic_string_view<CharT> color_code = source.substr(pos + 1, 8);
|
||||||
apply_color(color_code, styles);
|
apply_color(color_code, styles, style);
|
||||||
if (!eraseMarkdown) {
|
if (!eraseMarkdown) {
|
||||||
for (int i = 0; i < 9; ++i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
emit_md(source[pos + i], styles, ss);
|
emit_md(source[pos + i], styles, ss);
|
||||||
|
|||||||
@ -43,6 +43,11 @@ static int l_execute(lua::State* L) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_get(lua::State* L) {
|
||||||
|
auto name = lua::require_string(L, 1);
|
||||||
|
return lua::pushvalue(L, (*engine->getCommandsInterpreter())[name]);
|
||||||
|
}
|
||||||
|
|
||||||
static int l_set(lua::State* L) {
|
static int l_set(lua::State* L) {
|
||||||
auto name = lua::require_string(L, 1);
|
auto name = lua::require_string(L, 1);
|
||||||
auto value = lua::tovalue(L, 2);
|
auto value = lua::tovalue(L, 2);
|
||||||
@ -119,6 +124,7 @@ static int l_get_command_info(lua::State* L) {
|
|||||||
const luaL_Reg consolelib[] = {
|
const luaL_Reg consolelib[] = {
|
||||||
{"add_command", lua::wrap<l_add_command>},
|
{"add_command", lua::wrap<l_add_command>},
|
||||||
{"execute", lua::wrap<l_execute>},
|
{"execute", lua::wrap<l_execute>},
|
||||||
|
{"get", lua::wrap<l_get>},
|
||||||
{"set", lua::wrap<l_set>},
|
{"set", lua::wrap<l_set>},
|
||||||
{"get_commands_list", lua::wrap<l_get_commands_list>},
|
{"get_commands_list", lua::wrap<l_get_commands_list>},
|
||||||
{"get_command_info", lua::wrap<l_get_command_info>},
|
{"get_command_info", lua::wrap<l_get_command_info>},
|
||||||
|
|||||||
14
src/main.cpp
14
src/main.cpp
@ -3,11 +3,16 @@
|
|||||||
#include "util/command_line.hpp"
|
#include "util/command_line.hpp"
|
||||||
#include "debug/Logger.hpp"
|
#include "debug/Logger.hpp"
|
||||||
|
|
||||||
|
#include <csignal>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
static debug::Logger logger("main");
|
static debug::Logger logger("main");
|
||||||
|
|
||||||
|
static void sigterm_handler(int signum) {
|
||||||
|
Engine::getInstance().quit();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
CoreParameters coreParameters;
|
CoreParameters coreParameters;
|
||||||
try {
|
try {
|
||||||
@ -18,11 +23,15 @@ int main(int argc, char** argv) {
|
|||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
std::signal(SIGTERM, sigterm_handler);
|
||||||
|
|
||||||
debug::Logger::init(coreParameters.userFolder.string()+"/latest.log");
|
debug::Logger::init(coreParameters.userFolder.string()+"/latest.log");
|
||||||
platform::configure_encoding();
|
platform::configure_encoding();
|
||||||
|
|
||||||
|
auto& engine = Engine::getInstance();
|
||||||
try {
|
try {
|
||||||
Engine(std::move(coreParameters)).run();
|
engine.initialize(std::move(coreParameters));
|
||||||
|
engine.run();
|
||||||
} catch (const initialize_error& err) {
|
} catch (const initialize_error& err) {
|
||||||
logger.error() << "could not to initialize engine\n" << err.what();
|
logger.error() << "could not to initialize engine\n" << err.what();
|
||||||
}
|
}
|
||||||
@ -33,5 +42,6 @@ int main(int argc, char** argv) {
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Engine::terminate();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user