Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Pages: [1]   Go Down
Author Topic: Delegate system for member function pointers  (Read 4901 times)
0 Members and 1 Guest are viewing this topic.
Amsterdam
Offline Offline
Newbie
*
Karma: 0
Posts: 19
Xn=rX(1-X)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Because I like programming in objects/classes, I got myself in a situation to use timers and callbacks. This is generally an issue in c++ (member function pointers)

I found this Delegate system that covers a whole lot (too much for standard Arduino programming)
http://www.codeproject.com/KB/cpp/FastDelegate.aspx

I works very nice, changed the SimpleTimer lib (Author: mromani@ottotecnica.com) to be used with this Delegate system.

What I was thinking, since Arduino programming is getting more and more professional on one-side, having a standard low-footprint Delegate system could be a nice addition.

I already got it working and the extra memory needed is very little, the guy who made it states that in most cases it would only compile to two lines of assembly. What still needs to be done is cutting it up (i guess 80% of the code could be discarded since Arduino uses a single compiler) and making it integegrate easy (without API breaks)

this is my compile output for a small program with this Delegate system:

With FastDelegate:

Code:
AVR Memory Usage
----------------
Device: atmega2560
 
Program:   17178 bytes (6.6% Full)
(.text + .data + .bootloader)
 
Data:       1292 bytes (15.8% Full)
(.data + .bss + .noinit)
 
 
Finished building: sizedummy

Without FastDelegate:

Code:
AVR Memory Usage
----------------
Device: atmega2560

Program:   17030 bytes (6.5% Full)
(.text + .data + .bootloader)

Data:       1292 bytes (15.8% Full)
(.data + .bss + .noinit)


Finished building: sizedummy

Code as in test (working)

typedef
Code:
typedef FastDelegate0<> FuncDelegate;


 Code in robot class:
Code:
void Robot::test(){
    FuncDelegate f_delegate;
    f_delegate = MakeDelegate(this, &Robot::halt);
 
    timer.setTimerDelg(1, f_delegate, 1);
}
 
void Robot::halt() {
    Serial.println("TEST");
}


 Code in SimpleTimer class:
Code:
int SimpleTimer::setTimerDelg(long d, FuncDelegate f, int n){
    f();
}


Arduino prints TEST in the console


It all worked nice and fast, if it is not something to be used, mods may delete this post.
« Last Edit: January 12, 2012, 04:59:18 am by Aduen » Logged

Guildford, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Could you post all the code you used?

I started reading the article over at Code Project but part way through my eyes glazed over. A complete example I could cut and paste into a sketch would be really useful.

So far I've used functors to achieve callbacks to member functions but this looks very interesting.

Iain
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 139
Posts: 6835
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
This is generally an issue in c++ (member function pointers)

How so?  What did making and setting a "delegate" gain me over the existing timer1 code that was simpler and smaller?
Code:
// a function to be executed periodically
void repeatMe() {
    Serial.print("Uptime (s): ");
    Serial.println(millis() / 1000);
}

void setup() {
    timer.setInterval(1000, repeatMe);
}
Logged

Guildford, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You've got to be using classes to want this. If you were, you'd know why it's useful.
Logged

Amsterdam
Offline Offline
Newbie
*
Karma: 0
Posts: 19
Xn=rX(1-X)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I am using it myself right now, so a fully working example wouldnt be a problem. I've also rewrote the SimpleTimer lib from
Code:
Author: mromani@ottotecnica.com
using this system and some other advantages.

I'll make it a arduino lib with an example attached and post it for download in this thread. I'll try to get this done before the weekend.

@westfw: its for member function pointers, a simple function pointer wouldnt need a delegate system ofcourse. Although my current setup does all the magic in the background so you could easily throw in a simple function pointer or get more freaky and use a delegate for a member function pointer like so:

Code:
//no class
void simple_function(){
//do something
}

timerlib.setTimer(30000, simple_function, 0);

//within another class
delegate d = MakeDelegate(this, &BigClass::someFunction);

timerlib.setTimer(30000, d, 0);

With no changes in the timerlib object. This is ussually a hackle because non-member functions dont get a this operator, where member functions do get these. If your this operator gets screwed the called function has no clue whats going on in its own class/object.

But, I'll get back on this thread with some descent examples so its all getting a little clearer.
Logged

Guildford, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'll make it a arduino lib with an example attached and post it for download in this thread. I'll try to get this done before the weekend.

Excellent. I look forward to trying it out.

Iain
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 139
Posts: 6835
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
its for member function pointers
"pointers to functions that are defined as part of a class" ?
Like: getting a pointer to digitalRead() is easy (because it's just a function), but getting a pointer to the function that implements Serial.write() would be difficult (because it's encapsulated inside the class)?

All these new-age terms!  "Delegate", "member", "class"!
Pretend I'm a dinosaur who's more familiar with "AOBJN", "JCL", and "Chaff." :-)
Logged

Guildford, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The problem is that "regular" C callbacks do not carry any state information. All class member functions have an implicit "this" parameter which means they can't be called by a C callback. Using delegates gets round the problem as it creates a callback that captures the "this" parameter.

It allows you to callback to a specific object. If you had a Mega with 4 serial ports in use, a C callback couldn't differentiate between the four serial ports but a delegate could, as it will capture the "this" parameter identifying which serial port it's related to.

Iain
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 139
Posts: 6835
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah hah!  That seemed to make sense.
Logged

Amsterdam
Offline Offline
Newbie
*
Karma: 0
Posts: 19
Xn=rX(1-X)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've made it into a small library that you can unpack in the Arduino folder, I made it in 022, not 1.0. Have not tested it in 1.0 to (don't think it will work in the new one yet cause of the class differences) something for later on.

So, just unpack in the libraries folder of the arduino install, start/restart arduino software and you can look for it in the examples and libraries menu.

I did not made the delegate system API friendly yet but, its not that difficult as you will see in my code (kept it small). If it starts interesting more people I'll consider making the Delegate system more friendly.

http://img.aduen.nl/TimerLib.rar

Logged

0
Offline Offline
Edison Member
*
Karma: 67
Posts: 1703
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for pointing out this article!  This clears up some mysteries for me.

I have been experimenting with C++ templates for Arduino libraries and believe better C++/object support is the future of embedded programming.

Many people think these methods are not viable for the 8-bit AVR, maybe they are right, but playing with new techniques is fun.
Logged

0
Offline Offline
Jr. Member
**
Karma: 4
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Very useful indeed.  Thanks for posting.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great solution, a day of trying to figure this pointer crap out, and got it done in no time with this, once I figured out that you have to update his modified SimpleTimer.h to Arduino 1.0 by changing the <Wprogram.h> include to <Arduino.h>
Logged

Pages: [1]   Go Up
Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Jump to: