<functional> callback functions

Status
Not open for further replies.
So this runs fine on ccp.sh, but on arduino 1.05 teensy 3.1

1. i had to comment the "..SpecialFunction(Thingy....) i'm guessing just because of some compiler issue with inline class declaration
2. weird, i had to remove the ()'s when calling aButton.action(); to it's aButton.action; i guess Arduino is doing some type of assumption when compiling

More importantly...
3. once the code compiles, i can call the action functions, but nothing actually happens, i don't know if they're actually getting assigned or whats the deal

Code:
#include <functional>

int global1 = 0;
int global2 = 5;

class aButton {
public:
	int status, oldStatus;
	aButton(int initStatus) { oldStatus = status = initStatus; }
	std::function<int()> action;
};

class Thingy {
private:
	int mode  = 1;
	int value = 0;
public:
	void reset() { value = 0; }
	void setMode(int newMode) { mode = newMode; }
	void increment() { value = value + global2; }
	//...
};

// void specialFunction(Thingy *thingyToWorkOn) {
// 	//do stuff...
// }
// void anotherSpecialFunction(Thingy *firstThingy, Thingy *secondThingy) {
// 	//more stuff...
// }

void setup()  {
	// Open serial communications and wait for port to open:
	Serial.begin(115200);
	while (!Serial) { }

	Serial.println( "-- Start Test -- \n" );
	
	Thingy one;
	Thingy two;

	aButton on(0);
	aButton speedUp(0);

	on.action = std::function<int()>([&]() -> int{

			//some specific stuff....
			global1 = 1;
			if (global2 < 10) {
				global2++;
			}
			one.reset();
			two.reset();
			// anotherSpecialFunction(&one, &two);
			Serial.println( "on action \n" );
			return 1;
		});

	speedUp.action = std::function<int()>([&]() -> int{

			//some specific stuff....
			if (global1) {
				one.setMode(global2);
				two.setMode(global2);
				// specialFunction(&one);
				// specialFunction(&two);
				Serial.println( "speedUp action \n" );
				return 1;
			}
			return 0;
		});


	for(int i=0; i<5; i++) {
		//if on pushed
		on.action;

		//if speedUp pushed
		speedUp.action;
	}

	Serial.println( "\n-- End Test --" );

}

void loop() {

}
 
Last edited:
I tried <functional> on the Teensy 3.x and it used huge amounts of memory.

If you just need a simple callback, typedef a function pointer and go for that.
If you need callbacks to objects, you'll need something more complex.
If you need to assign multiple callbacks to one event, you also need something else.

So what is the most important point you are addressing with <functional>? Is it being able to write the function where it is assigned?

Regards

Christoph
 
different actions for different instances of buttons that can access different instances (pointers) to other objects and makes various changes to them
 
So the functions serve as some kind of delegate that, when called by the button action, modifies some other object?
 
yup, some buttons will be related, others will be grouped together in button containers, but do completely different things,
 
You can certainly do this with an intermediate class or function that is called by the button and modifies an object, but it looks like you don't want to have a plain old function declaration and definition for that.

Would something like the Qt signals and slots work (I know, they are not available for the Teensy, but if they were...)? Or boost.signals?
 
i'd rather have something like a lambda, which i can just declare to handle the various things different instantiations can handle. do boost.signals work on the teensy 3.1?
 
I think only very few persons on this forum have tried to use lambdas on a Teensy 3.1.

I've tried boost.Signals, but when that didn't work I tried to come up with my own. You can find it at https://github.com/crteensy/Signals and there are some usage examples in this thread: http://forum.pjrc.com/threads/25460-Looking-for-lightweight-signal-and-slot-classes

You can create a signal, and create Connections to it. Signals have operator() implemented, which calls all associated connections (the number of connections is not limited). The connections in turn call a free function, a static class method, or a non-static method on an object. All this is templated for passing around values, but very strict.

The only major caveats so far: If an object object is destroyed before the connection, and the connection is used afterwards, you'll crash your application. Other than that, it works well.

Regards

Christoph
 
i think i'm trying to go the other way, if i'm understanding signals correctly

instead of having models listen and do their thing, i already have my control logic responding to a screen touch to display a menu and i wanted to stay in the same scope to draw menu's and handle their button touch's actions since i have access to the various things i want to control
 
If you use lambdas, please post a small example when you got them working. When I tried <functional>, I was using a Teensy 3.0 and with the 3.1's extra RAM, it might not be a show stopper any more.
 
well my sample compiles, but doesn't actually do anything, like if i put a print statement in the action's i declare, they don't get printed, just "begin test" then "end test"
 
If I understand your code correctly, you should see "start test" and "end test" immediately after each other and when you press the buttons you should see the "onAction" and "speedupAction" output - right? Are the lambdas copied (by the compiler) to some place? If not, they would go out of scope when setup() finishes...
 
i thought lambda's were global scope? hence the danger of calling on non-global things, but in this demo, they're being declared and called in the same setup scope so i should see each of the actions print out 5 times in that for loop
 
i thought lambda's were global scope?
You probably know more about them, I absolutely can't comment on that.

I totally missed that for loop, sorry! So the lambdas act on something that's available when they need it. What happens when you move the thingys and the buttons to global scope?
 
Status
Not open for further replies.
Back
Top