Import into DevLib.
[bertos.git] / dt / dnotifier.h
1 /*!
2  * \file
3  * <!--
4  * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
5  * -->
6  *
7  * \version $Id$
8  *
9  * \brief Notifier obj (interface).
10  *
11  * \version $Id$
12  * \author Bernardo Innocenti <bernie@develer.com>
13  * \author Francesco Sacchi <batt@develer.com>
14  */
15
16 /*#*
17  *#* $Log$
18  *#* Revision 1.1  2005/11/04 18:26:38  bernie
19  *#* Import into DevLib.
20  *#*
21  *#* Revision 1.4  2005/06/09 13:23:58  batt
22  *#* Add some comments.
23  *#*
24  *#* Revision 1.3  2005/06/08 17:32:33  batt
25  *#* Switch to new messaging system.
26  *#*
27  *#* Revision 1.2  2005/06/06 11:04:12  batt
28  *#* Add some comments.
29  *#*
30  *#* Revision 1.1  2005/05/26 08:32:53  batt
31  *#* Add new Develer widget system :)
32  *#*
33  *#*/
34 #ifndef DT_DNOTIFIER_H
35 #define DT_DNOTIFIER_H
36
37 #include <cfg/debug.h>
38 #include <dt/dtag.h>
39 #include <mware/list.h>
40
41 //Fwd declaretion.
42 struct DNotifier;
43 struct DFilter;
44
45 typedef void (* update_func_ptr)(struct DNotifier *, dtag_t, dval_t);
46 typedef void (* update_filter_ptr)(struct DFilter *, dtag_t, dval_t);
47
48 /*!
49  * Base object for receive and forward messages.
50  * It contains an update function used to update itslef and a list to
51  * notify other DNotifer eventually connected.
52  */
53 typedef struct DNotifier
54 {
55         //! Receive new attributes from other notifiers.
56         update_func_ptr update;
57
58         //! List of target notifiers to set new attributes to.
59         List targets;
60 } DNotifier;
61
62 /*!
63  * Map for messages.
64  * Used to translate src message to dst message.
65  */
66 typedef struct DFilterMap
67 {
68         DTagItem src;
69         DTagItem dst;
70 } DFilterMap;
71
72
73 /*!
74  * A filter is an interface between two notifier.
75  * It can translate messages between them through a map (if it is not null).
76  */
77 typedef struct DFilter
78 {
79         //! Allow creating a list of dfilter objects.
80         Node link;
81
82         //! Target of the filter
83         DNotifier *target;
84
85         //! Update function called by the source dnotifier
86         update_filter_ptr update;
87
88         //!Map for translating messages for target
89         const DFilterMap *map;
90
91         //!Used in debug to prevent inserting this filter in more than one list
92         DB(uint8_t magic;)
93 } DFilter;
94
95 //! Type for filter-mask checking
96 typedef uint16_t dfilter_mask_t;
97
98 //! Filter init
99 void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target);
100
101 //! Filter update function without masking capabilities.
102 void filter_update(DFilter *f, dtag_t tag, dval_t val);
103
104 //! Filter update function with masking capabilities.
105 void filter_mask_update(DFilter *f, dtag_t tag, dval_t val);
106
107 //! Notifier init
108 void notifier_init(DNotifier *n);
109
110
111 /*!
112  * Macro to notify the target object.
113  */
114 INLINE void dnotify(DNotifier *target, dtag_t tag, dval_t val)
115 {
116         if (target)
117                 target->update(target, tag, val);
118 }
119
120 /*!
121  * Macro to notify all the targets of \a target object.
122  */
123 INLINE void dnotify_targets(DNotifier *target, dtag_t tag, dval_t val)
124 {
125         DFilter *f;
126         if (!ISLISTEMPTY(&target->targets))
127                 FOREACHNODE(f, &target->targets)
128                         f->update(f, tag, val);
129 }
130
131
132 /*!
133  * Macro that connect \a src notifier to \a tgt using \a map and passing \a opt for filtering option.
134  * It declares a static filter to achieve connection and messages translation.
135  * \note Due its static filter declaration, DCONNECT MUST NOT be used inside loops or in functions called multiple times.
136  * Failing to do so will lead to unpredictable connections between notifiers.
137  */
138 #define DCONNECT(src, tgt, map, opt) \
139         do { \
140                 static DFilter _filter_; /* Declare a filter */ \
141                 filter_init(&(_filter_), map, opt, src, tgt); /* Init it. */ \
142         } while (0)
143
144
145 #endif /* DT_DNOTIFIER_H */