sending a reference to a function in an argument

hi all

i’ve got a class called Histogram which stores the data for and renders a histogram
I use this histogram class for a bunch of histograms on my screen

What i’m wondering is
Is it possible to / how can I send a function reference to the histogram
So that whenever i click on the histogram, it calls the correct function from the host class.

e.g.
class A hosts class B (histogram)
when i initialise class B i give it a reference to a function Gamma in class A
then, whenever i click on histogram in class B, i call function Gamma

thanks!
elliot

you can use ofEvents for this, take a look at the advancedEventsExample

or pass a function pointer but the syntax is kind of horrible:

void passMeAFunction( void (*functionName)(int, int) ){
int a=0,b=0;
functionName(a,b);
}

if functionName is a plain function or:

void passMeAFunction( void (testApp::*functionName)(int, int) ){
int a=0,b=0;
functionName(a,b);
}

if functionName is a method of testApp

of course the original name of the function doesn’t need to be function name.

is it possible to store that function reference for later use?

so could i use the following in my class:

  
  
h:  
private:  
    void * _onSelect();  
  
  
  
cpp:  
Histogram::Histogram(void (testApp::*onSelect)())  
{  
    _onSelect = onSelect;  
}  
  
Histogram::Selected()  
{  
    _onSelect();  
}  
  
  

and would i call the constructor like

  
  
_histogram = new Histogram(histSelected());  
  

yes, it’s the same horrible syntax : )

  
h:  
private:  
void (testApp::*_onSelect)()  
  
cpp:  
Histogram::Histogram(void (testApp::*onSelect)())  
{  
    _onSelect = onSelect;  
}  

to pass the argument to the constructor:

  
new Histogram(&testApp::onSelect);  

ok
now i’ve got around the maths bit i’m back to this

with:

  
  
class histThreshold : public PCHistogram  
{  
public:  
	histThreshold(string name, int nClasses, ofTrueTypeFont &Typer, void ( PCDecode::*onSelect) (int) ) :  
		PCHistogram(name, nClasses, Typer)  
	{  
		_onSelect = onSelect;  
	}  
	  
protected:  
	void	updateSelection()  
	{  
		_onSelect(_selectionIClass);     //error comes up on this line  
	}  
  
	void	(PCDecode::*_onSelect) (int);  
};  
  

i get

error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((histThreshold*)this)->histThreshold::_onSelect (…)’

i dont seem to get the problem when _onSelect has no arguments, and using things like
&_onSelect

changing the line for

  
  
		(*_onSelect) (_selectionIClass);  
  

brings error

error: invalid use of ‘unary *’ on pointer to member

instead

any ideas :)?

ok
i’ve got this working now with ofEvents

i realised what was confusing me about the example
it wasn’t really obvious to myself what eventsObject.h is
from the look of it (the name, the #ifndef OFXEVENTSADDON_H_, etc)
it seemed like it was a special file that you had to use to work with events
rather than an example of a class

so in an attempt to help others who might get lost, from my understanding:
if class A hosts class B, and you want class B to trigger functions in class A
then rather than have a function in class B which links to class A, you use a special object called an ofEvent

ofEvent can deal with different types of data, but you can only pass through one object at a time (unlike a function where you can pass many)

you define ofEvent and the argument in class B

e.g.

  
  
ofEvent<int> mousehit;          // (1)  
  

this event has to be public, because you need to reference to it from class A

then in class A you add a listener for that event

e.g.

  
  
ofAddListener(classBinstance.mousehit,this,&classAdefinition::mouseWasHitInClassB); // (2)  
  

then

mouseWasHitInClassB must be a function in class A which takes one argument (a reference to an int)

  
  
mouseWasHitInClassB(int &argumentName) // (3)  
{  
....  
}  
  

the argument name isn’t important

finally,
you need to trigger the event somehow in class B
this is done with

  
  
ofNotifyEvent(mousehit,2,this); // result is evaluating mouseWasHitInClassB(2) in class A  
  

this was probably obvious to a lot of people
but i just couldn’t see the wood from the trees
hope this helps anyone if you get stuck!

and special thanks to arturo for his help here

Thanks for walking through the process Elliot - helped me a lot! :smiley: