Lines 5-8 were replaced by lines 5-8 |
- typedef struct { |
- char *class; |
- /* ... message data ... */ |
- } <message class>; |
+ typedef struct { |
+ char *class; |
+ /* ... message data ... */ |
+ } <message class>; |
Line 12 was replaced by line 12 |
- Example: |
+ Given the following functions dealing with callbacks: |
Line 14 was replaced by lines 14-49 |
- static char *setCallbackClass="set callback"; |
+ typedef void KillFunc(void *); |
+ typedef int CallbackFunction(Hdb *node, void *msg, void *data); |
+ typedef struct Callback Callback; |
+ |
+ InvokeCallback(Hdb *node, void *msg); |
+ Callback *MakeCallback(CallbackFunction *cbFunc, void *data, KillFunc *killFunc); |
+ AppendCallback(Hdb *node, Callback *cb); |
+ PrependCallback(Hdb *node, Callback *cb); |
+ }}} |
+ The callbacks are stored as one list per node. |
+ |
+ Extract from (sics)hipadaba.h: |
+ {{{ |
+ typedef struct { |
+ char *class; |
+ SConnection *pCon; |
+ ValueStruct *value; |
+ } SetCallbackMsg; |
+ |
+ SetCallbackMsg *SetCallbackCast(void *msg); |
+ }}} |
+ |
+ The members of callback message contain the additional arguments needed for the handling of |
+ the callback. SetCallbackCast reveals if an anonymous message is a SetCallbackMsg. It returns |
+ NULL otherwise. |
+ |
+ Extract from (sics)hipadaba.c: |
+ {{{ |
+ static char *setCallbackClass="set callback"; |
+ |
+ SetCallbackMsg *SetCallbackCast(void *msg) { |
+ if (((SetCallbackMsg *)msg)->class == setCallbackClass) { |
+ return msg; |
+ } |
+ return NULL; |
+ } |
Lines 16-21 were replaced by line 51 |
- typedef struct { |
- char *class; |
- SConnection *pCon; |
- Hdb *node; |
- ValueStruct *value; |
- } SetCallbackMsg; |
+ ... |
Line 23 was replaced by line 53 |
- ... |
+ /* calling the callback */ |
Removed lines 25-26 |
- /* calling the callback */ |
- { |
Removed line 30 |
- setMsg.node = node; |
Line 32 was replaced by lines 59-114 |
- CallCallback(callbacklist, &setMsg); |
+ InvokeCallback(node, &setMsg); |
+ }}} |
+ |
+ The text content of setCallbackClass is not very important, it may be used |
+ for logging purposes. The check for a particular class is done by comparing |
+ the pointers, not the contents. |
+ |
+ Extract from a module implementing a callback: |
+ {{{ |
+ int MySetCallback(Hdb *node, void *msg, void *data) { |
+ SetCallbackMsg *setMsg = SetCallbackCast(msg); |
+ MyData *mydata; |
+ |
+ if (! setMsg) return 0; /* not handled */ |
+ |
+ mydata = data; |
+ /* do the set */ |
+ |
+ return 1; |
+ } |
+ |
+ ... |
+ |
+ void KillMyData(MyData *data) { |
+ /* free resources */ |
+ } |
+ ... |
+ |
+ MyData *data; |
+ Callback *cb; |
+ |
+ cb = MakeCallback(MySetCallback, data, (KillFunc *)KillMyData); |
+ AppendCallback(node, cb); |
+ }}} |
+ |
+ An implementation may use the same callback function for handling different |
+ callback messages, with the same user data: |
+ {{{ |
+ int CombinedCallback(Hdb *node, void *msg, void *data) { |
+ SetCallbackMsg *setMsg; |
+ UpdateCallbackMsg *updateMsg; |
+ MyData *mydata = data; |
+ |
+ setMsg = SetCallbackCast(msg); |
+ if (setMsg) { |
+ /* handle setMsg */ |
+ return 1; |
+ } |
+ |
+ updateMsg= UpdateCallbackCast(msg); |
+ if (updateMsg) { |
+ /* handle updateMsg */ |
+ return 1; |
+ } |
+ |
+ return 0; /* not handled */ |
At line 33 added 10 lines. |
+ }}} |
+ |
+ For the implementation of Hipadaba at least the following callbacks have |
+ to be implemented: |
+ |
+ * SetCallback |
+ * ReadCallback |
+ * UpdateCallback |
+ * KillForIDCallback |
+ * KillForInternalIDCallback |