Re: [AD] user-defined events

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Sun, 2008-10-05 at 11:45 +1100, Peter Wang wrote:
> On 2008-09-27, Peter Wang <novalazy@xxxxxxxxxx> wrote:
> > Here is a proposal for allowing user-defined events.
> 
> Committed with some modifications.
> 
> As discussed, it's the user's own problem to manage dynamically allocate
> memory which events may point to.
> 

I attached a patch to ex_user_events which shows how to do it.

However, I'm not very happy about it, that cleanup loop is kinda ugly,
and much worse, I'm not 100% sure the example is correct (when applied
to an actual game with 100ds of events created everywhere).

Would it be acceptable to add a callback to ALLEGRO_USER_EVENT which is
called whenever an event is to be destroyed? Or if needed, also another
callback whenever it is duplicated (I assume the only way for this to
happen is when the event source is connected to two queues - but as long
as we support that, we must expect users two use it). I think I already
suggested it earlier, but the callbacks would look something like:

void (*destroy_user_event)(ALLEGRO_EVENT *event);
void (*copy_user_event)(ALLEGRO_EVENT *event);

Then my version of ex_user_events simply would fill in the callbacks and
the burden would be shifted to Allegro to make sure they are called at
the right time.

-- 
Elias Pschernig <elias@xxxxxxxxxx>
Index: ex_user_events.c
===================================================================
--- ex_user_events.c	(revision 11098)
+++ ex_user_events.c	(working copy)
@@ -7,9 +7,36 @@
 
 
 /* XXX Currently we have no formal way to allocate event type numbers. */
-#define MY_EVENT_TYPE   1025
+#define MY_SIMPLE_EVENT_TYPE   1025
+#define MY_COMPLEX_EVENT_TYPE   1026
 
+/* Just some fantasy event, supposedly used in an RPG - it's just to show that
+ * in practice, the 4 user fields we have now never will be enough. */
+typedef struct MY_EVENT
+{
+   int id;
+   int type; /* For example "attack" or "buy". */
+   int x, y, z; /* Position in the game world the event takes place. */
+   int server_time; /* Game time in ticks the event takes place. */
+   int source_unit_id; /* E.g. attacker or seller. */
+   int destination_unit_id; /* E.g. defender of buyer. */
+   int item_id; /* E.g. weapon used or item sold. */
+   int amount; /* Gold the item is sold for. */
+   
+} MY_EVENT;
 
+MY_EVENT *new_event(int id)
+{
+    MY_EVENT *event = calloc(1, sizeof *event);
+    event->id = id;
+    return event;
+}
+
+void del_event(MY_EVENT *event)
+{
+    free(event);
+}
+
 int main(void)
 {
    ALLEGRO_TIMER *timer;
@@ -49,21 +76,45 @@
 
          printf("Got timer event %d\n", n);
 
-         user_event.user.type = MY_EVENT_TYPE;
+         user_event.user.type = MY_SIMPLE_EVENT_TYPE;
          user_event.user.data1 = n;
          al_emit_user_event(user_src, &user_event);
+         
+         user_event.user.type = MY_COMPLEX_EVENT_TYPE;
+         user_event.user.data1 = (intptr_t)new_event(n);
+         al_emit_user_event(user_src, &user_event);
       }
-      else if (event.type == MY_EVENT_TYPE) {
+      else if (event.type == MY_SIMPLE_EVENT_TYPE) {
          int n = (int) event.user.data1;
          ASSERT(event.user.source == user_src);
 
-         printf("Got user event %d\n", n);
+         printf("Got simple user event %d\n", n);
          if (n == 5) {
             break;
          }
       }
+      else if (event.type == MY_COMPLEX_EVENT_TYPE) {
+         MY_EVENT *my_event = (void *)event.user.data1;
+         ASSERT(event.user.source == user_src);
+
+         printf("Got complex user event %d\n", my_event->id);
+         del_event(my_event);
+      }
    }
+   
+   /* We need to clean up lost complex user events. */
+   while (!al_event_queue_is_empty(queue)) {
+      al_get_next_event(queue, &event);
+      if (event.type == MY_COMPLEX_EVENT_TYPE) {
+         MY_EVENT *my_event = (void *)event.user.data1;
+         ASSERT(event.user.source == user_src);
 
+         printf("Cleaned lost complex user event %d\n", my_event->id);
+         del_event(my_event);
+      }
+   }
+
+   al_destroy_event_queue(queue);
    al_destroy_user_event_source(user_src);
    al_uninstall_timer(timer);
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/