CInputManager.h
Code: Select all
#ifndef CINPUTMANAGER_H
#define CINPUTMANAGER_H
#include <math.h>
#include <vector>
#include <list>
using namespace std;
#include <irrlicht.h>
class CInputManager : public irr::IEventReceiver
{
private:
static const int KEYEVENTTYPES = 3; //releasedcall, shift, control
static const int GUIEVENTTYPES = 24;
vector< vector< list< void (*)(irr::SEvent event) > > > m_KeyCallerArray;
vector< list< void (*)(irr::SEvent event) > > m_MouseCallerArray;
struct SGuiPtr
{
irr::gui::IGUIElement *guiElementPtr;
vector< list< void (*)(irr::SEvent event) > > eventType;
};
list< SGuiPtr > m_GuiCallerArray;
int calcKeyEventType(bool released, bool shift, bool ctrl);
bool isCallbackInList(void (*callback)(irr::SEvent), list<void (*)(irr::SEvent)>* listToCheck);
public:
CInputManager();
virtual bool OnEvent(const irr::SEvent& event);
bool registerKeyEvent(irr::EKEY_CODE key, void (*callback)(irr::SEvent), bool ctrl = false, bool shift = false, bool released = false, bool allowMultiple = false);
void removeKeyEvent(irr::EKEY_CODE key, void (*callback)(irr::SEvent), bool ctrl = false, bool shift = false, bool released = false);
bool registerMouseEvent(irr::EMOUSE_INPUT_EVENT mouseEvent, void (*callback)(irr::SEvent), bool allowMultiple = false);
void removeMouseEvent(irr::EMOUSE_INPUT_EVENT mouseEvent, void (*callback)(irr::SEvent));
bool registerGUIEvent(irr::gui::IGUIElement* elementPtr, irr::gui::EGUI_EVENT_TYPE guiEvent, void (*callback)(irr::SEvent), bool allowMultiple = false);
void removeGUIEvent(irr::gui::IGUIElement* elementPtr, irr::gui::EGUI_EVENT_TYPE guiEvent, void (*callback)(irr::SEvent));
void removeGUIEvent(irr::gui::IGUIElement* elementPtr);
};
#endif
Code: Select all
#include "CInputManager.h"
CInputManager::CInputManager()
{
m_KeyCallerArray.resize(irr::KEY_KEY_CODES_COUNT);
m_MouseCallerArray.resize(irr::EMIE_COUNT);
}
bool CInputManager::OnEvent(const irr::SEvent& event)
{
if(event.EventType == irr::EET_KEY_INPUT_EVENT)
{
if(m_KeyCallerArray[event.KeyInput.Key].size() != (pow((float)2,KEYEVENTTYPES)))
return false;
int keyEventType = calcKeyEventType(!event.KeyInput.PressedDown, event.KeyInput.Shift, event.KeyInput.Control);
list<void (*)(irr::SEvent event)>::iterator it = m_KeyCallerArray[event.KeyInput.Key][keyEventType].begin();
for(; it != m_KeyCallerArray[event.KeyInput.Key][keyEventType].end(); it++)
(**it)(event);
}
else if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
{
list<void (*)(irr::SEvent event)>::iterator it = m_MouseCallerArray[event.MouseInput.Event].begin();
for(; it != m_MouseCallerArray[event.MouseInput.Event].end(); it++)
(**it)(event);
}
else if(event.EventType == irr::EET_GUI_EVENT)
{
list< SGuiPtr >::iterator itElement = m_GuiCallerArray.begin();
for(; itElement != m_GuiCallerArray.end(); itElement++)
{
if((*itElement).guiElementPtr = event.GUIEvent.Caller)
{
list< void (*)(irr::SEvent event) >::iterator itCalls = (*itElement).eventType[event.GUIEvent.EventType].begin();
for(; itCalls != (*itElement).eventType[event.GUIEvent.EventType].end(); itCalls++)
{
(**itCalls)(event);
}
break;
}
}
}
return false;
}
bool CInputManager::isCallbackInList(void (*callback)(irr::SEvent), list<void (*)(irr::SEvent)>* listToCheck)
{
list<void (*)(irr::SEvent event)>::iterator it = listToCheck->begin();
for(; it != listToCheck->end(); it++)
if(*it == callback)
return true;
return false;
}
bool CInputManager::registerKeyEvent(irr::EKEY_CODE key, void (*callback)(irr::SEvent), bool ctrl, bool shift, bool released, bool allowMultiple)
{
if(m_KeyCallerArray[key].size() != (pow((float)2,KEYEVENTTYPES)))
m_KeyCallerArray[key].resize((int)(pow((float)2,KEYEVENTTYPES)));
int keyEventType = calcKeyEventType(released, shift, ctrl);
if(allowMultiple == false && isCallbackInList(callback, &m_KeyCallerArray[key][keyEventType]))
return false;
m_KeyCallerArray[key][keyEventType].push_back(callback);
return true;
}
void CInputManager::removeKeyEvent(irr::EKEY_CODE key, void (*callback)(irr::SEvent), bool ctrl, bool shift, bool released)
{
if(m_KeyCallerArray[key].size() != (pow((float)2,KEYEVENTTYPES)))
return;
int keyEventType = calcKeyEventType(released, shift, ctrl);
m_KeyCallerArray[key][keyEventType].remove(callback);
}
int CInputManager::calcKeyEventType(bool released, bool shift, bool ctrl)
{
int keyEventType = 0;
keyEventType |= (int)ctrl << 2;
keyEventType |= (int)shift << 1;
keyEventType |= (int)released;
return keyEventType;
}
bool CInputManager::registerMouseEvent(irr::EMOUSE_INPUT_EVENT mouseEvent, void (*callback)(irr::SEvent), bool allowMultiple)
{
if(allowMultiple == false && isCallbackInList(callback, &m_MouseCallerArray[mouseEvent]))
return false;
m_MouseCallerArray[mouseEvent].push_back(callback);
return true;
}
void CInputManager::removeMouseEvent(irr::EMOUSE_INPUT_EVENT mouseEvent, void (*callback)(irr::SEvent))
{
m_MouseCallerArray[mouseEvent].remove(callback);
}
bool CInputManager::registerGUIEvent(irr::gui::IGUIElement* elementPtr, irr::gui::EGUI_EVENT_TYPE guiEvent, void (*callback)(irr::SEvent), bool allowMultiple)
{
list< SGuiPtr >::iterator it = m_GuiCallerArray.begin();
for(; it != m_GuiCallerArray.end(); it++)
{
if((*it).guiElementPtr = elementPtr)
{
if(allowMultiple == false && isCallbackInList(callback, &((*it).eventType[guiEvent])))
return false;
(*it).eventType[guiEvent].push_back(callback);
return true;
}
}
vector< list< void (*)(irr::SEvent event) > > eventType(GUIEVENTTYPES);
SGuiPtr guiPtr = {elementPtr, eventType};
guiPtr.eventType[guiEvent].push_back(callback);
m_GuiCallerArray.push_back(guiPtr);
return true;
}
void CInputManager::removeGUIEvent(irr::gui::IGUIElement* elementPtr, irr::gui::EGUI_EVENT_TYPE guiEvent, void (*callback)(irr::SEvent))
{
list< SGuiPtr >::iterator it = m_GuiCallerArray.begin();
for(; it != m_GuiCallerArray.end(); it++)
{
if((*it).guiElementPtr = elementPtr)
{
(*it).eventType[guiEvent].remove(callback);
break;
}
}
}
void CInputManager::removeGUIEvent(irr::gui::IGUIElement* elementPtr)
{
list< SGuiPtr >::iterator it = m_GuiCallerArray.begin();
for(; it != m_GuiCallerArray.end(); it++)
{
if((*it).guiElementPtr = elementPtr)
{
m_GuiCallerArray.erase(it);
break;
}
}
}
Code: Select all
//telling irrlicht about it
CInputManager inputManager;
deviceParameter.EventReceiver = &inputManager;
IrrlichtDevice *device = createDeviceEx(deviceParameter);
//the callback itself
void run(SEvent event)
{
//...
}
//ctrl + Q for calling void run(SEvent event)
inputManager.registerKeyEvent(KEY_KEY_Q, run, true);
//left mousebutton released calls run(...)
inputManager.registerMouseEvent(EMIE_MMOUSE_LEFT_UP, run);
//a button used to call run(...)
gui::IGUIButton* tmp = env->addButton(core::rect<s32>(100,100,200,300), 0, -1, L"Quit", L"quits...");
inputManager.registerGUIEvent(tmp, gui::EGET_BUTTON_CLICKED, run);
//and to delete them...
inputManager.removeKeyEvent(KEY_KEY_Q, run, true);
inputManager.removeMouseEvent(EMIE_MMOUSE_LEFT_UP, run);
inputManager.removeGUIEvent(tmp, gui::EGET_BUTTON_CLICKED, run);
what you guys think about it?