/****************************************************************************************** * Chili Direct3D Engine * * Copyright 2018 PlanetChili * * * * This file is part of Chili Direct3D Engine. * * * * Chili Direct3D Engine is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * The Chili Direct3D Engine is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with The Chili Direct3D Engine. If not, see . * ******************************************************************************************/ #pragma once #include #include class Keyboard { friend class Window; public: class Event { public: enum class Type { Press, Release, Invalid }; private: Type type; unsigned char code; public: Event() noexcept : type( Type::Invalid ), code( 0u ) {} Event( Type type,unsigned char code ) noexcept : type( type ), code( code ) {} bool IsPress() const noexcept { return type == Type::Press; } bool IsRelease() const noexcept { return type == Type::Release; } bool IsValid() const noexcept { return type != Type::Invalid; } unsigned char GetCode() const noexcept { return code; } }; public: Keyboard() = default; // 单例设计 Keyboard( const Keyboard& ) = delete; // 单例设计 Keyboard& operator=( const Keyboard& ) = delete; // key event stuff // 根据bitset keystates中指定Key的状态 bool KeyIsPressed( unsigned char keycode ) const noexcept; // 从keyBuffer队列中找到最前面的Event,取出并移出队列 Event ReadKey() noexcept; // 检查keyBuffer队列是否为空 bool KeyIsEmpty() const noexcept; // 重置keyBuffer队列 void FlushKey() noexcept; // char event stuff // 从charBuff队列中找到最前面的Event,取出并移出队列 char ReadChar() noexcept; // 检查charBuffer队列是否为空 bool CharIsEmpty() const noexcept; // 重置charBuffer队列 void FlushChar() noexcept; // 重置keyBuffer和charBuffer队列 void Flush() noexcept; // autorepeat control void EnableAutorepeat() noexcept; void DisableAutorepeat() noexcept; bool AutorepeatIsEnabled() const noexcept; private: void OnKeyPressed( unsigned char keycode ) noexcept; void OnKeyReleased( unsigned char keycode ) noexcept; void OnChar( char character ) noexcept; void ClearState() noexcept; template static void TrimBuffer( std::queue& buffer ) noexcept; private: // Key的数量,Unsigned 256足够对应所有的Key static constexpr unsigned int nKeys = 256u; // 队列长度 static constexpr unsigned int bufferSize = 16u; // Todo bool autorepeatEnabled = false; // 用于存放每个Key的状态,每个bit的值对应一个Key的状态 std::bitset keystates; // 用于存放Key事件的队列 std::queue keybuffer; // 用于存放Char的队列 std::queue charbuffer; };