2016年6月23日木曜日

mbedのコールバック FunctionPointerを使うテスト

mbedにはコールバックを簡単に記述するためにFunctionPointerというクラスが用意されているようだ。

APIはドキュメントに載っていないようだが、mbed-src/api/FunctionPointer.hで定義されている。ちょっとややこしいのでよく読んでいない(^q^; いつものようにとりあえず動かしてみた。

FunctionPointerテストプログラム

#include "mbed.h"

class Foo {
public:
    void attach(void (*function)(void)) {
        callback.attach( function );
    }
    
    template<typename T>
    void attach(T *object, void (T::*member)(void)) {
        callback.attach( object, member );        
    }
    
    void update() {
        callback.call();
    }
    
protected:
    FunctionPointer callback;
};

class Bar {
public:
    Bar() : cnt(0) {}
    
    void bar_func() {
        printf("in Bar::bar_func\t%d\r\n", cnt);
        cnt++;
    }
    
private:
    int cnt;
};

void my_func() {
    static int cnt = 0;
    printf("in my_func\t%d\r\n", cnt);
    cnt++;
}

int main()
{
    printf("Callback function test\r\n");
    
    Foo foo1;
    foo1.attach(&my_func);
    
    Foo foo2;
    Bar bar;
    foo2.attach(&bar, &Bar::bar_func);
    
    while(1) {
        foo1.update();
        foo2.update();
        wait(1);
    }
}

foo1はコールバックに普通の関数、foo2はBarクラスのメンバ関数をコールバック関数として登録している。

コールバック関数をFunctionPointer::attach()で登録して、FunctionPointer::call()で呼び出す。

FunctionPointerを使うとコールバック関数は引数、返値とも取れない。

FunctionPointer.hにはint型の引数を一つだけとるevent_callback_tというクラスもtypedefされているのでこちらも同じようにテスト。

event_callback_tテストプログラム

#include "mbed.h"

class Foo {
public:
    void attach(void (*function)(int)) {
        callback.attach( function );
    }
   
    template<typename T>
    void attach(T *object, void (T::*member)(int)) {
        callback.attach( object, member );      
    }
   
    void update(int cnt) {
        callback.call(cnt);
    }
   
protected:
    event_callback_t callback;
};

class Bar {
public:
    void bar_func(int cnt) {
        printf("in Bar::bar_func\t%d\r\n", cnt);
    }
};

void my_func(int cnt)
{
    printf("in my_func\t%d\r\n", cnt);
}

int main()
{
    printf("Callback function test\r\n");
   
    Foo foo1;
    foo1.attach(&my_func);
   
    Foo foo2;
    Bar bar;
    foo2.attach(&bar, &Bar::bar_func);
   
    int cnt = 0;
    while(1) {
        foo1.update(cnt);
        foo2.update(cnt);
        cnt++;
        wait(1);
    }
}