Multiple EventReceivers ?
Posted: Tue May 06, 2008 9:43 am
Is it possible to add Multiple eventrecievers to the Irrlicht device instead of one ? I'm kinda against the idea to have 1 reciever handle every possible event.
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
No.Airslash wrote:Is it possible to add Multiple eventrecievers to the Irrlicht device instead of one ?
I'm going to go out on a limb and guess that what offends you is the idea of one function handling all events, not one instance of a class.I'm kinda against the idea to have 1 reciever handle every possible event.
All of the 'solutions' that I can find are variations on registering one event receiver that passes events on to other objects. This is not the same as "add[ing] multiple event receivers to the Irrlicht device", although it does allow splitting the event handling logic up. But so would having one event receiver class with multiple functions that each handle a subset of events.christianclavet wrote:There is a way to handle multiple event receiver. Search the forum.
Come on - you know that many people use Irrlicht to learn programming. Don't you remember anymore how it's been to learn the basic concepts, like what's the sense of this "function" thingy?.rogerborg wrote:Sorry if I seem lecturish, but this just seems so trivial and obvious that I'm astonished that anyone put any time in to 'solving' it.
Code: Select all
#ifndef _EVENT_FUNCTOR_H
#define _EVENT_FUNCTOR_H
namespace irr
{
struct SEvent;
}
class IEventFunctor : public irr::IUnknown
{
public:
virtual ~IEventFunctor() {}
virtual bool CallEvent(const irr::SEvent &event_) = 0;
};
// general functor for irrlicht events
template <class T>
class EventFunctor : public IEventFunctor
{
public:
EventFunctor(T* obj_, bool (T::* fpt_)(const irr::SEvent &event_))
{
mObj = obj_;
mFunctionPtr = fpt_;
}
virtual ~EventFunctor() {}
virtual bool CallEvent(const irr::SEvent &event_)
{
return (*mObj.*mFunctionPtr)(event_);
}
private:
bool (T::* mFunctionPtr)(const irr::SEvent &event_);
T* mObj;
};
// Restrict the functor to gui events of the type set in mGuiEventType
class GuiEventFunctor
{
public:
GuiEventFunctor(IEventFunctor* func_, irr::gui::EGUI_EVENT_TYPE type_)
: mFunctor(func_), mGuiEventType(type_)
{
if ( mFunctor )
mFunctor->grab();
}
GuiEventFunctor(const GuiEventFunctor& f)
: mFunctor(0), mGuiEventType( irr::gui::EGUI_EVENT_TYPE(0) )
{
*this = f;
}
virtual ~GuiEventFunctor()
{
if ( mFunctor )
mFunctor->drop();
}
GuiEventFunctor& operator=(const GuiEventFunctor& f)
{
mFunctor = f.mFunctor;
mFunctor->grab();
mGuiEventType = f.mGuiEventType;
return *this;
}
IEventFunctor* mFunctor;
irr::gui::EGUI_EVENT_TYPE mGuiEventType;
};
#endif // _EVENT_FUNCTOR_H
Code: Select all
typedef std::multimap<int, GuiEventFunctor> GuiEventFunctorMultiMap;
GuiEventFunctorMultiMap mGuiEventFunctors;
Code: Select all
// call either all functors which are registered for this event or until one returns true
typedef GuiEventFunctorMultiMap::const_iterator CI;
std::pair<CI,CI> foundFunctors = mGuiEventFunctors.equal_range(event_.GUIEvent.Caller->getID());
for ( CI it=foundFunctors.first; it!=foundFunctors.second; ++it )
{
if ( it->second.mGuiEventType == event_.GUIEvent.EventType )
{
if ( it->second.mFunctor->CallEvent(event_) )
return true;
}
}
Code: Select all
ADD_EVENT_HANDLER("buttonOK", EGET_BUTTON_CLICKED, MyDialog, OnOK );