module; #include #include #include export module VUI:Input; import :InputCodes; import :Keys; namespace VUI { struct WindowManager; struct Window; constexpr uint32_t DownMask = 1; constexpr uint32_t RepeatMask = 1 << 2; static std::array s_Keys{}; static constexpr std::array InputKeys = InitKeys(); export struct Input { static bool IsKeyDown(const KeyCodes key) { return s_Keys[std::to_underlying(key)] & DownMask; } static bool IsKeyPressed(const KeyCodes key) { const auto value = s_Keys[std::to_underlying(key)]; return value & DownMask && !(value & RepeatMask); } static bool IsKeyRepeat(const KeyCodes key) { return s_Keys[std::to_underlying(key)] & RepeatMask; } private: static void UpdateKey(uint32_t key, bool isDown); static void PostFrameUpdate(); friend WindowManager; friend Window; }; void Input::UpdateKey(const uint32_t key, const bool isDown) { assert(key < InputKeys.size() && "Keycode out of range"); const uint8_t keyCode = std::to_underlying(InputKeys[key]); uint8_t value = s_Keys[keyCode]; if (isDown) { value |= DownMask; } else { value &= ~(DownMask | RepeatMask); } s_Keys[keyCode] = value; } void Input::PostFrameUpdate() { for (uint8_t &s_key : s_Keys) s_key |= s_key & DownMask ? RepeatMask : 0; } } // namespace VUI