#ifndef __STATES_H__ #define __STATES_H__ #include #include struct event; enum { /* * This flag marks events as temporary. * * Thos are only used to trigger callbacks. And have the following odd * semantics: * - They will not appear in event_state * - They will not conceal calls with the same value * * They have been added to support the callback usage for * ab_onhook//offhook/fehler/active. Sadly this is the only usage and * new users of this feature are STRONGLY DISCOURAGED! */ EVENT_FLAG_TRANSIENT = (1 << 0), }; typedef void (*event_callback)(struct event *event, int old, int new); struct event_member_def { const char *name; int event_id; struct { int ms; int next; } timeout; }; struct event { const char *name; int max_state; const struct event_member_def *def; // Value atomic_t current_value; atomic_t pending_value; // Timeout related int timeout_setup; unsigned long timeout; // int raw_event_id; // int flags; // Callback on value update event_callback callback; }; /* * Now include all events, which are basically states */ #define DEFINE_EVENT_STATE(_name, ...) \ enum _name##_values{ \ _name##_unknown = 0, \ __VA_ARGS__ \ _name##_invalid, \ }; \ extern struct event __event_##_name; \ static struct event *const _name = &__event_##_name; #define DEFINE_EVENT(_name, ...) _name, #define DEFINE_EVENT_RAW(_name, ...) \ extern struct event __event_##_name; \ static struct event *const _name = &__event_##_name; #define DEFINE_EVENT_RAW_INTERNAL(_name, ...) DEFINE_EVENT_RAW(_name) #include static inline int event_get_value(struct event *event) { return atomic_read(&event->current_value); } /* * Will be called during the hui update cycle. * * Unless EVENT_FLAG_TRANSIENT is specified, will only be called if the value * changed. */ static inline void event_set_callback(struct event *event, event_callback cb) { event->callback = cb; } static inline int event_is_transient(const struct event *event) { return event->flags & EVENT_FLAG_TRANSIENT; } #endif