OF Events

This is pretty much a continuation of the “better event model” thread. The key ideas were already worked out pretty well. At this point it is just a matter of rounding things up. There was a bit of ambiguity on where/how to register the listeners. Arturo introduced the idea of a event manager class and in the patch-6 I am using this class for both registering and triggering the event. Here is a bit of a summary to get everybody going again:

http://file.stefanix.net/of-v005-poco-patch-6.zip
Howto use this patch: It is made for the “v005 + poco” zip that was circulating earlier on the forum. Copy all the files from the zip and overwrite the ones in OF. In main.cpp of any example replace “ofRunApp(new testApp());” with " testApp app; ofRunApp();".

Generally each event consists of the following classes:

event args:

  • Usage: carry data about the event,
    ------- the object passed to the event listener
  • Examples: ofKeyEventArgs, ofMouseEventArgs

event listener:

  • Useage: subclassed by any object that handles the event
    -------- (eg: ofSimpleApp)
  • Examples: ofKeyListener, ofMouseListner

event manager

  • Usage: registers/unregisters event listeners,
    ------- and triggers event
  • Examples: ofKeyEventManager, ofMouseEventManager

Event manager classes can either be instanced as globals, member variables or they can be subclassed. For the core they should probably be global. For gui elements (eg. buttons or or any object that occurs multiple times) they should be members or superclasses. For these three cases the the api looks like this, respectively.

registering a listener to a global manager:
ofKeyEvents.addListener(this);

registering a listener to a subclassed manager (eg. button “is a” manager):
button.addListener(this);

registering a listener to a member manager (eg. button “has a” manager):
button.events.addListener(this);

Some questions to consider:

Q: Where should the event manager objects reside?
For core events: ofAppRunner.cpp or event .cpp (eg. ofKeyEvents.cpp)
For gui objects: member of the gui class or superclass

Q: should we group setup, update, draw, exit ? Under what name ?
ofAppEvents.h ?

Q: Should all the event-related source files be moved from the “app” folder to the their own “events” folder?

Hi stefan

I’ve been thinking about this and my main concern with the last solution we had is that you actually need three classes for each event so perhaps is a little bit too much, but as we realized the last time we talked about this, perhaps it’s the simplest solution without using templates.

About this:

registering a listener to a subclassed manager (eg. button “is a” manager):
button.addListener(this);

registering a listener to a member manager (eg. button “has a” manager):
button.events.addListener(this);

you can actually use the first sintax no matter if the button is a manager or it has a manager, in the second case the button just calls the event manager (delegates that task). Just saying because the second option is not very correct from an oo point of view.

About your questions:

Q: Where should the event manager objects reside?
For core events: ofAppRunner.cpp or event .cpp (eg. ofKeyEvents.cpp)

I think we should separate them, then in addons if an extension generates some events, it will have its own event files and you will quickly know how it works.

For gui objects: member of the gui class or superclass

About this I will go with member classes. Also, I’ve been thinking if some day we want to implement some kind of network events, having to register the events through the event broadcaster (like the gui control) makes things more dificult as in a network environment you cannot access this object unless you have some kind of proxy representing it. Having a manager where you directly register events will also need some kind of id to know what object are you actually registering the listeners to. Although perhaps this is a little bit too much now.

Q: should we group setup, update, draw, exit ? Under what name ?
ofAppEvents.h ?

ofAppEvents it’s ok, as it follows the same naming than that currently in OF but perhaps it’s a little bit ambiguous as the app also receives mouse and keyboard events by default and indeed you can register any other class to that events. I think I used something like GLEngine in the last version, but I don’t like it very much.

Q: Should all the event-related source files be moved from the “app” folder to the their own “events” folder?

In my opinion every thing that have events, should have them separated in an events folder so you can easilly recognize them or change the way they work: just the same reasons as the first question.

btw, congratulations for the touchkit, I really like your business model selling hardware based on a totally open source software.

three classes
ya, I think it is the simplest

delegates
For the core this does not seem to apply. For addons (eg: GUI) this is really something the person writing it needs to decide. But yes, I think you are absolutely right. Delegates are the way to go whenever the event manager is a member of the object triggering the event.

touchkit
thanks, thanks … it’s an experiment but we are pretty confident it’s totally possible. We are learning a lost as we go :wink:

For the event stuff I think its time for zach and theo to jump in (hint!, hint!).
I think zach said you will be at the OF Lab at Ars. If so I look forward meeting you. Addie and I are going to be there on the weekend :slight_smile:

hey - just to say we are jumping in : )
we are very excited to get poco into the next release and incredibly grateful (And inspired) by all the event research and development you guys have been doing!

going to play with the latest zip you posted - let us know if either of you have any more thoughts on the best structure etc.

or maybe there has been enough discussion already?

:wink:

looking forward to seeing you at ars stefan!

Hi

I’ve added a resize event to ofAppEvents, so when the window gets resized the application or any listener get called.

Also I discovered some days ago this AbstractDelegate in poco that allows to create listeners over any function in any class. Adding some defines I can get something like:

ofAddUpdateListener(this,myClass,myMethod);

I’ve found this useful to make my own base classes that need to receive the update event and let the original update method overwritable so I don’t need to call the base method in each extended class, although I find the defines thing a little bit of a hack:

http://65.111.166.199/openframeworks/ev-…-081005.zip

Speaking of window resizing, I have a question about events: why does the ESC key close everything nicely, but if I hit the “X” button (“close”, on Windows) things crash? For example, if I create an ofImage and then I hit “X”, ofCloseFreeImage() isn’t called and Windows (Vista) tells me my app crashed.

kylemcdonald: That’s been discussed and I think it’s some issue with glut. There’s a thread about it somewhere. I couldn’t ever get anything recommended to work and never really saw a ‘fix’ for this :(. It’s only an issue on windows I believe.

Hey arturo, when will that resize be on the SVN? I really could use that resize() callback right now!

Hey memo

Sorry for late reply, I’ve been really busy the last week…

So I’ve done some changes to the events model that is now in the svn, they don’t break any code but I’m not very sure:

  • resize event: I think this should be implemented

  • change extern declarations to:

  
#define ofAppEvents ofAppEventManager::getInstance();  

and add code to the eventManagers so they’re singletons:

  
ofAppEventManager & getInstance()  

Don’t know about this, externs are problematic because of the initialization order, and we also get rid of the .cpp files but simulating an object with a define can be confusing?

  • add new methods to managers to allow to add any function with any name as a listener, the syntax is a little bit hard, but using some defines it can be something like:
  
ofAddUpdateListener(this,myClass,myMethod);   

The same problem than with the singleton, not very sure about the defines.

stefan, zach, theo, (or any others interested) what do you think?

http://65.111.166.199/openframeworks/ofAppEvents.h

I’ve got following error when I try to integrate this “advance event model” to my previous code.

‘ofKeyListener::keyPressed’ : cannot access protected member declared in class ‘ofKeyListener’

Do I miss something here? Any other files to be updated?

Thanks!

gatotkaca

You may have mixed files. Can you try downloading the latest files from svn.

  
  
svn co [http://svn.openframeworks.cc/openFrameworks/trunk/openFrameworks](http://svn.openframeworks.cc/openFrameworks/trunk/openFrameworks)  
  

If this does not work for you I think theo has also posted a snapshot on the forum. I just can’t find it right now.

Hey you can get the latest snapshot here:
http://www.openframeworks.cc/downloads/-…-eworks.zip

updated every hour

Hey arturo, hows it goin?

I just checked the SVN again, seems like it hasn’t been updated since 09/13/08?

I tried the attached AppEvents.h, seems to be backwards compatible so thats cool, but I couldn’t get the resized(int, int) to work for testApp, I’m just printfing w, h and I see nothing

  
  
void testApp::resized(int w, int h) {  
	printf("testApp::resized(%i, %i)\n", w, h);  
}  
  

am I missing something?

Yes sorry I uploaded the events definition but forgot about the modification to get the callbacks for the resize event from glut:

http://65.111.166.199/openframeworks/ev-…-081027.zip

ah excellent thanks, works good

I just noticed that

ofEventModel.cpp
ofEventModel.h

are still in the svn and in the prereleases for 006. They are redundant and should be deleted.