/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/Engine/Core/Input/InputDevice.h
135 строк
8 KB
C-Core
Re-enabled security relevant warnings (#1339)
25 июн 2024, 12:03
Не верифицирован
25 июн 2024, 12:03
7083663
Код
Авторство
О чём код?
#pragma once #include <Core/CoreDLL.h> #include <Core/Input/Declarations.h> #include <Foundation/Containers/Map.h> #include <Foundation/Reflection/Reflection.h> #include <Foundation/Strings/String.h> #include <Foundation/Time/Time.h> #include <Foundation/Utilities/EnumerableClass.h> /// \brief The base class for all input device types. /// /// An input device is the abstraction of one or more types of input. It is not linked to one physical device. /// For example an input device can represent mouse AND keyboard (through one class). Another input device /// can represent all connected controllers (e.g. up to 4 XBox 360 controllers). /// On OSes where applications can have several windows, an input device may also represent all input from one window, if required. /// /// An input device is the abstraction layer for the hardware input. All keys, movements etc. are mapped to named 'input slots', /// which typically hold a value between 0 and 1, where 0 represents 'not pressed' and 1 represents 'fully pressed'. All hardware /// that has a finite range (such as buttons, analog triggers, the positive/negative axis of analog sticks) should try to map to this /// range. Even mouse coordinates are typically mapped to the 0 to 1 range, where zero means top/left and 1 means bottom/right. /// /// All input handling is usually handled through the ezInputManager class. /// A user should typically not have to interact directly with an input device, unless he needs to call device specific functions /// for advanced configuration. /// /// An input device defines which input slots it exposes to the engine. All input slots are handled by name (e.g. string). /// For example a keyboard would expose the input slots 'keyboard_a' to 'keyboard_z' and other keys. A mouse would expose slots /// such as 'mouse_move_pos_x' and 'mouse_move_neg_x' etc. /// /// By deriving from ezInputDevice you can extend what hardware the engine supports. The derived class should override /// InitializeDevice() to do hardware specific setup. It also needs to override RegisterInputSlots() to register all the input slots /// that it wants to expose from the hardware. E.g. if the device wants to expose values from a gyroscope, it should register /// input slots that represent the rotations around the different axis (one slot each for both positive and negative changes). /// It then also needs to implement UpdateInputSlotValues() and/or ResetInputSlotValues() and possible a device-specific update /// function, to get the input values. For example on Windows a platform/device specific update function is necessary to parse /// the incoming window messages. If such a device specific function is necessary, it also needs to be integrated into the proper /// code (e.g. into the window handling code, to be able to get the window messages). In such a case it might not be possible /// to add such a device purely through a dynamic plugin, but might also need deeper integration into other engine code. class EZ_CORE_DLL ezInputDevice : public ezEnumerable<ezInputDevice, ezReflectedClass> { EZ_DECLARE_ENUMERABLE_CLASS_WITH_BASE(ezInputDevice, ezReflectedClass); EZ_ADD_DYNAMIC_REFLECTION(ezInputDevice, ezReflectedClass); public: /// \brief Default Constructor. ezInputDevice(); /// \brief Allows to query current input values for the given slot float GetInputSlotState(ezStringView sSlot) const; /// \brief Returns true, if the device was 'used' during the last frame, ie. when it generated input due to some user interaction. /// /// This can be used to figure out which device the user is currently using, for example whether mouse/keyboard or a controller is in use. bool HasDeviceBeenUsedLastFrame() const; private: friend class ezInputManager; /// \brief If this type of input device handles character input (typed text with all its formatting), this function returns the last typed /// character. /// /// An input device that handles keyboard input should also have a way to query the real typed character. I.e. by default only the /// individual state of each key is handled, such that we know that the shift key and the a key are pressed. However, the fact that /// this results in an upper case A in typed text also needs to be handled. An OS usually has a way to compute this, for example /// on Windows the WM_CHAR message sends this information. An ezInputDevice derived class should never try to compute this /// itself, but instead query this information from the OS, which will also handle localization. ezUInt32 RetrieveLastCharacter(); /// \brief Calls UpdateHardwareState() on all devices. static void UpdateAllHardwareStates(ezTime tTimeDifference); /// \brief Calls Initialize() and UpdateInputSlotValues() on all devices. static void UpdateAllDevices(); /// \brief Calls ResetInputSlotValues() on all devices. static void ResetAllDevices(); /// \brief Calls RetrieveLastCharacter() on all devices. Returns the first non-null character that any device returned. static ezUInt32 RetrieveLastCharacterFromAllDevices(); protected: /// \brief Calls RegisterInputSlot() on the ezInputManager and passes the parameters through. static void RegisterInputSlot(ezStringView sName, ezStringView sDefaultDisplayName, ezBitflags<ezInputSlotFlags> SlotFlags); // [tested] /// \brief Stores all the values for all input slots that this device handles. /// /// A derived class needs to fill out this map every frame. There are two ways this map can be filled out. /// For devices where you can query the complete state at one point in time (e.g. controllers), you can update the entire /// map inside an overridden UpdateInputSlotValues() function. /// For devices where you get the input only piece-wise and usually only when something changes (e.g. through messages) /// you can also just update the map whenever input arrives. However in such a use-case you sometimes need to manually /// reset the state of certain input slots. For example when a mouse-move message arrives that movement delta is accumulated in /// the map. However, when the mouse stops usually no 'mouse stopped' message is sent but the values in the map need to be /// reset to zero, to prevent the mouse from keeping moving in the engine. /// Do this inside an overridden ResetInputSlotValues() function. You don't need to do this for input slots that /// will reset to zero anyway. ezMap<ezString, float> m_InputSlotValues; // [tested] /// \brief If this input device type handles character input, it should write the last typed character into this variable. /// The ezInputManager calls RetrieveLastCharacter() to query what the user typed last. ezUInt32 m_uiLastCharacter; // [tested] /// \brief Override this if you need to do device specific initialization before the first use. virtual void InitializeDevice() = 0; /// \brief Override this, if you need to query the state of the hardware to update the input slots. /// /// \note This function might be called multiple times before ResetInputSlotValues() is called. /// This will be the case when ezInputManager::PollHardware is used to make more frequent hardware updates /// than input is actually processed. /// Just make sure to always accumulate delta values (such as mouse move values) and don't expect ResetInputSlotValues() /// to be called in tandem with this function and it will be fine. virtual void UpdateInputSlotValues() = 0; /// \brief Override this, if you need to reset certain input slot values to zero, after the ezInputManager is finished with the current /// frame update. virtual void ResetInputSlotValues() {}; // [tested] /// \brief Override this to register all the input slots that this device exposes. /// /// This is called once during initialization. It needs to call RegisterInputSlot() once for every input slot that this device /// exposes to the system. virtual void RegisterInputSlots() = 0; // [tested] /// \brief This function is called once after ezInputManager::Update with the same time delta value. /// It allows to update hardware state, such as the vibration of gamepad motors. virtual void UpdateHardwareState(ezTime tTimeDifference) { EZ_IGNORE_UNUSED(tTimeDifference); } private: /// \brief Calls InitializeDevice() when the device is not yet initialized. void Initialize(); bool m_bInitialized = false; bool m_bGeneratedInputRecently = false; };