Impossible event class? how to change return type w/ string?

Get answers to all your basic programming questions. No Ogre questions, please!
Post Reply
User avatar
toglia
Gnome
Posts: 336
Joined: Sat Dec 08, 2007 4:28 am
Location: Canada

Impossible event class? how to change return type w/ string?

Post by toglia » Thu May 20, 2010 3:08 am

Hi,

I'm doing my first event system in C++ using fastdelegates(codeproject) and although its already working, I'm thinking of doing a cleaner design.

Well, the basic problem when using delegates is that it is necessary to specify the handler's parameter types. So first I started using a Variant class based on a union, but later switched to simple pointers cause I couldn't use custom constructors.

I ended up with something like:

Code: Select all

eventManager->defineEvent("explosion"); 
Person *person = new Person();
eventManager->bindEvent("explosion", EventManager::Delegate2(person, &Person::OnExplosion));
eventManager->fireEvent("explosion", Variant(Vector3(1,2,3)), Variant(0.5f));

void Person::OnExplosion(Variant* v1, Variant* v2){
	v1->getVector3Ptr();
	//...
Not bad, but I hate the getVector3Ptr stuff cause people who use this event has to know the order AND the type of the Event.

Then I started thinking maybe I could use a map to pair names with types, but I can't figure out a way to do it.

I would like to have:

Code: Select all

Event event("explosion");
event.setProperty("position", Vector3()); //The second parameter could be a Variant
event.setProperty("force", int(10));

eventManager->fireEvent("explosion", event);

void Person::OnExplosion(Event* e){
	Vector3 v = e->getProperty("position"); // How to do this?
	float f = e->getProperty("force"); // Same function returns a Vector3 and a float?
	//...
This would be very elegant, but how in the world can I change the return type of a function if I pass the same parameter type? Seems imposible for now...
0 x

User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US

Re: Impossible event class? how to change return type w/ str

Post by xavier » Thu May 20, 2010 3:35 am

You can't. C and C++ do not distinguish function type based on return value type.

What you *can* do is implement getProperty as a templated member function; clearly the caller has to know the correct type to use since they are providing typed storage for it.
0 x
Do you need help? What have you tried?

Image

Angels can fly because they take themselves lightly.

User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US

Re: Impossible event class? how to change return type w/ str

Post by xavier » Thu May 20, 2010 3:53 am

An example probably helps here too.

Code: Select all

// MyClass.h

class MyClass
{
public:
	template <typename T>
	T myMethod(int param);
};

Code: Select all

// MyClass.cpp
 
#include "MyClass.h"

template<>
int MyClass::myMethod<int>(int param)
{
	return param;
}

template<>
double MyClass::myMethod<double>(int param)
{
	return double(param);
}

Code: Select all

// main.cpp

#include "MyClass.h"

int main(int argc, char* argv[])
{
	MyClass dInst;
	// this is fine because we implemented this specifically
	double x = dInst.myMethod<double>(4);
	// this is fine because we implemented this specifically
	int y = dInst.myMethod<int>(9);
	// this will link-error because it's not defined anywhere
	float f = dInst.myMethod<float>(100);

	return 0;
}
0 x
Do you need help? What have you tried?

Image

Angels can fly because they take themselves lightly.

User avatar
toglia
Gnome
Posts: 336
Joined: Sat Dec 08, 2007 4:28 am
Location: Canada

Re: Impossible event class? how to change return type w/ str

Post by toglia » Thu May 20, 2010 3:57 am

Cool! Got it. Thanks for the example too. Clear as water.
0 x

Bingo
Gremlin
Posts: 155
Joined: Sat Dec 10, 2005 5:30 pm

Re: Impossible event class? how to change return type w/ str

Post by Bingo » Wed May 26, 2010 8:36 am

I also use fastdelegates for delegates in my project. I encapsulated it as follows:

Code: Select all

	// class EventArgs
	class EventArgs
	{
	protected:

	public:
		EventArgs(){};
		virtual ~EventArgs(){};
	};	// eo class EventArgs

	typedef fastdelegate::FastDelegate1<EventArgs&> JooseEventDelegate;

	// class Event
	class Event
	{
	private:
		typedef std::list<JooseEventDelegate> DelegateList;
		typedef DelegateList::iterator DelegateList_it;
		DelegateList m_Delegates;
		bool		 m_bEnabled;

	public:
		Event(bool _enabled = true) : m_bEnabled(_enabled)
		{
		};	// eo ctor
		~Event()
		{
		};	// eo dtor

		// methods
		void raise(EventArgs& args)
		{
			if(!m_bEnabled)
				return;
			for(DelegateList_it dit(m_Delegates.begin());
				dit != m_Delegates.end();
				++dit)
				(*dit)(args);
		};

		// properties
		void enableEvents(bool _enabled) {m_bEnabled = _enabled;};

		// operators
		Event& operator += (JooseEventDelegate e)
		{
			m_Delegates.push_back(e);
			return(*this);
		};

		Event& operator -= (JooseEventDelegate e)
		{
			m_Delegates.remove(e);
			return(*this);
		};
	};	// eo class Event
Any object that raises events can define an event thusly:

Code: Select all

class MyObject
{
public:
    MyObject();
    ~MyObject();

    Event OnInitialise;
    Event OnDestroy;
}; // eo class MyObject
.. and can also provide any custom parameters by simply deriving from the EventArgs class:

Code: Select all

class MyEventArgs : public EventArgs
{
private:
    String someData;
    String moreData;
public:
    // etc...
};
raising an event is as simple as:

Code: Select all

MyObjectEventArgs myArgs;
OnDestroy.raise(myArgs);
Other objects interested in responding to events, do so thusly:

Code: Select all

MyObject obj;
obj.OnDestroy += fastdelegate::MakeDelegate(this, &SomeObject::HandleOnDestroy);

I find this to be quite a neat approach to using fastdelegate in a generic way.
0 x
A ship, atop a mountain, is not in itself, proof of a flood. It means someone thought there was going to be a flood.

User avatar
toglia
Gnome
Posts: 336
Joined: Sat Dec 08, 2007 4:28 am
Location: Canada

Re: Impossible event class? how to change return type w/ str

Post by toglia » Thu May 27, 2010 4:38 am

Hey Bingo, nice approach, I didn't go with the template solution either. I found it problematic cause I had know all the possible types, which "could" be possible but not very scalable. So I did something very similar using a polymorphic event class.
0 x

Post Reply