mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-20 23:23:30 +02:00
245 lines
6.2 KiB
C++
245 lines
6.2 KiB
C++
/*
|
|
This Source Code Form is subject to the
|
|
terms of the Mozilla Public License, v.
|
|
2.0. If a copy of the MPL was not
|
|
distributed with this file, You can
|
|
obtain one at
|
|
http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "application/scriptedinput.h"
|
|
|
|
#include "application/application.h"
|
|
#include "application/uilayer.h"
|
|
#include "utilities/Globals.h"
|
|
#include "utilities/Logs.h"
|
|
#include "utilities/utilities.h"
|
|
#include "editor/editorFormat.hpp"
|
|
#include "imgui/imgui.h"
|
|
|
|
#include <cctype>
|
|
#include <cstdlib>
|
|
#include <fstream>
|
|
#include <map>
|
|
|
|
namespace
|
|
{
|
|
|
|
int key_named(std::string const &Name)
|
|
{
|
|
static std::map<std::string, int> const names{{"ctrl", GLFW_KEY_LEFT_CONTROL}, {"shift", GLFW_KEY_LEFT_SHIFT}, {"alt", GLFW_KEY_LEFT_ALT}, {"esc", GLFW_KEY_ESCAPE}, {"enter", GLFW_KEY_ENTER}, {"backspace", GLFW_KEY_BACKSPACE},
|
|
{"del", GLFW_KEY_DELETE}, {"space", GLFW_KEY_SPACE}, {"tab", GLFW_KEY_TAB}};
|
|
if (auto const found{names.find(Name)}; found != names.end())
|
|
return found->second;
|
|
if (Name.size() == 1 && std::isalpha(static_cast<unsigned char>(Name[0])))
|
|
return GLFW_KEY_A + (std::toupper(static_cast<unsigned char>(Name[0])) - 'A');
|
|
if (Name.size() == 1 && std::isdigit(static_cast<unsigned char>(Name[0])))
|
|
return GLFW_KEY_0 + (Name[0] - '0');
|
|
if (Name.size() > 1 && (Name[0] == 'f' || Name[0] == 'F') && std::isdigit(static_cast<unsigned char>(Name[1])))
|
|
return GLFW_KEY_F1 + std::stoi(Name.substr(1)) - 1;
|
|
return GLFW_KEY_UNKNOWN;
|
|
}
|
|
|
|
int modifier_of(int const Key)
|
|
{
|
|
return Key == GLFW_KEY_LEFT_CONTROL ? GLFW_MOD_CONTROL : Key == GLFW_KEY_LEFT_SHIFT ? GLFW_MOD_SHIFT : Key == GLFW_KEY_LEFT_ALT ? GLFW_MOD_ALT : 0;
|
|
}
|
|
|
|
void modifiers(int const Mods)
|
|
{
|
|
auto &io{ImGui::GetIO()};
|
|
io.AddKeyEvent(ImGuiMod_Ctrl, (Mods & GLFW_MOD_CONTROL) != 0);
|
|
io.AddKeyEvent(ImGuiMod_Shift, (Mods & GLFW_MOD_SHIFT) != 0);
|
|
io.AddKeyEvent(ImGuiMod_Alt, (Mods & GLFW_MOD_ALT) != 0);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void scripted_input::queue(std::function<void()> Event)
|
|
{
|
|
s_driving = true;
|
|
m_events.emplace_back(std::move(Event));
|
|
}
|
|
|
|
void scripted_input::deliver()
|
|
{
|
|
auto const events{std::move(m_events)};
|
|
m_events.clear();
|
|
for (auto const &event : events)
|
|
event();
|
|
}
|
|
|
|
void scripted_input::mouse_to(glm::dvec2 const &Screen)
|
|
{
|
|
bool const entered{m_mouse.has_value()};
|
|
m_mouse = Screen;
|
|
queue([Screen, entered]() {
|
|
if (false == entered)
|
|
ui_layer::cursor_enter_callback(1);
|
|
ui_layer::cursor_pos_callback(Screen.x, Screen.y);
|
|
Global.cursor_pos = glm::ivec2(Screen);
|
|
Application.on_cursor_pos(Screen.x, Screen.y);
|
|
});
|
|
}
|
|
|
|
bool scripted_input::dispatch(std::string const &Command, std::istringstream &Words)
|
|
{
|
|
if (Command == "mouse")
|
|
{
|
|
glm::dvec2 screen{0.0};
|
|
Words >> screen.x >> screen.y;
|
|
mouse_to(screen);
|
|
WriteLog(format("SELFTEST mouse %.0f %.0f", screen.x, screen.y));
|
|
return true;
|
|
}
|
|
if (Command == "button")
|
|
{
|
|
std::string which;
|
|
std::string action;
|
|
Words >> which >> action;
|
|
auto const button{which == "right" ? GLFW_MOUSE_BUTTON_RIGHT : which == "middle" ? GLFW_MOUSE_BUTTON_MIDDLE : GLFW_MOUSE_BUTTON_LEFT};
|
|
auto const state{action == "release" ? GLFW_RELEASE : GLFW_PRESS};
|
|
queue([button, state, mods = m_mods]() {
|
|
Application.on_mouse_button(button, state, mods);
|
|
modifiers(mods);
|
|
});
|
|
return true;
|
|
}
|
|
if (Command == "wheel")
|
|
{
|
|
double offset{0.0};
|
|
Words >> offset;
|
|
queue([offset, mods = m_mods]() {
|
|
Application.on_scroll(0.0, offset);
|
|
modifiers(mods);
|
|
});
|
|
return true;
|
|
}
|
|
if (Command == "press" || Command == "release" || Command == "tap")
|
|
{
|
|
std::string name;
|
|
Words >> name;
|
|
auto const key{key_named(name)};
|
|
if (key == GLFW_KEY_UNKNOWN)
|
|
{
|
|
WriteLog("SELFTEST " + Command + ": unknown key " + name);
|
|
return true;
|
|
}
|
|
if (Command != "release")
|
|
{
|
|
m_mods |= modifier_of(key);
|
|
queue([key, mods = m_mods]() {
|
|
Application.on_key(key, 0, GLFW_PRESS, mods);
|
|
modifiers(mods);
|
|
});
|
|
}
|
|
if (Command != "press")
|
|
{
|
|
m_mods &= ~modifier_of(key);
|
|
queue([key, mods = m_mods]() {
|
|
Application.on_key(key, 0, GLFW_RELEASE, mods);
|
|
modifiers(mods);
|
|
});
|
|
}
|
|
return true;
|
|
}
|
|
if (Command == "type")
|
|
{
|
|
std::string text;
|
|
std::getline(Words >> std::ws, text);
|
|
for (std::size_t index = 0; index < text.size();)
|
|
{
|
|
auto const lead{static_cast<unsigned char>(text[index])};
|
|
auto const extra{lead >= 0xF0 ? 3 : lead >= 0xE0 ? 2 : lead >= 0xC0 ? 1 : 0};
|
|
unsigned int code{extra == 0 ? lead : lead & (0x3Fu >> extra)};
|
|
for (int k = 1; k <= extra && index + k < text.size(); ++k)
|
|
code = (code << 6) | (static_cast<unsigned char>(text[index + k]) & 0x3Fu);
|
|
queue([code]() { Application.on_char(code); });
|
|
index += extra + 1;
|
|
}
|
|
return true;
|
|
}
|
|
if (Command == "softcursor")
|
|
{
|
|
int on{1};
|
|
Words >> on;
|
|
ImGui::GetIO().MouseDrawCursor = on != 0;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void input_script::step()
|
|
{
|
|
if (false == m_loaded)
|
|
{
|
|
m_loaded = true;
|
|
auto const *file{std::getenv(m_variable)};
|
|
if (file == nullptr)
|
|
return;
|
|
std::ifstream stream(file);
|
|
std::string line;
|
|
while (std::getline(stream, line))
|
|
if (false == line.empty() && line.front() != '#')
|
|
m_lines.push_back(line);
|
|
WriteLog("SELFTEST: " + std::to_string(m_lines.size()) + " steps from " + file);
|
|
}
|
|
if (m_wait > 0)
|
|
{
|
|
--m_wait;
|
|
return;
|
|
}
|
|
while (m_next < m_lines.size())
|
|
{
|
|
std::istringstream words(m_lines[m_next++]);
|
|
std::string command;
|
|
words >> command;
|
|
if (command == "wait")
|
|
{
|
|
words >> m_wait;
|
|
return;
|
|
}
|
|
if (command == "screenshot")
|
|
{
|
|
Application.queue_screenshot();
|
|
m_wait = 3;
|
|
return;
|
|
}
|
|
if (command == "log")
|
|
{
|
|
std::string text;
|
|
std::getline(words >> std::ws, text);
|
|
WriteLog("SELFTEST " + text);
|
|
continue;
|
|
}
|
|
if (command == "editorscript")
|
|
{
|
|
std::string file;
|
|
words >> file;
|
|
#ifdef _WIN32
|
|
_putenv_s("EU07_EDITOR_SELFTEST", file.c_str());
|
|
#else
|
|
setenv("EU07_EDITOR_SELFTEST", file.c_str(), 1);
|
|
#endif
|
|
WriteLog("SELFTEST editor script " + file);
|
|
continue;
|
|
}
|
|
if (command == "quit")
|
|
{
|
|
if (false == m_quitting)
|
|
{
|
|
WriteLog("SELFTEST done");
|
|
m_quitting = true;
|
|
m_wait = 30;
|
|
--m_next;
|
|
return;
|
|
}
|
|
Application.queue_quit(true);
|
|
return;
|
|
}
|
|
if (false == m_input.dispatch(command, words))
|
|
WriteLog("SELFTEST unknown command " + command);
|
|
}
|
|
}
|