EventReciever in another file?

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
Taymo
Posts: 55
Joined: Mon May 22, 2006 1:06 am
Location: Colorado Springs - CTU
Contact:

EventReciever in another file?

Post by Taymo »

This seems like it would be a pretty common problem but I have my event receivers in another file away from the data it needs to manipulate. I'm wondering how I should get the data I need into the event receiver.
Dances
Posts: 454
Joined: Sat Jul 02, 2005 1:45 am
Location: Canada
Contact:

Post by Dances »

Your event receiver is a class. Make a public function in the class that accepts the variables you need, and private variables to store them. Then you just pass them (I believe from what Vitek told me with an &), and then access the private variables in your event receiver.
spopo
Posts: 33
Joined: Wed Mar 28, 2007 1:46 pm

Post by spopo »

Or you could have your EventReceiver class something like this :

Code: Select all

// Event Receiver.h

#include <irrlicht.h>

struct mouse {
	bool left;
};

struct keyboard {
	bool escape;
};



class EventReceiver : public irr::IEventReceiver 
{ 
    mouse Mouse;
    keyboard Keyboard;
	
	virtual bool OnEvent(irr::SEvent event);
public:   
	EventReceiver();
	~EventReceiver();
	bool isKeyDown (irr::core::stringc key);
	bool isMouseDown (irr::core::stringc button);	
};

// Event receiver.cpp

#include "EventReceiver.h"



EventReceiver::EventReceiver ()
{
	Keyboard.escape = false;
	Mouse.left = false;
}

EventReceiver::~EventReceiver() 
{
}

bool EventReceiver::OnEvent(irr::SEvent event) 
{ 
    if (event.EventType == irr::EET_KEY_INPUT_EVENT) 
    { 
      switch(event.KeyInput.Key) 
      { 
	  case irr::KEY_ESCAPE: Keyboard.escape = event.KeyInput.PressedDown;       
      } 	    
	}

	if (event.EventType == irr::EET_MOUSE_INPUT_EVENT)
	{
	  switch(event.MouseInput.Event)
      {
		case irr::EMIE_LMOUSE_PRESSED_DOWN: Mouse.left = true; break;
		case irr::EMIE_LMOUSE_LEFT_UP: Mouse.left = false; break;
	  }
	}
	
	    return false; 
}   

bool EventReceiver::isKeyDown (irr::core::stringc key)
{
	if (key == "ESCAPE") return Keyboard.escape;
	return false;
}

bool EventReceiver::isMouseDown (irr::core::stringc button)
{
	if (button == "LEFT") return Mouse.left;
	return false;
}

// And in the main.cpp

EventReceiver *receiver = new EventReceiver();

 if (receiver->isKeyDown("ESCAPE")) break;

Of course this can be done in a much better way, but i think you got the idea.
Taymo
Posts: 55
Joined: Mon May 22, 2006 1:06 am
Location: Colorado Springs - CTU
Contact:

Post by Taymo »

I realize I would store the variables in the class if needed, I'm wondering how to actually get the data into the receiver as I can't pass them in being I don't call the event receiver.. Irrlicht does. The data I need will be in another class.
Dances
Posts: 454
Joined: Sat Jul 02, 2005 1:45 am
Location: Canada
Contact:

Post by Dances »

But you can have another function to pass them to...

Code: Select all

#ifndef EVENTRECEIVER_H
#define EVENTRECEIVER_H

class EventReceiver : public IEventReceiver
{
public:
            void initialize(); // make this function accept the variables you need
	virtual bool OnEvent(SEvent event)
	{
	  //code here	
            return false;
            }
    private:
      // declare variables you need here
 };
 
 #endif
THEN in a cpp file

Code: Select all

#include "eventreceiver.h"

void GameEventReceiver::initialize()
{
     //write those variables you accepted to your private data here
}
THEN in main.cpp

Code: Select all

#include "eventreceiver.h"

int main
{
     eventreceiver receiver;
     eventreceiver.initialize();
     device->setEventReceiver(&receiver);
}
NOW, the suggestion spopo made is actually better, if I understand it correctly.
This way we are creating copies of all the data. We want to use as little memory as possible so we don't want to copy them if we can.

so, we do this in our header

Code: Select all

#ifndef EVENTRECEIVER_H
#define EVENTRECEIVER_H

class EventReceiver : public IEventReceiver
{
public:
            void initialize(); // this will be only to initialize your bool keys
            void handle(); // this will be in your main cpp file
	virtual bool OnEvent(SEvent event)
	{
	  //code here
             //We WILL NOT do any event handling here, we simply store
             //which buttons are being hit privately (use bool keys)
            return false;
            }
    private:
      // your bool keys will be defined here
 };
 
 #endif
THEN in main.cpp file

Code: Select all

#include "eventreceiver.h"

int main
{
   eventreceiver receiver;
   receiver.initialize();
   device->setEventReceiver(&receiver);

   receiver.handle(); //THIS will go in your game loop
}

void EventReceiver::handle()
{
   //THIS is where you will handle events
}
I hope this helps :)
Taymo
Posts: 55
Joined: Mon May 22, 2006 1:06 am
Location: Colorado Springs - CTU
Contact:

Post by Taymo »

Ahhhhh, indeed.. I can't image why I didn't think of that. Anyways thanks a lot everyone.
Catprog
Posts: 164
Joined: Wed Jan 31, 2007 9:07 am
Contact:

Post by Catprog »

Global variables are bad coding practice.

Pass in pointers to your function.
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Post by Clash »

Sorry to bump this 10 days old thread, but I have a doubt on how to optimize that code.

Instead of using if (key == "ESCAPE") return Keyboard.escape;
A way so all the keys are already defined, something like:

Code: Select all

bool eventsReceiver::OnEvent(irr::SEvent event)
{
    bool value = false;

    if (event.EventType == irr::EET_KEY_INPUT_EVENT)
    {
        key[event.KeyInput.Key] = event.KeyInput.PressedDown;
        value = true;
    }

   if (event.EventType == irr::EET_MOUSE_INPUT_EVENT)
    {
        switch(event.MouseInput.Event)
        {
            case EMIE_LMOUSE_PRESSED_DOWN: mouse.left = true; break;
            case EMIE_RMOUSE_PRESSED_DOWN: mouse.right = true; break;
            case EMIE_MMOUSE_PRESSED_DOWN: mouse.middle = true; break;
            case EMIE_LMOUSE_LEFT_UP: mouse.left = false;break;
            case EMIE_RMOUSE_LEFT_UP: mouse.right = false; break;
            case EMIE_MMOUSE_LEFT_UP: mouse.middle = false; break;
            case EMIE_MOUSE_MOVED: mouse.X = event.MouseInput.X; mouse.Y = event.MouseInput.Y; break;
            case EMIE_MOUSE_WHEEL: mouse.wheel = mouse.wheel + event.MouseInput.Wheel; break;
        }

        value = true;
    }

    return value;
};

bool eventsReceiver::isKeyDown (irr::core::stringc Key)
{
return key[Key];
}
But it didn't like much the key[Key], help? :oops:
Perceval
Posts: 158
Joined: Tue May 30, 2006 2:42 pm

Post by Perceval »

You have to use EKEY_CODE type instead of stringc.
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Post by Clash »

That worked great perceval, thanks! By the way, how to make it recognize caps lock and shift?

But for some reason, KEY_DOWN, right, left and up are all coming as true, how can I by default set those keys to false? Other keys like KEY_KEY_J aren't though
Post Reply