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