Jump to content
  • Advertisement
Sign in to follow this  
Impz0r

Templates and Event handling

This topic is 4268 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Heya, i wonder if there is a way to achieve the following:
template <class T> class Event
 {
  public :
   template <class T> class EventSubscriber
    {
     public :
      virtual VOID OnEvent (const Event<T> *e)=0;

     public :
      EventSubscriber () { Event<T>::addSubscriber (this); }
      virtual ~EventSubscriber () { Event<T>::delSubscriber (this); }
    };

  public :
   typedef std::list <EventSubscriber<T>* > TSubscriber;

  private :
   static TSubscriber       ms_Subscriber;
     
  public :
   Event () { }
   virtual ~Event () { }

   void doFire (void) {
     for (TSubscriber::iterator i=m_Subscriber.begin (); i!=m_Subscriber.end (); ++i)
      (*i)->OnEvent (this);
    }

   static VOID addSubscriber (EventSubscriber<T> *s) {
     ms_Subscriber.push_back (s);
    }
   static VOID delSubscriber (EventSubscriber<T> *s) {
     ms_Subscriber.remove (s);
    }
 }

The thing with this code is, i've only one subscriber list for every event type i might derive, but what i want is a very own list of subscribers for every event. So if i fire an event, only thoes subscribers who have registered to that particular event will be notified. I hope you guys could give me a hint how to achieve this. Thanks in advance. Impz0r

Share this post


Link to post
Share on other sites
Advertisement
I changed the code a bit to have everything working (notice that it is actually simpler that what you might think):

#ifndef EVENT_H
#define EVENT_H
#include <list>

template <class T> class Event
{
public :
// T is also a template parameter for this class,
// no need to repeat this
class EventSubscriber
{
public :
virtual void OnEvent (const Event<T> *e)=0;

public :
EventSubscriber() { Event<T>::addSubscriber (this); }
virtual ~EventSubscriber () { Event<T>::delSubscriber (this); }
};

public :
// same: EventSubscriber is EventSubscriber<T> by default
typedef std::list <EventSubscriber*> TSubscriber;

private :
static TSubscriber ms_Subscriber;

public :
Event () { }
virtual ~Event () { }

void doFire (void) {
for (TSubscriber::iterator i=ms_Subscriber.begin (); i!=ms_Subscriber.end (); ++i) {
(*i)->OnEvent (this);
}
}

// again, EventSubscriber is EventSubscriber<T> by default
static void addSubscriber (EventSubscriber *s) {
ms_Subscriber.push_back (s);
}

static void delSubscriber (EventSubscriber *s) {
ms_Subscriber.remove (s);
}
};

// need this in order to create a definition for ms_Subscriber (and avoid
// the undefined symbol reference at link time)
template <class T> std::list<Event<T>::EventSubscriber*> Event<T>::ms_Subscriber;
#endif // EVENT_H


An example:

#include <iostream>
#include "event.h"

struct WindowEvent
{
};

class WindowEventSubscriber : public Event<WindowEvent>::EventSubscriber
{
public:
virtual void OnEvent (const Event<WindowEvent> *e) { std::cout << "window event received" << std::endl; }
};

int main()
{
WindowEventSubscriber subscriber;
Event<WindowEvent> e;

e.doFire();
}

HTH,

Share this post


Link to post
Share on other sites
Wahhh awesome, i actually thought this won't work.

Thank you very much Emmanuel!

PS: I had to change this line:

template <class T> std::list<Event<T>::EventSubscriber*> Event<T>::ms_Subscriber;



to:

template <class T> std::list<typename Event<T>::EventSubscriber*> Event<T>::ms_Subscriber;



because the compiler complains about an unknown type.

Anyway, now it works, thanks alot!


Impz0r

Share this post


Link to post
Share on other sites
Quote:
Original post by Impz0r
Wahhh awesome, i actually thought this won't work.

Thank you very much Emmanuel!

PS: I had to change this line:
*** Source Snippet Removed ***

to:
*** Source Snippet Removed ***

because the compiler complains about an unknown type.

Anyway, now it works, thanks alot!


Impz0r


Yes - I just forgot to copy the last version, sorry [embarrass]

Share this post


Link to post
Share on other sites
No problem Emmanuel ;)


Before this thread gets cold, i've got a related question.

I want create thoes Events, described within my first post, created dynamicly by a factory over an unique Id.

Something like this:

class EventFactory {
public :
static Event<T> create (unsigned int id) {
...
}
static void registerEvent (...) {
...
}
}





The problem here is, the Event type, as written within the last posts, i want to derive new Events from the base template, but i can't get my head around how to achieve a factory which can be used for all type of events i might derive from it.

Any idea if this actually might work ?


Thanks in advance !

Impz0r

[Edited by - Impz0r on September 18, 2006 11:05:00 AM]

Share this post


Link to post
Share on other sites
Ok, nevermind, i've got the factory to work. I just had to declare a Base Event class from which my templated Event class is then derived. Works like a charm!


Thanks anyway :)

Impz0r

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!