diff --git a/meson.build b/meson.build index d690a49..e8411b5 100644 --- a/meson.build +++ b/meson.build @@ -9,12 +9,25 @@ project('tiwiq', twq_lib = static_library('tiwiq', sources: [ - 'src/core/KeyMod.cpp', - 'src/core/Shortcut.cpp', + 'src/core/Binding.cpp', 'src/core/Command.cpp', 'src/core/Context.cpp', - 'src/core/Binding.cpp', 'src/core/Executor.cpp', + 'src/core/KeyMod.cpp', + 'src/core/Plugin.cpp', + 'src/core/Shortcut.cpp', + 'src/core/Tiwiq.cpp', + 'src/core/UI.cpp', + 'src/core/Observer.cpp', + 'src/core/Observable.cpp', + 'src/core/Event.cpp', + + 'src/cmd/QuitCmd.cpp', + + 'src/plugins/CorePlugin.cpp', + + 'src/term/Controller.cpp', + 'src/term/Term.cpp', ], dependencies: [ dependency('ncursesw') diff --git a/src/cmd/QuitCmd.cpp b/src/cmd/QuitCmd.cpp new file mode 100644 index 0000000..cba8cce --- /dev/null +++ b/src/cmd/QuitCmd.cpp @@ -0,0 +1,25 @@ +#include "QuitCmd.hpp" + +namespace twq +{ + namespace cmd + { + /*explicit*/ QuitCmd::QuitCmd() + { + } + + /*virtual*/ QuitCmd::~QuitCmd() + { + } + + /*virtual*/ void QuitCmd::execute(core::Context& context) /*override*/ + { + context.tiwiq().stop(); + } + + /*virtual*/ void QuitCmd::undo(core::Context&) /*override*/ + { + } + + } +} diff --git a/src/cmd/QuitCmd.hpp b/src/cmd/QuitCmd.hpp new file mode 100644 index 0000000..e408385 --- /dev/null +++ b/src/cmd/QuitCmd.hpp @@ -0,0 +1,24 @@ +#ifndef twq_cmd_QUITCMD_HPP +#define twq_cmd_QUITCMD_HPP + +#include "../core/Command.hpp" + +namespace twq +{ + namespace cmd + { + class QuitCmd: public core::Command + { + public: + explicit QuitCmd(); + virtual ~QuitCmd(); + + virtual void execute(core::Context& context) override; + virtual void undo(core::Context& context) override; + + private: + }; + } +} + +#endif diff --git a/src/core/Context.cpp b/src/core/Context.cpp index d323a11..e9c9dfe 100644 --- a/src/core/Context.cpp +++ b/src/core/Context.cpp @@ -4,7 +4,8 @@ namespace twq { namespace core { - /*explicit*/ Context::Context() + /*explicit*/ Context::Context(Tiwiq& tiwiq) + : m_tiwiq { tiwiq } { } diff --git a/src/core/Context.hpp b/src/core/Context.hpp index a91b9d0..724c6e4 100644 --- a/src/core/Context.hpp +++ b/src/core/Context.hpp @@ -1,6 +1,8 @@ #ifndef twq_core_CONTEXT_HPP #define twq_core_CONTEXT_HPP +#include "Tiwiq.hpp" + namespace twq { namespace core @@ -8,10 +10,13 @@ namespace twq class Context { public: - explicit Context(); + explicit Context(Tiwiq& tiwiq); virtual ~Context(); + Tiwiq& tiwiq() const { return m_tiwiq; } + private: + Tiwiq& m_tiwiq; }; } } diff --git a/src/core/Event.cpp b/src/core/Event.cpp new file mode 100644 index 0000000..e5e4138 --- /dev/null +++ b/src/core/Event.cpp @@ -0,0 +1,8 @@ +#include "Event.hpp" + +namespace twq +{ + namespace core + { + } +} diff --git a/src/core/Event.hpp b/src/core/Event.hpp new file mode 100644 index 0000000..ad12bd0 --- /dev/null +++ b/src/core/Event.hpp @@ -0,0 +1,18 @@ +#ifndef twq_core_EVENT_HPP +#define twq_core_EVENT_HPP + +#include "../commons.hpp" +#include "KeyMod.hpp" + +namespace twq +{ + namespace core + { + struct Event + { + std::optional key; + }; + } +} + +#endif diff --git a/src/core/KeyMod.cpp b/src/core/KeyMod.cpp index bb52dbf..e7eecdd 100644 --- a/src/core/KeyMod.cpp +++ b/src/core/KeyMod.cpp @@ -10,18 +10,18 @@ namespace twq return KeyMod { key_type, mods, std::nullopt }; } - /*explicit*/ KeyMod::KeyMod(std::string const& repr) + /*explicit*/ KeyMod::KeyMod(std::wstring const& repr) { std::vector mods; - if (repr.find("C-") != std::string::npos) + if (repr.find(L"C-") != std::string::npos) { - mods.push_back(MOD_LCTRL); + mods.push_back(KM_MOD_LCTRL); } - if (repr.find("A-") != std::string::npos) + if (repr.find(L"A-") != std::string::npos) { - mods.push_back(MOD_ALT); + mods.push_back(KM_MOD_ALT); } ssize_t k = repr.size() - 1; @@ -30,7 +30,7 @@ namespace twq k--; } - std::string value; + std::wstring value; while (k >= 0 && !std::isspace(repr[k]) @@ -42,16 +42,17 @@ namespace twq if (value.size() == 1) { - m_key_type = KEY_TEXT; + m_key_type = KM_KEY_TEXT; m_mods = mods; m_text = value.front(); return; } else { - for (size_t i=0; i const& mods) - : m_key_type { KEY_TEXT } + : m_key_type { KM_KEY_TEXT } , m_mods { mods } , m_text { text } { @@ -78,7 +80,7 @@ namespace twq /*explicit*/ KeyMod::KeyMod(KeyType key_type, std::vector const& mods, - std::optional text) + std::optional text) : m_key_type { key_type } , m_mods { mods } , m_text { text } @@ -103,7 +105,7 @@ namespace twq return false; } - if (m_key_type == KEY_TEXT + if (m_key_type == KM_KEY_TEXT && *m_text != *rhs.m_text) { return false; @@ -126,27 +128,27 @@ namespace twq return true; } - std::string KeyMod::string() const + std::wstring KeyMod::wstring() const { - std::stringstream ss; + std::wstringstream ss; - if (has_mod(MOD_LCTRL)) + if (has_mod(KM_MOD_LCTRL)) { ss << "C-"; } - if (has_mod(MOD_ALT)) + if (has_mod(KM_MOD_ALT)) { ss << "A-"; } - if (m_key_type == KEY_TEXT) + if (m_key_type == KM_KEY_TEXT) { ss << *m_text; } else { - ss << (KeyTypeStr[m_key_type] + strlen("KEY_")); + ss << (KeyTypeStr[m_key_type] + strlen("KM_KEY_")); } return ss.str(); diff --git a/src/core/KeyMod.hpp b/src/core/KeyMod.hpp index 7378cc4..79c0ae8 100644 --- a/src/core/KeyMod.hpp +++ b/src/core/KeyMod.hpp @@ -4,17 +4,17 @@ #include "../commons.hpp" #define KEY_TYPES(G) \ - G(KEY_TEXT), \ - G(KEY_UP), \ - G(KEY_DOWN), \ - G(KEY_LEFT), \ - G(KEY_RIGHT), \ - G(KEY_COUNT), + G(KM_KEY_TEXT), \ + G(KM_KEY_UP), \ + G(KM_KEY_DOWN), \ + G(KM_KEY_LEFT), \ + G(KM_KEY_RIGHT), \ + G(KM_KEY_COUNT), #define MOD_TYPES(G)\ - G(MOD_LCTRL), \ - G(MOD_ALT), \ - G(MOD_COUNT), + G(KM_MOD_LCTRL), \ + G(KM_MOD_ALT), \ + G(KM_MOD_COUNT), namespace twq { @@ -31,31 +31,31 @@ namespace twq static KeyMod key(KeyType key_type, std::vector const& mods={}); - explicit KeyMod(std::string const& repr); + explicit KeyMod(std::wstring const& repr); - explicit KeyMod(char text, std::vector const& mods={}); + explicit KeyMod(wchar_t text, std::vector const& mods={}); explicit KeyMod(KeyType key_type, std::vector const& mods, - std::optional text); + std::optional text); KeyType key_type() const { return m_key_type; } std::vector mods() const { return m_mods; } - std::optional text() const { return m_text; } + std::optional text() const { return m_text; } bool has_mod(ModType mod_type) const; bool equals(KeyMod const& rhs) const; - std::string string() const; + std::wstring wstring() const; virtual ~KeyMod(); private: KeyType m_key_type; std::vector m_mods; - std::optional m_text; + std::optional m_text; }; } } diff --git a/src/core/Observable.cpp b/src/core/Observable.cpp new file mode 100644 index 0000000..f377082 --- /dev/null +++ b/src/core/Observable.cpp @@ -0,0 +1,33 @@ +#include "Observable.hpp" + +namespace twq +{ + namespace core + { + /*explicit*/ Observable::Observable() + { + } + + /*virtual*/ Observable::~Observable() + { + } + + void Observable::add_observer(std::weak_ptr observer) + { + m_observers.push_back(observer); + } + + void Observable::notify(Event& event) + { + for (auto observer: m_observers) + { + if (auto obs = observer.lock(); + obs) + { + obs->update(event); + } + } + } + + } +} diff --git a/src/core/Observable.hpp b/src/core/Observable.hpp new file mode 100644 index 0000000..2e35800 --- /dev/null +++ b/src/core/Observable.hpp @@ -0,0 +1,27 @@ +#ifndef twq_core_OBSERVABLE_HPP +#define twq_core_OBSERVABLE_HPP + +#include "../commons.hpp" +#include "Observer.hpp" +#include "Event.hpp" + +namespace twq +{ + namespace core + { + class Observable + { + public: + explicit Observable(); + virtual ~Observable(); + + void add_observer(std::weak_ptr observer); + void notify(Event& event); + + private: + std::vector> m_observers; + }; + } +} + +#endif diff --git a/src/core/Observer.cpp b/src/core/Observer.cpp new file mode 100644 index 0000000..a9800fe --- /dev/null +++ b/src/core/Observer.cpp @@ -0,0 +1,15 @@ +#include "Observer.hpp" + +namespace twq +{ + namespace core + { + /*explicit*/ Observer::Observer() + { + } + + /*virtual*/ Observer::~Observer() + { + } + } +} diff --git a/src/core/Observer.hpp b/src/core/Observer.hpp new file mode 100644 index 0000000..370649d --- /dev/null +++ b/src/core/Observer.hpp @@ -0,0 +1,24 @@ +#ifndef twq_core_OBSERVER_HPP +#define twq_core_OBSERVER_HPP + +#include "../commons.hpp" +#include "Event.hpp" + +namespace twq +{ + namespace core + { + class Observer + { + public: + explicit Observer(); + virtual ~Observer(); + + virtual void update(Event&) {} + + private: + }; + } +} + +#endif diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp new file mode 100644 index 0000000..b5f83f8 --- /dev/null +++ b/src/core/Plugin.cpp @@ -0,0 +1,23 @@ +#include "Plugin.hpp" +#include "Executor.hpp" + +namespace twq +{ + namespace core + { + /*explicit*/ Plugin::Plugin(std::string const& name) + : m_name { name } + , m_executor { std::make_shared() } + { + } + + /*virtual*/ Plugin::~Plugin() + { + } + + std::weak_ptr Plugin::executor() + { + return m_executor; + } + } +} diff --git a/src/core/Plugin.hpp b/src/core/Plugin.hpp new file mode 100644 index 0000000..0ee8de1 --- /dev/null +++ b/src/core/Plugin.hpp @@ -0,0 +1,33 @@ +#ifndef twq_core_PLUGIN_HPP +#define twq_core_PLUGIN_HPP + +#include "../commons.hpp" +#include "UI.hpp" + +namespace twq +{ + namespace core + { + class Executor; + + class Plugin + { + public: + explicit Plugin(std::string const& name); + virtual ~Plugin(); + + std::string name() const { return m_name; } + std::weak_ptr ui() { return m_ui; } + + std::weak_ptr executor(); + private: + std::string m_name; + std::shared_ptr m_executor; + + std::shared_ptr m_ui = + std::make_shared(); + }; + } +} + +#endif diff --git a/src/core/Shortcut.cpp b/src/core/Shortcut.cpp index 8c4fc05..7992771 100644 --- a/src/core/Shortcut.cpp +++ b/src/core/Shortcut.cpp @@ -10,14 +10,14 @@ namespace twq { } - /*explicit*/ Shortcut::Shortcut(std::string const& repr) + /*explicit*/ Shortcut::Shortcut(std::wstring const& repr) { - std::string buffer; + std::wstring buffer; std::vector mods; for (size_t i=0; i m_keymods; diff --git a/src/core/Tiwiq.cpp b/src/core/Tiwiq.cpp new file mode 100644 index 0000000..611e789 --- /dev/null +++ b/src/core/Tiwiq.cpp @@ -0,0 +1,44 @@ +#include "Tiwiq.hpp" +#include "Event.hpp" +#include "Executor.hpp" + +namespace twq +{ + namespace core + { + /*explicit*/ Tiwiq::Tiwiq() + { + } + + /*virtual*/ Tiwiq::~Tiwiq() + { + } + + void Tiwiq::start() + { + m_is_running = true; + } + + void Tiwiq::stop() + { + m_is_running = false; + } + + void Tiwiq::add_plugin(std::shared_ptr plugin) + { + m_plugins.push_back(plugin); + } + + void Tiwiq::update(Event& event) /*override*/ + { + if (event.key) + { + if (!m_plugins.empty()) + { + Context ctx { *this }; + m_plugins.back()->executor().lock()->update(ctx, *event.key); + } + } + } + } +} diff --git a/src/core/Tiwiq.hpp b/src/core/Tiwiq.hpp new file mode 100644 index 0000000..35464ed --- /dev/null +++ b/src/core/Tiwiq.hpp @@ -0,0 +1,34 @@ +#ifndef twq_core_TIWIQ_HPP +#define twq_core_TIWIQ_HPP + +#include "../commons.hpp" +#include "Plugin.hpp" +#include "Observer.hpp" + +namespace twq +{ + namespace core + { + class Tiwiq: public Observer + { + public: + explicit Tiwiq(); + virtual ~Tiwiq(); + + bool is_running() const { return m_is_running; } + + void start(); + void stop(); + + void add_plugin(std::shared_ptr plugin); + + void update(Event& event) override; + + private: + bool m_is_running = false; + std::vector> m_plugins; + }; + } +} + +#endif diff --git a/src/core/UI.cpp b/src/core/UI.cpp new file mode 100644 index 0000000..702728e --- /dev/null +++ b/src/core/UI.cpp @@ -0,0 +1,15 @@ +#include "UI.hpp" + +namespace twq +{ + namespace core + { + /*explicit*/ UI::UI() + { + } + + /*virtual*/ UI::~UI() + { + } + } +} diff --git a/src/core/UI.hpp b/src/core/UI.hpp new file mode 100644 index 0000000..fb32fe9 --- /dev/null +++ b/src/core/UI.hpp @@ -0,0 +1,19 @@ +#ifndef twq_core_UI_HPP +#define twq_core_UI_HPP + +namespace twq +{ + namespace core + { + class UI + { + public: + explicit UI(); + virtual ~UI(); + + private: + }; + } +} + +#endif diff --git a/src/main.cpp b/src/main.cpp index a72903a..e061cd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,27 @@ #include +#include "core/Tiwiq.hpp" +#include "term/Term.hpp" +#include "plugins/CorePlugin.hpp" int main(int, char**) { + auto tiwiq = std::make_shared(); + auto term = std::make_shared(); + term->controller().lock()->add_observer(tiwiq); + + // Build and add plugins + // --------------------- + auto core_plugin = std::make_shared(); + tiwiq->add_plugin(core_plugin); + + // Start TiwiQ + // ----------- + tiwiq->start(); + + while (tiwiq->is_running()) + { + term->controller().lock()->update(); + } + return 0; } diff --git a/src/plugins/CorePlugin.cpp b/src/plugins/CorePlugin.cpp new file mode 100644 index 0000000..53578fb --- /dev/null +++ b/src/plugins/CorePlugin.cpp @@ -0,0 +1,23 @@ +#include "CorePlugin.hpp" +#include "../core/Executor.hpp" + +namespace twq +{ + namespace plugins + { + /*explicit*/ CorePlugin::CorePlugin() + : core::Plugin {"core"} + { + auto exec = executor().lock(); + + auto sc = std::make_shared(L"C-C C-C"); + auto cmd = std::make_shared(); + auto binding = core::Binding{sc, cmd}; + exec->register_binding(binding); + } + + /*virtual*/ CorePlugin::~CorePlugin() + { + } + } +} diff --git a/src/plugins/CorePlugin.hpp b/src/plugins/CorePlugin.hpp new file mode 100644 index 0000000..fd135f5 --- /dev/null +++ b/src/plugins/CorePlugin.hpp @@ -0,0 +1,22 @@ +#ifndef twq_plugins_COREPLUGIN_HPP +#define twq_plugins_COREPLUGIN_HPP + +#include "../core/Plugin.hpp" +#include "../cmd/QuitCmd.hpp" + +namespace twq +{ + namespace plugins + { + class CorePlugin: public core::Plugin + { + public: + explicit CorePlugin(); + virtual ~CorePlugin(); + + private: + }; + } +} + +#endif diff --git a/src/term/Controller.cpp b/src/term/Controller.cpp new file mode 100644 index 0000000..3c88c9e --- /dev/null +++ b/src/term/Controller.cpp @@ -0,0 +1,61 @@ +#include +#include "Controller.hpp" +#include "../core/KeyMod.hpp" + + +namespace twq +{ + namespace term + { + /*explicit*/ Controller::Controller() + { + } + + /*virtual*/ Controller::~Controller() + { + } + + void Controller::update() + { + core::Event event; + event.key = get(); + notify(event); + } + + core::KeyMod Controller::get() const + { + wint_t c; + get_wch(&c); + + core::KeyType key_type = core::KM_KEY_TEXT; + std::optional text; + std::vector mods; + + if (c == 27) + { + get_wch(&c); + mods.push_back(core::KM_MOD_ALT); + } + + std::string name = keyname(c); + std::wstring wname {std::begin(name), std::end(name)}; + + if (wname.size() > 1 && wname[0] == L'^') + { + text = wname[1]; + mods.push_back(core::KM_MOD_LCTRL); + } + else if (std::iswprint((wchar_t) c)) + { + text = c; + } + else + { + TWQ_ASSERT(0, "keymod not found"); + } + + auto keymod = core::KeyMod {key_type, mods, text}; + return keymod; + } + } +} diff --git a/src/term/Controller.hpp b/src/term/Controller.hpp new file mode 100644 index 0000000..45d2126 --- /dev/null +++ b/src/term/Controller.hpp @@ -0,0 +1,26 @@ +#ifndef twq_term_CONTROLLER_HPP +#define twq_term_CONTROLLER_HPP + +#include "../commons.hpp" +#include "../core/KeyMod.hpp" +#include "../core/Observable.hpp" + +namespace twq +{ + namespace term + { + class Controller: public core::Observable + { + public: + explicit Controller(); + virtual ~Controller(); + + void update(); + core::KeyMod get() const; + + private: + }; + } +} + +#endif diff --git a/src/term/Term.cpp b/src/term/Term.cpp new file mode 100644 index 0000000..39eba32 --- /dev/null +++ b/src/term/Term.cpp @@ -0,0 +1,22 @@ +#include "Term.hpp" + +namespace twq +{ + namespace term + { + /*explicit*/ Term::Term() + { + setlocale(LC_ALL, ""); + + initscr(); + raw(); + keypad(stdscr, TRUE); + noecho(); + } + + /*virtual*/ Term::~Term() + { + endwin(); + } + } +} diff --git a/src/term/Term.hpp b/src/term/Term.hpp new file mode 100644 index 0000000..9021c41 --- /dev/null +++ b/src/term/Term.hpp @@ -0,0 +1,28 @@ +#ifndef twq_term_TERM_HPP +#define twq_term_TERM_HPP + +#include +#include "../commons.hpp" + +#include "Controller.hpp" + +namespace twq +{ + namespace term + { + class Term + { + public: + explicit Term(); + virtual ~Term(); + + std::weak_ptr controller() { return m_controller; } + + private: + std::shared_ptr m_controller = + std::make_shared(); + }; + } +} + +#endif diff --git a/tests/Executor.cpp b/tests/Executor.cpp index 3bc1b6b..edcae43 100644 --- a/tests/Executor.cpp +++ b/tests/Executor.cpp @@ -1,4 +1,5 @@ #include +#include "../src/core/Tiwiq.hpp" #include "../src/core/Executor.hpp" using namespace twq::core; @@ -9,7 +10,13 @@ public: explicit ExecutorTest() {} virtual ~ExecutorTest() {} + Context get_context() + { + return Context {m_tiwiq}; + } + protected: + twq::core::Tiwiq m_tiwiq; }; struct CommandMock: public Command @@ -28,95 +35,95 @@ struct CommandMock: public Command TEST_CASE_METHOD(ExecutorTest, "Executor_one_key") { - Context ctx; + Context ctx = get_context(); auto cmd = std::make_shared(); - Binding b {std::make_shared("a"), cmd}; + Binding b {std::make_shared(L"a"), cmd}; Executor exec; exec.register_binding(b); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(1 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(2 == cmd->execute_count); } TEST_CASE_METHOD(ExecutorTest, "Executor_two_same_keys") { - Context ctx; + Context ctx = get_context(); auto cmd = std::make_shared(); - Binding b {std::make_shared("a a"), cmd}; + Binding b {std::make_shared(L"a a"), cmd}; Executor exec; exec.register_binding(b); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(1 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(1 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(2 == cmd->execute_count); } TEST_CASE_METHOD(ExecutorTest, "Executor_two_keys") { - Context ctx; + Context ctx = get_context(); auto cmd = std::make_shared(); - Binding b {std::make_shared("a b"), cmd}; + Binding b {std::make_shared(L"a b"), cmd}; Executor exec; exec.register_binding(b); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"b"}); + exec.update(ctx, KeyMod {L"b"}); REQUIRE(1 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(1 == cmd->execute_count); - exec.update(ctx, KeyMod {"b"}); + exec.update(ctx, KeyMod {L"b"}); REQUIRE(2 == cmd->execute_count); } TEST_CASE_METHOD(ExecutorTest, "Executor_wrong_key") { - Context ctx; + Context ctx = get_context(); auto cmd = std::make_shared(); - Binding b {std::make_shared("a b"), cmd}; + Binding b {std::make_shared(L"a b"), cmd}; Executor exec; exec.register_binding(b); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"c"}); + exec.update(ctx, KeyMod {L"c"}); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"b"}); + exec.update(ctx, KeyMod {L"b"}); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"a"}); + exec.update(ctx, KeyMod {L"a"}); REQUIRE(0 == cmd->execute_count); - exec.update(ctx, KeyMod {"b"}); + exec.update(ctx, KeyMod {L"b"}); REQUIRE(1 == cmd->execute_count); } TEST_CASE_METHOD(ExecutorTest, "Executor_two_commands") { - Context ctx; + Context ctx = get_context(); auto cmd0 = std::make_shared(); - Binding b0 {std::make_shared("C-a b"), cmd0}; + Binding b0 {std::make_shared(L"C-a b"), cmd0}; auto cmd1 = std::make_shared(); - Binding b1 {std::make_shared("C-a c"), cmd1}; + Binding b1 {std::make_shared(L"C-a c"), cmd1}; Executor exec; exec.register_binding(b0); @@ -126,11 +133,11 @@ TEST_CASE_METHOD(ExecutorTest, "Executor_two_commands") { REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"C-a"}); + exec.update(ctx, KeyMod {L"C-a"}); REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"b"}); + exec.update(ctx, KeyMod {L"b"}); REQUIRE(1 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); @@ -140,11 +147,11 @@ TEST_CASE_METHOD(ExecutorTest, "Executor_two_commands") { REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"C-a"}); + exec.update(ctx, KeyMod {L"C-a"}); REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"c"}); + exec.update(ctx, KeyMod {L"c"}); REQUIRE(0 == cmd0->execute_count); REQUIRE(1 == cmd1->execute_count); @@ -154,15 +161,15 @@ TEST_CASE_METHOD(ExecutorTest, "Executor_two_commands") { REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"C-a"}); + exec.update(ctx, KeyMod {L"C-a"}); REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"d"}); + exec.update(ctx, KeyMod {L"d"}); REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"b"}); + exec.update(ctx, KeyMod {L"b"}); REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); @@ -171,13 +178,13 @@ TEST_CASE_METHOD(ExecutorTest, "Executor_two_commands") TEST_CASE_METHOD(ExecutorTest, "Executor_two_sequentials_commands") { - Context ctx; + Context ctx = get_context(); auto cmd0 = std::make_shared(); - Binding b0 {std::make_shared("C-a b"), cmd0}; + Binding b0 {std::make_shared(L"C-a b"), cmd0}; auto cmd1 = std::make_shared(); - Binding b1 {std::make_shared("b c"), cmd1}; + Binding b1 {std::make_shared(L"b c"), cmd1}; Executor exec; exec.register_binding(b0); @@ -187,23 +194,23 @@ TEST_CASE_METHOD(ExecutorTest, "Executor_two_sequentials_commands") { REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"C-a"}); + exec.update(ctx, KeyMod {L"C-a"}); REQUIRE(0 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"b"}); + exec.update(ctx, KeyMod {L"b"}); REQUIRE(1 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"c"}); + exec.update(ctx, KeyMod {L"c"}); REQUIRE(1 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"b"}); + exec.update(ctx, KeyMod {L"b"}); REQUIRE(1 == cmd0->execute_count); REQUIRE(0 == cmd1->execute_count); - exec.update(ctx, KeyMod {"c"}); + exec.update(ctx, KeyMod {L"c"}); REQUIRE(1 == cmd0->execute_count); REQUIRE(1 == cmd1->execute_count); diff --git a/tests/Shortcut.cpp b/tests/Shortcut.cpp index 48c5d78..7754ef0 100644 --- a/tests/Shortcut.cpp +++ b/tests/Shortcut.cpp @@ -9,8 +9,8 @@ public: explicit ShortcutTest() {} virtual ~ShortcutTest() {} - void test_to_string(std::string const& oracle, - std::vector keymods) + void test_to_string(std::wstring const& oracle, + std::vector keymods) { Shortcut sc; @@ -19,16 +19,15 @@ public: sc.push(km); } - INFO("Expected '" << oracle << "' got '" << sc.string() << "'"); - REQUIRE(oracle == sc.string()); + REQUIRE(oracle == sc.wstring()); } - void test_from_string(std::string const& oracle, - std::string const& shortcut) + void test_from_string(std::wstring const& oracle, + std::wstring const& shortcut) { Shortcut sc { shortcut }; - INFO("Expected '" << oracle << "' got '" << sc.string() << "'"); - REQUIRE(oracle == sc.string()); + + REQUIRE(oracle == sc.wstring()); } protected: @@ -36,71 +35,71 @@ protected: TEST_CASE_METHOD(ShortcutTest, "Shortcut_string") { - test_to_string("f", {KeyMod {'f'}}); + test_to_string(L"f", {KeyMod {'f'}}); - test_to_string("a b c", { - KeyMod {'a'}, - KeyMod {'b'}, - KeyMod {'c'}, + test_to_string(L"a b c", { + KeyMod {L'a'}, + KeyMod {L'b'}, + KeyMod {L'c'}, }); - test_to_string("C-g", {KeyMod {'g', {MOD_LCTRL}}}); - test_to_string("A-g", {KeyMod {'g', {MOD_ALT}}}); - test_to_string("C-A-g", {KeyMod {'g', {MOD_LCTRL, MOD_ALT}}}); + test_to_string(L"C-g", {KeyMod {L'g', {KM_MOD_LCTRL}}}); + test_to_string(L"A-g", {KeyMod {L'g', {KM_MOD_ALT}}}); + test_to_string(L"C-A-g", {KeyMod {L'g', {KM_MOD_LCTRL, KM_MOD_ALT}}}); - test_to_string("A-a C-A-b C-c d", { - KeyMod {'a', {MOD_ALT}}, - KeyMod {'b', {MOD_LCTRL, MOD_ALT}}, - KeyMod {'c', {MOD_LCTRL}}, - KeyMod {'d'}, + test_to_string(L"A-a C-A-b C-c d", { + KeyMod {L'a', {KM_MOD_ALT}}, + KeyMod {L'b', {KM_MOD_LCTRL, KM_MOD_ALT}}, + KeyMod {L'c', {KM_MOD_LCTRL}}, + KeyMod {L'd'}, }); - test_to_string("UP", { - KeyMod::key(KEY_UP) + test_to_string(L"UP", { + KeyMod::key(KM_KEY_UP) }); - test_to_string("DOWN", { - KeyMod::key(KEY_DOWN) + test_to_string(L"DOWN", { + KeyMod::key(KM_KEY_DOWN) }); - test_to_string("LEFT", { - KeyMod::key(KEY_LEFT) + test_to_string(L"LEFT", { + KeyMod::key(KM_KEY_LEFT) }); - test_to_string("RIGHT", { - KeyMod::key(KEY_RIGHT) + test_to_string(L"RIGHT", { + KeyMod::key(KM_KEY_RIGHT) }); - test_to_string("C-UP", { - KeyMod::key(KEY_UP, {MOD_LCTRL}) + test_to_string(L"C-UP", { + KeyMod::key(KM_KEY_UP, {KM_MOD_LCTRL}) }); - test_to_string("A-LEFT", { - KeyMod::key(KEY_LEFT, {MOD_ALT}), + test_to_string(L"A-LEFT", { + KeyMod::key(KM_KEY_LEFT, {KM_MOD_ALT}), }); - test_to_string("C-A-RIGHT", { - KeyMod::key(KEY_RIGHT, {MOD_LCTRL, MOD_ALT}), + test_to_string(L"C-A-RIGHT", { + KeyMod::key(KM_KEY_RIGHT, {KM_MOD_LCTRL, KM_MOD_ALT}), }); - test_from_string("", ""); + test_from_string(L"", L""); - test_from_string("a", "a"); - test_from_string("a", " a"); - test_from_string("a", "a "); + test_from_string(L"a", L"a"); + test_from_string(L"a", L" a"); + test_from_string(L"a", L"a "); - test_from_string("C-a", "C-a"); - test_from_string("C-a", " C-a "); - test_from_string("A-a", "A-a"); - test_from_string("A-a", " A-a "); + test_from_string(L"C-a", L"C-a"); + test_from_string(L"C-a", L" C-a "); + test_from_string(L"A-a", L"A-a"); + test_from_string(L"A-a", L" A-a "); - test_from_string("C-A-a", " A-C-a "); - test_from_string("C-A-a", " C-A-a "); + test_from_string(L"C-A-a", L" A-C-a "); + test_from_string(L"C-A-a", L" C-A-a "); - test_from_string("C-A-a b C-c", " C-A-a b C-c"); + test_from_string(L"C-A-a b C-c", L" C-A-a b C-c"); - test_from_string("C-A-LEFT RIGHT C-UP", - " C-A-LEFT RIGHT C-UP"); + test_from_string(L"C-A-LEFT RIGHT C-UP", + L" C-A-LEFT RIGHT C-UP"); - REQUIRE_THROWS_AS(Shortcut { "C-A-DUCK" }, invalid_shortcut_error); + REQUIRE_THROWS_AS(Shortcut { L"C-A-DUCK" }, invalid_shortcut_error); }