equeue icon indicating copy to clipboard operation
equeue copied to clipboard

Provide pick event function

Open gghyoo opened this issue 9 years ago • 1 comments

This lib is very good , but can you provide pick event functions that I can handle the event by myself.

some thing like following:


// post a event somewhere
equeue_post_event(queue, type, param);


// pick event by wait function
if(equeue_wait_event(queue, &type, &param, timeout) >= 0)
{
    switch(type)
    {
        case EV_EVENT1:
            //do someting ...
        break;
        case EV_EVENT2:
            //do someting ...
        break;
    }
}

gghyoo avatar Nov 05 '16 03:11 gghyoo

Hello, thanks for the interest!

The API you are suggesting would be reasonable, but the goal for the equeue library is to provide a small API that is robust and well tested. I would like to see how far the current API can take the project before extending it too much.


That being said, with the current API you could create a wrapper like the following. This could be used locally in your project to get the API you would like and also have the flexibility to use an enum with values relevant to your system:

#include "equeue.h"

// wrapper around equeue with storage for current event
typedef struct equeue_with_event {
    // event enum indicates the type and can be changed for the
    // event types in the system
    enum event {
        EVENT_NONE,
        EVENT_A,
        EVENT_B,
        EVENT_C,
    } event;
    void *data;
    equeue_t queue;
} equeue_with_event_t;

// waits for an event to be posted
// asigns the event type and data to the arguments passed by address
// returns false if no event occurs before the specified timeout in milliseconds
bool equeue_wait_event(equeue_with_event_t *queue,
        enum event *event, void **data, int timeout) {
    equeue_dispatch(&queue->queue, timeout);
    *event = queue->event;
    *data = queue->data;
    queue->event = EVENT_NONE;
    return *event != EVENT_NONE;
}

// internal context for event
struct equeue_event_struct {
    equeue_with_event_t *queue;
    enum event event;
    void *data;
};

// internal callback for event
static void equeue_event_cb(void *p) {
    struct equeue_event_struct *e = p;
    e->queue->event = e->event;
    e->queue->data = e->data;
    equeue_break(&e->queue->queue);
}

// posts an event with the event type described by the "event" enum
// the event type and data are passed to the equeue_wait_event function
int equeue_post_event(equeue_with_event_t *queue,
        enum event event, void *data) {
    struct equeue_event_struct *e =
            equeue_alloc(&queue->queue, sizeof(struct equeue_event_struct));
    e->queue = queue;
    e->event = event;
    e->data = data;
    // note that the assignment to the current event occurs in the context of the 
    // event queue's dispatch function to avoid synchronization concerns
    return equeue_post(&queue->queue, equeue_event_cb, e);
}

Here's an example using it (I tried to match your use case):

#include "equeue_with_event.h"
#incclude <stdio.h>

int main(void) {
    equeue_with_events_t q;
    equeue_create(&q.queue, 1024);
    equeue_post_event(&q, EVENT_A, 0);

    enum event event;
    void *data;

    // dispatch events for two seconds
    while (equeue_wait_event(&q, &event, &data, 2000)) {
        switch (event) {
            case EVENT_A:
                printf("event a!\n");
            break;
            case EVENT_B:
                printf("event b!\n");
            break;
        }
    }
}

geky avatar Nov 05 '16 21:11 geky