1
\$\begingroup\$

I'm using SDL2 in my game engine and have created custom event types that use the data from SDL_Event. This works well within my own code, but it becomes problematic with ImGui (and other libraries that rely on SDL) because ImGui expects SDL_Event for ImGui_ImplSDL2_ProcessEvent(), but the editor (which uses ImGui) doesn't have access to the original event object.

Looking at the ImGui_ImplSDL2_ProcessEvent() implementation, it appears to be a convenience function, so I should be able to reuse the same code with my own events. However, getting this to work has been a bit of a hassle because for things like key presses I need to convert the key to a SDL key and then to a ImGui key, so I'm curious what else I can do. I'm thinking along the lines of exposing the SDL_Event somehow, but I'm also wondering if perhaps it's better to just ditch the SDL abstraction/wrapping altogether?

class Event { public: virtual ~Event() = default; virtual EventType GetEventType() const = 0; bool WasHandled() const { return mHandled; } void SetHandled(bool handled) { mHandled = handled; } private: bool mHandled = false; }; class KeyEvent : public Event { public: enum class KeyAction { Pressed, Released, Repeat }; int GetKeyCode() const { return mKeyCode; } int GetModifiers() const { return mModifiers; } KeyAction GetAction() const { return mAction; } protected: KeyEvent(int keyCode, int modifiers, KeyAction action) : mKeyCode(keyCode), mModifiers(modifiers), mAction(action) { } private: int mKeyCode; int mModifiers; KeyAction mAction; }; class KeyPressedEvent : public KeyEvent { public: KeyPressedEvent(int keyCode, int modifiers, int repeatCount = 0) : KeyEvent(keyCode, modifiers, KeyAction::Pressed), mRepeatCount(repeatCount) { } EventType GetEventType() const override { return EventType::KeyPressed; } static EventType GetStaticType() { return EventType::KeyPressed; } int GetRepeatCount() const { return mRepeatCount; } private: int mRepeatCount; }; void Platform::PollInput() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: { if (mEventCallback) { KeyPressedEvent keyPressedEvent(event.key.keysym.sym, event.key.repeat != 0); mEventCallback(keyPressedEvent); } break; } } } } void Application::OnEvent(Event& event) { EventDispatcher dispatcher(event); dispatcher.Dispatch<KeyReleasedEvent>([this](KeyReleasedEvent& e) { this->OnKeyReleased(e.GetKeyCode(), e.GetModifiers()); return true; }); } 
\$\endgroup\$
3
  • 2
    \$\begingroup\$ What you do is not just wrapping SDL events in classes of your own, but translating SDL events to your own event system. What were you trying to achieve with that? \$\endgroup\$ Commented Oct 30 at 7:36
  • \$\begingroup\$ You have two systems of events happening, and you need them to cross communicate. Rather than force one or the other to conform, you create a third system which encompasses both, as @BartvanIngenSchenau mentioned. Keep the inner event data available, but use a wrapper to pull whatever information you need from them and have events in common with both systems extending the same base class, or alternatively create a new event using your system and trigger it. \$\endgroup\$ Commented Oct 30 at 7:55
  • 1
    \$\begingroup\$ @Neil: sounds like a good start for an answer. Maybe we should delete the code section from the question and rewrite it in a purely conceptional manner, then the question may have a chance to survive here, and you can write your comment as an answer. When it comes to the exact coding details, the OP can still ask this question on a different level of abstraction on Gamedev.SE. \$\endgroup\$ Commented Oct 30 at 12:31

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.