Events, do you need references to the instance that publishes the event?

I think I’m confusing myself the more I try to fix this simple ofEvent problem. I have events working just fine if, for example, I have ofApp listening for event notifications in some child class. But now I have 2 child classes, a controller class and a sound engine class, and I want the controller to publish an event to the sound engine. They don’t know each other exist, but I thought events could work anyway. I can’t seem to get it to work though, since usually you pass the instance in ofAddListener. I tried making the event static, but then I get undefined reference error.

Any examples I can be pointed to?

Hi, you need to have a way so each of these clases, the one that notifies the event and the one that listens can see the ofEvent instance of the event. There can be a lot of ways but usually the class that notifies the event also owns the ofEvent instance.
If you have it static or not the same applies. In the case of having it static you get the “benefit” of not having to pass the instance of one class to the other. just including the header file would work.

check the example at examples/events/simpleEventsExample

or another option you can have is that the ofApp (which I guess holds the instances for the sound engine and the controller) acts as an intermediary just for the task of generating the listener, after that it should just work (although be careful if these instances are pointers as it might invalidate the event listeners).

so


class ControllerClass {
public:
/// TheEventType can be an int, void or whatever type but it is important that it is the same you use in the callback function, either if it is a class method or a lambda function
ofEvent<TheEventType> event;

void notify(){
ofNotifyEvent(event, eventArgs, this);
///ofNotifyEvent(event,  this); // if TheEventType is void you should use this form
}

TheEventType eventArgs; // whatever data you might want to pass with the event. dont use if you declare ofEvent<void>

};

class SoundEngineClass {
public:
void setListener(ControllerClass* controller){
eventListener = controller->event.newListener(this, &SoundEngineClass::eventCallback);
}

// in case you used a void event just make a funtion without arguments
void eventCallback(TheEventType& ){
// this gets triggered by the event!
}

ofEventListener eventListener;

};

class ofApp{
///.... whateverelse goes in this classs;
void setup(){
soundEngine.setListener(&controller);

}

SoundEngineClass soundEngine;
ControllerClass controller;

};

Hope this helps.
if not please post some of your code

Hey I may have done something somewhat similar with a friend class and ofEventListener with a lambda. The controller class (I think) could become a friend of the sound engine class, and have access to its private and protected (?) members and functions. The ofEventListener (and its lambda) would have resided in the controller class. If I remember right, the friend designation lets the two classes remain distinct, but able to interact in defined way. Friendship is not bi-directional if I remember right.

friendship only allows one class to access anothers private and protected fucntions and properties. If you make it all public (for the sake of testing) you dont need friending these.

Yeah the friendship idea always seemed a bit contrived to me. But, it did allow my controller class to listen to variables in other classes, and then call functions from those, without defining them as public. Maybe its academic, but its kinda nice to use if more typical inheritance isn’t really suitable (ie 1 controller for multiple objects/classes).

I ended up just pinging an event in ofApp, it seems that communicating between two children is a bit fraught (or my code is a mess).

Another question–it seems that you can only send references to variables via events, and not constants, is this correct? As in, when I do

ofNotifyEvent(activeVecChanged, active_vec);

this is fine, but if I do

ofNotifyEvent(activeVecChanged, 2);

it throws an error. This isn’t a huge deal, but there are times when I wonder if I could lose the additional line of code where I declare a throwaway variable

correct, it always passes references. If you dont need that value to be passed use instead an ofEvent<void>.