From 6dc60a2082a4e57347789d3c26db0978194e4dc4 Mon Sep 17 00:00:00 2001 From: dean11 Date: Tue, 25 Feb 2014 14:20:11 +0100 Subject: [PATCH] Input - Added more functionality, custom tag and all-in-one key callback --- Code/Misc/Input/Include/InputManager.h | 5 + Code/Misc/Input/Include/Keyboard.h | 49 +++++-- Code/Misc/Input/Source/InputManager.cpp | 8 ++ Code/Misc/Input/Source/Keyboard.cpp | 128 +++++++++++++----- .../Misc/Input/Source/Win32/Win32Keyboard.cpp | 23 +++- 5 files changed, 159 insertions(+), 54 deletions(-) diff --git a/Code/Misc/Input/Include/InputManager.h b/Code/Misc/Input/Include/InputManager.h index 1feff9cf..964a47bc 100644 --- a/Code/Misc/Input/Include/InputManager.h +++ b/Code/Misc/Input/Include/InputManager.h @@ -25,6 +25,11 @@ namespace Input */ static InputManager* CreateInputManager (); + /** + * @return Destroys the default input manager. + */ + static void DestroyInputManager (); + /** * @return Destroys a input manager. */ diff --git a/Code/Misc/Input/Include/Keyboard.h b/Code/Misc/Input/Include/Keyboard.h index b6708604..f29bcde1 100644 --- a/Code/Misc/Input/Include/Keyboard.h +++ b/Code/Misc/Input/Include/Keyboard.h @@ -135,11 +135,23 @@ namespace Input }; } //----------------------------------------------------------------------------------------------------------------------------- + namespace Struct + { + struct KeyboardEventData + { + Enum::SAKI key; + Enum::ButtonState state; + Keyboard* sender; + void* tag; + }; + } + //----------------------------------------------------------------------------------------------------------------------------- namespace Typedefs { - typedef void(*OnKeyPressCallback)(Enum::SAKI key, Keyboard* sender); - typedef void(*OnKeyDownCallback)(Enum::SAKI key, Keyboard* sender); - typedef void(*OnKeyReleaseCallback)(Enum::SAKI key, Keyboard* sender); + typedef void(*OnKeyEventCallback) (const Struct::KeyboardEventData& eventData); + typedef void(*OnKeyPressCallback) (Enum::SAKI key, Keyboard* sender, void* tag); + typedef void(*OnKeyDownCallback) (Enum::SAKI key, Keyboard* sender, void* tag); + typedef void(*OnKeyReleaseCallback) (Enum::SAKI key, Keyboard* sender, void* tag); } //----------------------------------------------------------------------------------------------------------------------------- @@ -149,9 +161,10 @@ namespace Input class KeyboardEvent { public: - virtual void OnKeyPress(Enum::SAKI key, Keyboard* sender) { } - virtual void OnKeyDown(Enum::SAKI key, Keyboard* sender) { } - virtual void OnKeyRelease(Enum::SAKI key, Keyboard* sender) { } + virtual void OnKeyEvent (const Struct::KeyboardEventData& eventData) { } + virtual void OnKeyPress (Enum::SAKI key, Keyboard* sender) { } + virtual void OnKeyDown (Enum::SAKI key, Keyboard* sender) { } + virtual void OnKeyRelease (Enum::SAKI key, Keyboard* sender) { } }; public: /* Manual check functions */ @@ -166,18 +179,25 @@ namespace Input virtual void Deactivate () override = 0; virtual bool IsActive() override = 0; - public: /* global subscribe callback functions */ - void AddOnKeyPressCallback (Typedefs::OnKeyPressCallback func); - void AddOnKeyDownCallback (Typedefs::OnKeyDownCallback func); - void AddOnKeyReleaseCallback (Typedefs::OnKeyReleaseCallback func); + public: /* object subscribe functions */ + void AddKeyboardEvent (KeyboardEvent* object); + void RemoveKeyboardEvent (KeyboardEvent* object); + void operator+= (KeyboardEvent* object); + void operator-= (KeyboardEvent* object); - void RemoveOnKeyPressCallback (Typedefs::OnKeyPressCallback func); - void RemoveOnKeyDownCallback (Typedefs::OnKeyDownCallback func); + public: /* global subscribe callback functions */ + void AddOnKeyEventCallback (Typedefs::OnKeyEventCallback func, void* tag); + void AddOnKeyPressCallback (Typedefs::OnKeyPressCallback func, void* tag); + void AddOnKeyDownCallback (Typedefs::OnKeyDownCallback func, void* tag); + void AddOnKeyReleaseCallback (Typedefs::OnKeyReleaseCallback func, void* tag); + + void RemoveOnKeyEventCallback (Typedefs::OnKeyEventCallback func); + void RemoveOnKeyPressCallback (Typedefs::OnKeyPressCallback func); + void RemoveOnKeyDownCallback (Typedefs::OnKeyDownCallback func); void RemoveOnKeyReleaseCallback (Typedefs::OnKeyReleaseCallback func); public: - void operator+= (KeyboardEvent* object); - void operator-= (KeyboardEvent* object); + void BindTextTarget( ::std::wstring *field ); void ReleaseTextTarget(); @@ -189,6 +209,7 @@ namespace Input Keyboard(); protected: /* Internal event proc */ + void InternalOnEvent(Struct::KeyboardEventData& data); void InternalOnKeyPress(Enum::SAKI key); void InternalOnKeyDown(Enum::SAKI key); void InternalOnKeyRelease(Enum::SAKI key); diff --git a/Code/Misc/Input/Source/InputManager.cpp b/Code/Misc/Input/Source/InputManager.cpp index 48bb828f..8e13dd6e 100644 --- a/Code/Misc/Input/Source/InputManager.cpp +++ b/Code/Misc/Input/Source/InputManager.cpp @@ -57,6 +57,14 @@ InputManager* InputManager::CreateInputManager() { return CreateManager(); } +void InputManager::DestroyInputManager() +{ + if(!defaultInstance) return; + + defaultInstance->Destroy(); + delete defaultInstance; + defaultInstance = 0; +} void InputManager::DestroyInputManager(InputManager* inputSystem) { if(!inputSystem) return; diff --git a/Code/Misc/Input/Source/Keyboard.cpp b/Code/Misc/Input/Source/Keyboard.cpp index a35f75a5..b94d5dce 100644 --- a/Code/Misc/Input/Source/Keyboard.cpp +++ b/Code/Misc/Input/Source/Keyboard.cpp @@ -12,12 +12,14 @@ struct Keyboard::KeyboardCallbackList { enum CallbackDataType { + CallbackDataType_OnEvent, CallbackDataType_OnPress, CallbackDataType_OnDown, CallbackDataType_OnRelease } type; union CallbackData { + Typedefs::OnKeyEventCallback keyEventCallback; Typedefs::OnKeyPressCallback keyPressCallback; Typedefs::OnKeyDownCallback keyDownCallback; Typedefs::OnKeyReleaseCallback keyReleaseCallback; @@ -29,7 +31,8 @@ struct Keyboard::KeyboardCallbackList operator bool(){ return this->keyDownCallback != 0; } } function; KeyboardCallbackList *next; - KeyboardCallbackList(CallbackData func, CallbackDataType t) :function(func), next(0), type(t) { } + void* tag; + KeyboardCallbackList(CallbackData func, CallbackDataType t, void* ct) :function(func), next(0), type(t), tag(ct) { } }; void ClearList(Keyboard::KeyboardCallbackList* first) @@ -44,7 +47,7 @@ void ClearList(Keyboard::KeyboardCallbackList* first) delete removee; } } -void AddToList(Keyboard::KeyboardCallbackList* first, Keyboard::KeyboardCallbackList::CallbackData data, Keyboard::KeyboardCallbackList::CallbackDataType type) +void AddToList(Keyboard::KeyboardCallbackList* first, Keyboard::KeyboardCallbackList::CallbackData data, Keyboard::KeyboardCallbackList::CallbackDataType type, void* tag) { Keyboard::KeyboardCallbackList *w = first; Keyboard::KeyboardCallbackList *prev = first; @@ -54,7 +57,7 @@ void AddToList(Keyboard::KeyboardCallbackList* first, Keyboard::KeyboardCallback Keyboard::KeyboardCallbackList::CallbackData f; f = data; - prev->next = new Keyboard::KeyboardCallbackList(f, type); + prev->next = new Keyboard::KeyboardCallbackList(f, type, tag); } void RemoveFromList(Keyboard::KeyboardCallbackList* first, Keyboard::KeyboardCallbackList::CallbackData data) { @@ -112,6 +115,27 @@ Keyboard::~Keyboard() } +void Keyboard::InternalOnEvent(Struct::KeyboardEventData& data) +{ + for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) + { + if(this->keyEventSubscrivers[i]) + { + this->keyEventSubscrivers[i]->OnKeyEvent(data); + } + } + KeyboardCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == KeyboardCallbackList::CallbackDataType_OnEvent) + { + data.tag = w->tag; + w->function.keyEventCallback(data); + } + w = w->next; + } +} void Keyboard::InternalOnKeyPress(Enum::SAKI key) { for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) @@ -126,7 +150,9 @@ void Keyboard::InternalOnKeyPress(Enum::SAKI key) { if(w->function) if (w->type == KeyboardCallbackList::CallbackDataType_OnPress) - w->function.keyPressCallback(key, this); + { + w->function.keyPressCallback(key, this, w->tag); + } w = w->next; } } @@ -144,7 +170,7 @@ void Keyboard::InternalOnKeyDown(Enum::SAKI key) { if(w->function) if (w->type == KeyboardCallbackList::CallbackDataType_OnDown) - w->function.keyDownCallback(key, this); + w->function.keyDownCallback(key, this, w->tag); w = w->next; } } @@ -162,46 +188,26 @@ void Keyboard::InternalOnKeyRelease(Enum::SAKI key) { if(w->function) if (w->type == KeyboardCallbackList::CallbackDataType_OnRelease) - w->function.keyReleaseCallback(key, this); + w->function.keyReleaseCallback(key, this, w->tag); w = w->next; } } -void Keyboard::AddOnKeyPressCallback (OnKeyPressCallback func) +void Keyboard::AddKeyboardEvent(KeyboardEvent* object) { - KeyboardCallbackList::CallbackData d; - d.keyPressCallback = func; - if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnPress); - else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnPress); -} -void Keyboard::AddOnKeyDownCallback (OnKeyDownCallback func) -{ - KeyboardCallbackList::CallbackData d; - d.keyDownCallback = func; - if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnDown); - else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnDown); -} -void Keyboard::AddOnKeyReleaseCallback (OnKeyReleaseCallback func) -{ - KeyboardCallbackList::CallbackData d; - d.keyReleaseCallback = func; - if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnRelease); - else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnRelease); -} + if(ExistsInList(this->keyEventSubscrivers, object)) return; -void Keyboard::RemoveOnKeyPressCallback (OnKeyPressCallback func) -{ - RemoveFromList(this->callbackList, func); + this->keyEventSubscrivers.push_back(object); } -void Keyboard::RemoveOnKeyDownCallback (OnKeyDownCallback func) +void Keyboard::RemoveKeyboardEvent(KeyboardEvent* object) { - RemoveFromList(this->callbackList, func); + int i = -1; + if((i = ExistsInList(this->keyEventSubscrivers, object))) + { + std::swap(this->keyEventSubscrivers[i], this->keyEventSubscrivers[this->keyEventSubscrivers.size() - 1]); + this->keyEventSubscrivers.resize(this->keyEventSubscrivers.size() - 1); + } } -void Keyboard::RemoveOnKeyReleaseCallback (OnKeyReleaseCallback func) -{ - RemoveFromList(this->callbackList, func); -} - void Keyboard::operator+= (KeyboardEvent* object) { if(ExistsInList(this->keyEventSubscrivers, object)) return; @@ -218,6 +224,56 @@ void Keyboard::operator-= (KeyboardEvent* object) } } +void Keyboard::AddOnKeyEventCallback (OnKeyEventCallback func, void* tag) +{ + KeyboardCallbackList::CallbackData d; + d.keyEventCallback = func; + if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnEvent, tag); + else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnEvent, tag); +} +void Keyboard::AddOnKeyPressCallback (OnKeyPressCallback func, void* tag) +{ + KeyboardCallbackList::CallbackData d; + d.keyPressCallback = func; + if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnPress, tag); + else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnPress, tag); +} +void Keyboard::AddOnKeyDownCallback (OnKeyDownCallback func, void* tag) +{ + KeyboardCallbackList::CallbackData d; + d.keyDownCallback = func; + if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnDown, tag); + else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnDown, tag); +} +void Keyboard::AddOnKeyReleaseCallback (OnKeyReleaseCallback func, void* tag) +{ + KeyboardCallbackList::CallbackData d; + d.keyReleaseCallback = func; + if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnRelease, tag); + else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnRelease, tag); +} + +void Keyboard::RemoveOnKeyEventCallback (OnKeyEventCallback func) +{ + Keyboard::KeyboardCallbackList::CallbackData temp; + temp.keyEventCallback = func; + RemoveFromList(this->callbackList, temp); +} +void Keyboard::RemoveOnKeyPressCallback (OnKeyPressCallback func) +{ + RemoveFromList(this->callbackList, func); +} +void Keyboard::RemoveOnKeyDownCallback (OnKeyDownCallback func) +{ + RemoveFromList(this->callbackList, func); +} +void Keyboard::RemoveOnKeyReleaseCallback (OnKeyReleaseCallback func) +{ + RemoveFromList(this->callbackList, func); +} + + + void Keyboard::BindTextTarget( ::std::wstring *field ) { this->textTarget = field; diff --git a/Code/Misc/Input/Source/Win32/Win32Keyboard.cpp b/Code/Misc/Input/Source/Win32/Win32Keyboard.cpp index 475a9e85..84e3eb28 100644 --- a/Code/Misc/Input/Source/Win32/Win32Keyboard.cpp +++ b/Code/Misc/Input/Source/Win32/Win32Keyboard.cpp @@ -66,10 +66,10 @@ void Win32Keyboard::Deactivate () void Win32Keyboard::ProccessKeyboardData (RAWKEYBOARD keyboard) { - if(!this->active) - { - return; - } + if(!this->active) return; + + static Struct::KeyboardEventData keyboardEventData; + memset(&keyboardEventData, 0, sizeof(Struct::KeyboardEventData)); bool isUp = (( keyboard.Flags & RI_KEY_BREAK) != 0); SAKI key = SAKI_Unknown; @@ -86,6 +86,11 @@ void Win32Keyboard::ProccessKeyboardData (RAWKEYBOARD keyboard) this->keys[key].isDown = false; this->keys[key].isE0 = isE0; this->keys[key].makecode = keyboard.MakeCode; + + keyboardEventData.key = key; + keyboardEventData.sender = this; + keyboardEventData.state = Enum::ButtonState_Release; + InternalOnEvent(keyboardEventData); } //The key is pressed. else /*if (k.Flags == RI_KEY_MAKE || k.Flags == (RI_KEY_MAKE | RI_KEY_E0) || k.Flags == (RI_KEY_MAKE | RI_KEY_E1))*/ @@ -93,6 +98,11 @@ void Win32Keyboard::ProccessKeyboardData (RAWKEYBOARD keyboard) if(this->keys[key].isDown) { this->InternalOnKeyDown(key); + + keyboardEventData.key = key; + keyboardEventData.sender = this; + keyboardEventData.state = Enum::ButtonState_Down; + InternalOnEvent(keyboardEventData); } else { @@ -100,6 +110,11 @@ void Win32Keyboard::ProccessKeyboardData (RAWKEYBOARD keyboard) this->keys[key].isDown = true; this->keys[key].isE0 = isE0; this->keys[key].makecode = keyboard.MakeCode; + + keyboardEventData.key = key; + keyboardEventData.sender = this; + keyboardEventData.state = Enum::ButtonState_Press; + InternalOnEvent(keyboardEventData); } } }