Event receiver class not working

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
aeronmike
Posts: 45
Joined: Thu May 24, 2012 5:00 am
Location: Rio de Janeiro, Brazil

Event receiver class not working

Post by aeronmike »

I wrote this event receiver class for my needs based on the "MastEventReceiver".
I create it's object, initialize it and then pass it to my scene manager.

It simply does not work!

It should work like this:
On each event the overrided "OnEvent" captures it, it stores the event into ObEventsData struct. Then, I have a function (not part of the class) that reads the structure and performs my desired action.
I've tried to change that function, my key variables types, but none of these worked. I had also created the "KeyReleased" function, but it still does not work. :(
I believe the problem is my class:

Code: Select all

#include <irrlicht/irrlicht.h>
 
/// Basic debug pre-definitions
#define DEBUG           true   // Used to trigger the internal console debug extension.
#define DBG_OUT         if(DEBUG) std::cout << std::endl    // Simple macro for debug outputs.
#define DBG_STS         if(DEBUG) std::cout << "\t"         // Simple macro for debug output statuses.
#define DBG_NL          if(DEBUG) std::cout << std::endl;   // Simple macro for new line.
#define DBG_FLUSH       if(DEBUG) std::cout.flush();        // Simple macro for flusing the output buffer.
 
/// ====================================================================================
/// AeroEventReceiver
/// ====================================================================================
 
class AeroEventReceiver : public irr::IEventReceiver
{
public:
  enum FGameState { IN_GAME = 1, OUT_GAME };
  enum FKeyState { UP, PRESSED, HELD_DOWN, RELEASED };
  enum FGUIEvent {
    // Here you add whatever element type you're going to use. Do NOT remove "GUI_ID_NONE", since
    // it is needed by this class's constructor for initialization purposes (see below).
    GUI_ID_NONE = 0,
 
    GUI_ID_ROOT_WINDOW = 0x10000,
 
    GUI_ID_RESUME_BUTTON,
    GUI_ID_EXIT_BUTTON
  };
 
  struct SEventsData {
    FKeyState keyboardKeys[irr::KEY_KEY_CODES_COUNT];
    FKeyState mouseKeys[2]; // Left(0), Middle(1) and Right(2).
    FGUIEvent guiEvent;
  } ObEventsData;
 
  void Init(irr::gui::IGUIEnvironment* guiEnv) {
    DBG_OUT << "AeroEventReceiver Init() called.";
    DBG_FLUSH
 
    // First we initialize the keys (keyboard and mouse, respectively).
        DBG_OUT << "Initializing event data structure:";
    DBG_FLUSH
    for(int i = 0; i <= irr::KEY_KEY_CODES_COUNT; i++) {
        ObEventsData.keyboardKeys[i] = UP;
        DBG_OUT << "KEYBOARD KEY[" << i << "] = " << ObEventsData.keyboardKeys[i];
        DBG_FLUSH
      }
 
    for(int i = 0; i <= 2; i++) {
        ObEventsData.mouseKeys[i] = UP;
        DBG_OUT << "MOUSE KEY[" << i << "] = " << ObEventsData.mouseKeys[i];
        DBG_FLUSH
      }
 
    // The GUI event flag.
    ObEventsData.guiEvent = GUI_ID_NONE;
    DBG_OUT << "GUI ID = " << ObEventsData.guiEvent;
    DBG_FLUSH
 
    // And the GUI environment pointer.
    guiEnvironment = guiEnv;
    DBG_OUT << "GUI ENVIRONMENT POINTER = " << guiEnvironment;
    DBG_FLUSH
  }
 
  // Main function for getting events accordingly to the game state.
  void SetGameState(FGameState gameState) {
    DBG_OUT << "SetGameState() called.";
    DBG_FLUSH
 
    GameState = gameState;
 
    DBG_OUT << "GameState variable set to " << GameState;
    DBG_FLUSH
  }
 
  void EndEvents()
  {
    // Keyboard key states
    for (int i = 0; i < irr::KEY_KEY_CODES_COUNT; i++) {
        if (ObEventsData.keyboardKeys[i] == RELEASED) {
            ObEventsData.keyboardKeys[i] = UP;
          }
        if (ObEventsData.keyboardKeys[i] == PRESSED) {
            ObEventsData.keyboardKeys[i] = PRESSED;
          }
      }
    // Mouse button states
    for (int i = 0; i <= 2; i++) {
        if (ObEventsData.mouseKeys[i] == RELEASED) {
            ObEventsData.mouseKeys[i] = UP;
          }
        if (ObEventsData.mouseKeys[i] == PRESSED) {
            ObEventsData.mouseKeys[i] = PRESSED;
          }
      }
  }
 
  bool keyReleased(char keycode) {
    DBG_OUT << "KEYRELEASED() CALLED!";
    DBG_FLUSH
    if(ObEventsData.keyboardKeys[keycode] == RELEASED) return true; else return false;
  }
 
 
protected:
  FGameState GameState;
  irr::gui::IGUIEnvironment* guiEnvironment;
 
  virtual bool OnEvent(const irr::SEvent &event)
  {
    ///////////////////////////
    /// IN-GAME Input Event ///
    ///////////////////////////
    if(GameState == IN_GAME) {
 
        // KEYBOARD EVENT COLLECTING //
        if(event.EventType == irr::EET_KEY_INPUT_EVENT) {
            if(event.KeyInput.PressedDown == true) { // If a key was pressed.
 
                // If the key was not pressed before...
                if(ObEventsData.keyboardKeys[event.KeyInput.Key] != PRESSED) {
                    // Now it is.
                    ObEventsData.keyboardKeys[event.KeyInput.Key] = PRESSED;
                  } else {
                    // If key was already pressed before... Now it is being held down.
                    ObEventsData.keyboardKeys[event.KeyInput.Key] = HELD_DOWN;
                  }
              } else {
 
                // If the key is not being pressed down...
                if(ObEventsData.keyboardKeys[event.KeyInput.Key] != UP) {
                    // So it was released.
                    ObEventsData.keyboardKeys[event.KeyInput.Key] = RELEASED;
                  }
              }
          }
 
        /// AND
 
        // MOUSE EVENT COLLECTING //
        if(event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
 
            // Left mouse button pressed.
            if(event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN) {
                if(ObEventsData.mouseKeys[0] != PRESSED) {
                    ObEventsData.mouseKeys[0] = PRESSED;
                  } else {
                    ObEventsData.mouseKeys[0] = HELD_DOWN;
                  }
              } else {
                if(ObEventsData.mouseKeys[0] != UP) {
                    ObEventsData.mouseKeys[0] = RELEASED;
                  }
              }
            // Middle mouse button pressed.
            if(event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN) {
                if(ObEventsData.mouseKeys[1] != PRESSED) {
                    ObEventsData.mouseKeys[1] = PRESSED;
                  } else {
                    ObEventsData.mouseKeys[1] = HELD_DOWN;
                  }
              } else {
                if(ObEventsData.mouseKeys[1] != UP) {
                    ObEventsData.mouseKeys[1] = RELEASED;
                  }
              }
            // Right mouse button pressed.
            if(event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN) {
                if(ObEventsData.mouseKeys[2] != PRESSED) {
                    ObEventsData.mouseKeys[2] = PRESSED;
                  } else {
                    ObEventsData.mouseKeys[2] = HELD_DOWN;
                  }
              } else {
                if(ObEventsData.mouseKeys[2] != UP) {
                    ObEventsData.mouseKeys[2] = RELEASED;
                  }
              }
          }
      }
 
 
    ////////////////////////////
    /// OUT-GAME Input Event ///
    ////////////////////////////
    if(GameState == OUT_GAME) {
 
        // KEYBOARD EVENT COLLECTING //
        if(event.EventType == irr::EET_KEY_INPUT_EVENT) {
            if(event.KeyInput.PressedDown == true) { // If a key was pressed.
 
                // If the key was not pressed before...
                if(ObEventsData.keyboardKeys[event.KeyInput.Key] != PRESSED) {
                    // Now it is.
                    ObEventsData.keyboardKeys[event.KeyInput.Key] = PRESSED;
                  } else {
                    // If key was already pressed before... Now it is being held down.
                    ObEventsData.keyboardKeys[event.KeyInput.Key] = HELD_DOWN;
                  }
              } else {
 
                // If the key is not being pressed down...
                if(ObEventsData.keyboardKeys[event.KeyInput.Key] != UP) {
                    // So it was released.
                    ObEventsData.keyboardKeys[event.KeyInput.Key] = RELEASED;
                  }
              }
          }
 
        /// OR
 
        // GUI EVENT COLLECTING //
        if(event.EventType == irr::EET_GUI_EVENT) {
 
            // First we need to get the caller element id.
            irr::s32 ID = event.GUIEvent.Caller->getID();
 
            // Then we process the event type. ONLY if a button was clicked.
            if(event.GUIEvent.EventType == irr::gui::EGET_BUTTON_CLICKED) {
                ObEventsData.guiEvent = (FGUIEvent) ID;
              }
          }
      }
 
    // We return FALSE to avoid FPS camera conflicts.
    return false;
  }
};
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Event receiver class not working

Post by CuteAlien »

I have no idea how you can pass an eventreceiver to the SceneManager... you have to pass it to the IrrlichtDevice. Also you have to call device->run() regularly. If that still doesn't work set a breakpoint in OnEvent and check what's happening, maybe your gamestates have never the values you seem to check there.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
aeronmike
Posts: 45
Joined: Thu May 24, 2012 5:00 am
Location: Rio de Janeiro, Brazil

Re: Event receiver class not working

Post by aeronmike »

Sorry sorry! I mean the device, instead.

Also, I have already checked the game states... Everything is OK outside the class. It used to work with MastEventReceiver.
I even keep comparing both classes and also the examples in the tutorials, but anyway I can't find a clear mistake. :(

I have NO ideia of what is going on.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Event receiver class not working

Post by CuteAlien »

That's why you should set a breakpoint and check-out what is going on. And if it's not called at all then something in the intialization is wrong - for example the class-object might be in a scope which is no longer valid at that point (although that would rather crash, so I still suspect the game-states which can be easy seen by using the debugger).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
aeronmike
Posts: 45
Joined: Thu May 24, 2012 5:00 am
Location: Rio de Janeiro, Brazil

Re: Event receiver class not working

Post by aeronmike »

I solved it. :)

It was a missing line (out of the class), letting a variable undefined.

I also enhanced the class. As soon as it is OK for me to release it, I'll do it. :P

Thanks.
Post Reply