btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / cortex / support / observe.h
blob37379f7f22a6fe2a8b44330af043bc9de01c04a8
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // Observe.h (cortex)
33 // * PURPOSE
34 // Messages used for implementation of the Observer pattern.
36 // * HISTORY
37 // e.moon 19aug99 Begun
39 #ifndef __Observe_H__
40 #define __Observe_H__
42 #include <Messenger.h>
43 #include <Debug.h>
44 #include <string.h>
46 #include "cortex_defs.h"
47 __BEGIN_CORTEX_NAMESPACE
49 // -------------------------------------------------------- //
50 // *** MESSAGES ***
51 // -------------------------------------------------------- //
53 // messages sent to the Observable (source)
54 enum observer_message_t {
55 // Requests that an observer be added to a given
56 // observable (target).
57 // - "observer" (BMessenger)
58 M_ADD_OBSERVER = Observer_message_base,
60 // Requests that a given observable (target) stop
61 // sending notifications to a given observer.
62 // Should be sent in response to M_RELEASE_OBSERVABLE
63 // in order to allow the observable object to be deleted.
64 // - "observer" (BMessenger)
65 M_REMOVE_OBSERVER,
67 // Requests that an observable quit immediately without
68 // waiting for its observers to acknowledge that they're done.
69 // This should only be posted to an Observable in an
70 // emergency
71 M_KILL_OBSERVABLE
75 // messages sent by the Observable (target)
76 enum target_message_t {
77 // sent when the target is no longer needed; the
78 // observer should reply with M_REMOVE_OBSERVER in order
79 // to release (allow the deletion of) the target
80 // - "target" (BMessenger)
81 M_RELEASE_OBSERVABLE = Observable_message_base,
83 // SUGGESTED BUT NOT REQUIRED FOR IObservable IMPLEMENTATION:
84 // *** IObservables are encouraged to send other replies!
85 // sent upon successful receipt of M_ADD_OBSERVER
86 // - "target" (BMessenger)
87 M_OBSERVER_ADDED,
89 // SUGGESTED BUT NOT REQUIRED FOR IObservable IMPLEMENTATION:
90 // *** IObservables are encouraged to send other replies!
91 // sent upon successful receipt of M_REMOVE_OBSERVER
92 // - "target" (BMessenger)
93 M_OBSERVER_REMOVED,
95 // sent when no matching observer was found for an
96 // M_REMOVE_OBSERVER message, or if the observer specified
97 // in an M_ADD_OBSERVER message was previously added.
98 // - "target" (BMessenger)
99 // - "observer" (BMessenger)
100 M_BAD_OBSERVER,
102 // sent when the target receiving an M_ADD_OBSERVER
103 // or M_REMOVE_OBSERVER didn't match the target described
104 // in the message. also sent if the target is currently
105 // in the process of quitting (it's already sent M_RELEASE_OBSERVABLE
106 // to its current observers, and is waiting for them to acknowledge
107 // with M_REMOVE_OBSERVER so that it can delete itself.)
108 // - "target" (BMessenger)
109 // - "observer" (BMessenger)
110 M_BAD_TARGET
113 // -------------------------------------------------------- //
114 // *** FUNCTIONS ***
115 // -------------------------------------------------------- //
117 // * Asynchronous
119 status_t add_observer(
120 const BMessenger& observer,
121 const BMessenger& target);
123 status_t remove_observer(
124 const BMessenger& observer,
125 const BMessenger& target);
127 // * Synchronous
129 status_t add_observer(
130 const BMessenger& observer,
131 const BMessenger& target,
132 BMessage& reply,
133 bigtime_t timeout =B_INFINITE_TIMEOUT);
135 status_t remove_observer(
136 const BMessenger& observer,
137 const BMessenger& target,
138 BMessage& reply,
139 bigtime_t timeout =B_INFINITE_TIMEOUT);
141 // -------------------------------------------------------- //
142 // *** TOOL CLASSES ***
143 // -------------------------------------------------------- //
145 template <class _observable_t>
146 class observer_handle {
148 public: // ctor/dtor
150 virtual ~observer_handle() {}
152 observer_handle(
153 const BMessenger& observer,
154 _observable_t* target,
155 bigtime_t timeout =B_INFINITE_TIMEOUT) :
157 _observer_messenger(observer),
158 _target_messenger(target),
159 _target_cache(target),
160 _timeout(timeout),
161 _valid(false) {
163 BMessage reply;
164 status_t err = add_observer(
165 _observer_messenger,
166 _target_messenger,
167 reply, timeout);
168 if(err < B_OK) {
169 PRINT((
170 "! observer_handle<>(): add_observer() failed:\n"
171 " %s\n", strerror(err)));
172 #if DEBUG
173 PRINT((
174 " * target's reply:\n"));
175 reply.PrintToStream();
176 #endif
178 else _valid = true;
181 public: // interface
183 virtual void release() {
184 if(!_valid) {
185 PRINT((
186 "! observer_handle<>::release(): invalid or already released.\n"));
187 return;
190 BMessage reply;
191 status_t err = remove_observer(
192 _observer_messenger,
193 _target_messenger,
194 reply,
195 _timeout);
196 if(err < B_OK) {
197 PRINT((
198 "! observer_handle<>::release(): remove_observer() failed:\n"
199 " %s\n", strerror(err)));
200 #if DEBUG
201 PRINT((
202 " * target's reply:\n"));
203 reply.PrintToStream();
204 #endif
207 _valid = false;
210 private:
211 const BMessenger _observer_messenger;
212 BMessenger _target_messenger;
213 _observable_t* _target_cache;
214 bigtime_t _timeout;
215 bool _valid;
219 __END_CORTEX_NAMESPACE
220 #endif /*__Observe_H__*/