#pragma once #include "DI/auto_wirable.hpp" #include "interfaces/cursor.hpp" #include "engine/data/vector2.hpp" #include #include #include #include #include constexpr std::string_view MOVE_CURSOR_UP = "{esc}[{amount}A"; constexpr std::string_view MOVE_CURSOR_DOWN = "{esc}[{amount}B"; constexpr std::string_view MOVE_CURSOR_LEFT = "{esc}[{amount}D"; constexpr std::string_view MOVE_CURSOR_RIGHT = "{esc}[{amount}C"; constexpr fmt::string_view MOVE_CURSOR_TO = "{esc}[{row};{column}H"; constexpr fmt::string_view REQUEST_CURSOR_POSITION = "{esc}[6n"; constexpr fmt::string_view CURSOR_VISIBLE = "{esc}[?25h"; constexpr fmt::string_view CURSOR_INVISIBLE = "{esc}[?25l"; const std::unordered_map direction_format_map = {{Vector2::up(), MOVE_CURSOR_UP}, {Vector2::down(), MOVE_CURSOR_DOWN}, {Vector2::left(), MOVE_CURSOR_LEFT}, {Vector2::right(), MOVE_CURSOR_RIGHT}}; class CursorController : public ICursorController, public AutoWirable { public: CursorController() noexcept; void move(const Vector2 &direction, const uint32_t &amount) noexcept override; void move_to(const Vector2 &position, bool silent) noexcept override; [[nodiscard]] Vector2 where() const noexcept override; void ensure_position() noexcept override; void hide() noexcept override; void show() noexcept override; void subscribe(const Event &event, const Subscriber &subscriber) noexcept override; void notify_subscribers(const Event &event, const Context &context) const noexcept override; private: Vector2 _position; std::unordered_map> _subscribers; };