Event receiver with null device?

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 with null device?

Post by aeronmike »

Hey

I switched to null device for debugging purposes, but then I realized event receivers does not work with null device.

What could I do to make it to work?

Thanks!
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Event receiver with null device?

Post by CuteAlien »

It still should work... what kind of problem do you have with a null device?
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 with null device?

Post by aeronmike »

I don't think I have a problem with it.. But I believe IT has against me, 'cause it's really not getting to work. :(

I just tried out the simplest possible code. My event receiver works greatly in every situation I tested it. But not working with a null device.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Event receiver with null device?

Post by hybrid »

Maybe show the event receiver so we can participate, or even better a full test app which reproducibly fails in these cases.
aeronmike
Posts: 45
Joined: Thu May 24, 2012 5:00 am
Location: Rio de Janeiro, Brazil

Re: Event receiver with null device?

Post by aeronmike »

OK...

When my device is created:

Code: Select all

AeroEventReceiver ObEventReceiver;
ObEventReceiver.Init();
mainDevice = createDevice(video::EDT_SOFTWARE, dimension2d<u32>(640, 480), 16,
        false, false, false, &ObEventReceiver);
This is a very simple game loop. If you check my event receiver class you'll realize the "ObEventReceiver.EndEventsCollection();"

Code: Select all

while (mainDevice->run()) {
        /// BEGIN ///
 
        /// STAGE A
        // Process events.
        CTRL_ProcessEvents();
 
        /// STAGE B
        videoDvr->beginScene(true, true, video::SColor(SCOLOR_ALPHA, SCOLOR_RED, SCOLOR_GREEN, SCOLOR_BLUE));
        sceneMgr->drawAll();
        guiEnv->drawAll();
        videoDvr->endScene();
 
        /// STAGE C
        ObEventReceiver.EndEventsCollection();
 
        /// END ///
    }
The "CTRL_ProcessEvents();" is a simple function to check if a specific key was pressed and take some actions (ESC, for instance).

And finally this is my event receiver class. It's not yet fully completed, but what it already has works perfectly.

Code: Select all

// Change this to the path where your Irrlicht Header Files are.
#include <iostream>
#include "../includes/Irrlicht-1.7.3/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[3]; // 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
    }
 
    void SetGameState(FGameState gameState)
    {
        DBG_OUT << "SetGameState() called.";
        DBG_FLUSH
 
        GameState = gameState;
 
        DBG_OUT << "GameState variable set to " << GameState;
        DBG_FLUSH
    }
 
    void EndEventsCollection(void)
    {
        EventsCollection = true;
 
        // 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;
            }
        }
 
        ObEventsData.guiEvent = GUI_ID_NONE;
    }
 
protected:
    FGameState GameState;
    irr::gui::IGUIEnvironment* guiEnvironment;
    bool EventsCollection;
 
    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_MMOUSE_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_RMOUSE_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;
    }
};
 
/// ====================================================================================
/// END OF AeroEventReceiver
/// ====================================================================================
However, as I said, when I use "EDT_NULL" instead of any of the other device types, it stops processing ANY event my class would get. :(
In another thread (other subject) a member mentioned something about Windows OSes to need a window to receive inputs. I checked Irrlicht sources (CIrrDeviceWin32.cpp) and saw that it still DOES create a handle for a window when using EDT_NULL.
So that should still work!

Ah! Just to remember... EDT_NULL does not create a window (just its handle). Maybe that's why Windows cannot get input? 'Cause there's no active window for, even when the null device tells the window handle to be shown?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Event receiver with null device?

Post by hybrid »

Yeah, I would say so. But IMHO the null device will not create any window on any platform. Only console device might work, I'm not sure how far this has gone. So I doubt that you will receive any input events, but all the other event handling should work. For example console logs, which are also going through the event handler.
aeronmike
Posts: 45
Joined: Thu May 24, 2012 5:00 am
Location: Rio de Janeiro, Brazil

Re: Event receiver with null device?

Post by aeronmike »

Well so.. I think I'll have to spread "cout"s all over the code. LoL

But.. I still won't be able to perform some tests.. :(

But thanks anyway.
Post Reply