Is my user event handling ok ? (glfw/c++) So this is how i do it: On creation, my window object (GlfwWindow * is passed in) creates an EventHandler, which holds a data structure for objects to register themselves and offers virtual methods for the c-style callback functions (code for the cursor callback, not every callback is implemented yet). In EventHandler.h/.cpp: typedef enum eventType : unsigned int { MOUSE_MOVE = 0b1, MOUSE_BUTTON = 0b10, MOUSE_SCROLL = 0b100, KEY = 0b1000, CHAR = 0b10000, FRAMEBUFFER_RESIZE = 0b100000 } eventType; std::vector EventHandler::s_registeredObjects {}; EventHandler::EventHandler( GlfwWindow *win ) : m_window { win } { glfwSetCursorPosCallback( m_window->getWindow(), cursorPosCallback ); ... ... The callback redirects to the virtual method: // static void EventHandler::cursorPosCallback( GLFWwindow *w, double x, double y ) { EventHandler *e = reinterpret_cast( glfwGetWindowUserPointer( w ) ); e->onMouseMove( (float)x, (float)y ); } The virtual method iterates over registered objects and calls their respective overriden methods, that can return a bool if they don't want anybody else to handle the event: // virtual bool EventHandler::onMouseMove( float x, float y ) { bool handled = false; for( RegisteredObject &obj : s_registeredObjects ) { if( obj.types & MOUSE_MOVE ) { //handled = reinterpret_cast(obj.object)->onMouseMove( x, y ); handled = obj.object->onMouseMove( x, y ); if( handled ) break; } } return handled; } A class that wants to receive user events must inherit from EventHandler and register the events it wants to receive via a method from the eventhandler, via a simple bit field (in the first code snippet): void EventHandler::registerObject( RegisteredObject &obj ) { bool found = false; for( RegisteredObject &r : s_registeredObjects ) { if( r.object == obj.object ) { Logbook::getInstance().logMsg( Logbook::WINDOW, Logbook::WARNING, "Ignoring try to register an already registered object with the event handler." ); found = true; } } if( !found ) s_registeredObjects.push_back( obj ); } And overrides the inherited virtual method: // virtual bool Camera::onMouseMove( float x, float y ) { bool handled{ false }; ... do mouse move stuff ... return handled; } // onMouseMove() It works, for Camera, UI interface and my drawing apps. What do you think ? It is probably a standard, though i have seen more complicated solutions. Have i missed something ? Could it be done better with the window user pointer, whose function i haven't really understood ? https://ift.tt/eA8V8J
So this is how i do it: On creation, my window object (GlfwWindow * is passed in) creates an EventHandler, which holds a data structure for objects to register themselves and offers virtual methods for the c-style callback functions (code for the cursor callback, not every callback is implemented yet). In EventHandler.h/.cpp: typedef enum eventType : unsigned int { MOUSE_MOVE = 0b1, MOUSE_BUTTON = 0b10, MOUSE_SCROLL = 0b100, KEY = 0b1000, CHAR = 0b10000, FRAMEBUFFER_RESIZE = 0b100000 } eventType; std::vector<EventHandler::RegisteredObject> EventHandler::s_registeredObjects {}; EventHandler::EventHandler( GlfwWindow *win ) : m_window { win } { glfwSetCursorPosCallback( m_window->getWindow(), cursorPosCallback ); ... ... The callback redirects to the virtual method: // static void EventHandler::cursorPosCallback( GLFWwindow *w, double x, double y ) { EventHandler *e = reinterpret_cast<EventHandler *>( glfwGetWindowUserPointer( w ) ); e->onMouseMove( (float)x, (float)y ); } The virtual method iterates over registered objects and calls their respective overriden methods, that can return a bool if they don't want anybody else to handle the event: // virtual bool EventHandler::onMouseMove( float x, float y ) { bool handled = false; for( RegisteredObject &obj : s_registeredObjects ) { if( obj.types & MOUSE_MOVE ) { //handled = reinterpret_cast<EventHandler *>(obj.object)->onMouseMove( x, y ); handled = obj.object->onMouseMove( x, y ); if( handled ) break; } } return handled; } A class that wants to receive user events must inherit from EventHandler and register the events it wants to receive via a method from the eventhandler, via a simple bit field (in the first code snippet): void EventHandler::registerObject( RegisteredObject &obj ) { bool found = false; for( RegisteredObject &r : s_registeredObjects ) { if( r.object == obj.object ) { Logbook::getInstance().logMsg( Logbook::WINDOW, Logbook::WARNING, "Ignoring try to register an already registered object with the event handler." ); found = true; } } if( !found ) s_registeredObjects.push_back( obj ); } And overrides the inherited virtual method: // virtual bool Camera::onMouseMove( float x, float y ) { bool handled{ false }; ... do mouse move stuff ... return handled; } // onMouseMove() It works, for Camera, UI interface and my drawing apps. What do you think ? It is probably a standard, though i have seen more complicated solutions. Have i missed something ? Could it be done better with the window user pointer, whose function i haven't really understood ?
from GameDev.net http://bit.ly/2LKHJrw
from GameDev.net http://bit.ly/2LKHJrw
ليست هناك تعليقات