2009年12月13日 星期日

Delegation in C - 在 C 語言當中實作委派方法 (1)

原本的想法是想要能夠在 C 語言中實現 event bubbling
提供一些函式去註冊需要被 callback 的函式
然後在 event 發生時去呼叫所有註冊過的函式
於是就有了以下的程式碼

首先來看一段程式碼片段
int main(int argc, char* argv[])
{
    list_t* list = NULL;

    add_func(&list, funcA);
    add_func(&list, funcB);
    add_func(&list, funcC);

    invoke_all_func(&list, "Hello World");

    return 0;
}
這邊利用 add_func() 將 funcA, funcB, funcC 註冊到某個 double linked list 上面
然後呼叫 invoke_all_func() 去呼叫註冊好的 funcA, funcB, funcC
static bool funcA(const char* str)
{
    fprintf(stderr, "%s says %s\n", __FUNCTION__,  str);
    return true;
}

static bool funcB(const char* str)
{
    fprintf(stderr, "%s says %s\n", __FUNCTION__,  str);
    return true;
}

static bool funcC(const char* str)
{
    fprintf(stderr, "%s says %s\n", __FUNCTION__,  str);
    return true;
}
執行後的結果是
funcC says Hello World
funcB says Hello World
funcA says Hello World
這邊的設計上是越後面註冊的函式越先被呼叫到
如果把 funcC() 的回傳值改成 false 結果就會變成
funcC says Hello World
只要某個註冊過的函式先回傳了 false 接下去的函式就不必再去執行了
於是這兩個負責註冊跟呼叫的函式的 prototype 應該就長得像是下面這樣
bool add_func(list_t** list, bool (*func)(const char*));
bool invoke_all_func(list_t** list, const char* msg);
然後再去實作這些函式的剩餘部份,不過問題來了...
當 funcA, funcB, funcC 換成了
static bool funcA(int val)
{
    fprintf(stderr, "%s count %d\n", __FUNCTION__,  val);
    return true;
}

static bool funcB(int val)
{
    fprintf(stderr, "%s count %d\n", __FUNCTION__,  val);
    return true;
}

static bool funcC(int val)
{
    fprintf(stderr, "%s count %d\n", __FUNCTION__,  val);
    return true;
}
或者是換成了
static bool funcA(const char* msg, int val)
{
    fprintf(stderr, "%s says '%s' count: %d\n", __FUNCTION__, msg, val);
    return true;
}

static bool funcB(const char* msg, int val)
{
    fprintf(stderr, "%s says '%s' count: %d\n", __FUNCTION__, msg, val);
    return true;
}  

static bool funcC(const char* msg, int val)
{
    fprintf(stderr, "%s says '%s' count: %d\n", __FUNCTION__, msg, val);
    return true;

可是 event bubbling 的方法還是一模一樣的,這時候我們應該怎麼辦呢?
有一種最不用花腦袋最快速可以解決問題的辦法就是去複製貼上程式碼,然後將參數換一換,有幾種不同的函式就重複幾次同樣的工作

待續...

沒有留言: