changeset 198:f9d507a3e1d9

Add event observer which listen to one event type only.
author wycc@wycc-desktop
date Fri, 05 Dec 2008 22:12:18 +0800
parents bcad1ccdf45c
children 55533146efdf
files examples/svg2code_ex/main.c include/mb_observer.h src/observer.c
diffstat 3 files changed, 33 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/examples/svg2code_ex/main.c	Wed Nov 19 00:27:20 2008 +0800
+++ b/examples/svg2code_ex/main.c	Fri Dec 05 22:12:18 2008 +0800
@@ -14,34 +14,23 @@
     svg2code_ex_t *code;
 };
 
+#define COORD_SHOW(group) coord_show(group);rdman_coord_changed(X_MB_rdman(ex_rt->rt), group)
+#define COORD_HIDE(group) coord_hide(group);rdman_coord_changed(X_MB_rdman(ex_rt->rt), group)
+
 static void file_button_handler(event_t *evt, void *arg) {
     ex_rt_t *ex_rt = (ex_rt_t *)arg;
 
-    switch(evt->type) {
-    case EVT_MOUSE_BUT_PRESS:
-	coord_show(ex_rt->code->file_menu);
-	/* Tell redraw manager that a coord (group) is chagned. */
-	rdman_coord_changed(X_MB_rdman(ex_rt->rt), ex_rt->code->file_menu);
-	/* Update changed part to UI. */
-	rdman_redraw_changed(X_MB_rdman(ex_rt->rt));
-	break;
-    }
+    COORD_SHOW(ex_rt->code->file_menu);
+    /* Update changed part to UI. */
+    rdman_redraw_changed(X_MB_rdman(ex_rt->rt));
 }
 
 static void file_menu_handler(event_t *evt, void *arg) {
     ex_rt_t *ex_rt = (ex_rt_t *)arg;
-    redraw_man_t *rdman;
 
-    rdman = X_MB_rdman(ex_rt->rt);
-    switch(evt->type) {
-    case EVT_MOUSE_BUT_PRESS:
-	coord_hide(ex_rt->code->file_menu);
-	/* Tell redraw manager that a coord (group) is chagned. */
-	rdman_coord_changed(rdman, ex_rt->code->file_menu);
-	/* Update changed part to UI. */
-	rdman_redraw_changed(rdman);
-	break;
-    }
+    COORD_HIDE(ex_rt->code->file_menu);
+    /* Update changed part to UI. */
+    rdman_redraw_changed(X_MB_rdman(ex_rt->rt));
 }
 
 int main(int argc, char * const argv[]) {
@@ -68,9 +57,9 @@
     subject = coord_get_mouse_event(svg2code->file_button);
     ex_rt.rt = rt;
     ex_rt.code = svg2code;
-    subject_add_observer(subject, file_button_handler, &ex_rt);
+    subject_add_event_observer(subject,  EVT_MOUSE_BUT_PRESS, file_button_handler, &ex_rt);
     subject = coord_get_mouse_event(svg2code->file_menu);
-    subject_add_observer(subject, file_menu_handler, &ex_rt);
+    subject_add_event_observer(subject,  EVT_MOUSE_BUT_PRESS,  file_menu_handler, &ex_rt);
 
     /*
      * Start handle connections, includes one to X server.
--- a/include/mb_observer.h	Wed Nov 19 00:27:20 2008 +0800
+++ b/include/mb_observer.h	Fri Dec 05 22:12:18 2008 +0800
@@ -20,6 +20,7 @@
  * A target for receiving events.
  */
 struct _observer {
+    int type;
     evt_handler hdr;
     void *arg;
     observer_t *next;
@@ -71,7 +72,7 @@
 				     subject_t *cur_subject);
 };
 
-enum {EVT_MOUSE_OVER, EVT_MOUSE_OUT, EVT_MOUSE_MOVE,
+enum {EVT_ANY,EVT_MOUSE_OVER, EVT_MOUSE_OUT, EVT_MOUSE_MOVE,
       EVT_MOUSE_BUT_PRESS, EVT_MOUSE_BUT_RELEASE,
       EVT_KB_PRESS, EVT_KB_RELEASE, EVT_PROGM_COMPLETE,
       EVT_RDMAN_REDRAW };
--- a/src/observer.c	Wed Nov 19 00:27:20 2008 +0800
+++ b/src/observer.c	Fri Dec 05 22:12:18 2008 +0800
@@ -65,7 +65,8 @@
 	for(observer = STAILQ_HEAD(subject->observers);
 	    observer != NULL;
 	    observer = STAILQ_NEXT(observer_t, next, observer)) {
-	    observer->hdr(evt, observer->arg);
+	    if (observer->type == EVT_ANY || observer->type == evt->type)
+		    observer->hdr(evt, observer->arg);
 	}
 
 	subject->flags &= ~SUBF_BUSY;
@@ -90,6 +91,24 @@
 	return NULL;
     observer->hdr = hdr;
     observer->arg = arg;
+    observer->type = EVT_ANY;
+
+    STAILQ_INS_TAIL(subject->observers, observer_t, next, observer);
+
+    return observer;
+}
+
+observer_t *subject_add_event_observer(subject_t *subject, int type,
+				 evt_handler hdr, void *arg) {
+    ob_factory_t *factory = subject->factory;
+    observer_t *observer;
+
+    observer = factory->observer_alloc(factory);
+    if(observer == NULL)
+	return NULL;
+    observer->hdr = hdr;
+    observer->arg = arg;
+    observer->type = type;
 
     STAILQ_INS_TAIL(subject->observers, observer_t, next, observer);