1/* 2 * Copyright 1999, Be Incorporated. 3 * Copyright (c) 1999-2000, Eric Moon. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions, and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 28 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 33//////////////////////////////////////////////////////////// 34// MultiInvoker.cpp 35// ---------------- 36// Implements the MultiInvoker class. 37// 38 39#include <Messenger.h> 40#include "MultiInvoker.h" 41 42MultiInvoker::MultiInvoker() 43{ 44 m_message = 0; 45 m_timeout = B_INFINITE_TIMEOUT; 46 m_replyHandler = 0; 47} 48 49MultiInvoker::MultiInvoker(const MultiInvoker& src) 50{ 51 Clone(src); 52} 53 54MultiInvoker::~MultiInvoker() 55{ 56 Clear(); 57} 58 59MultiInvoker& MultiInvoker::operator=(const MultiInvoker& src) 60{ 61 if (this != &src) { 62 Clear(); 63 Clone(src); 64 } 65 return *this; 66} 67 68void MultiInvoker::Clear() 69{ 70 delete m_message; 71 int32 i=CountTargets(); 72 while (--i >=0) { 73 RemoveTarget(i); 74 } 75} 76 77void MultiInvoker::Clone(const MultiInvoker& src) 78{ 79 m_message = new BMessage(*src.Message()); 80 int32 len=src.CountTargets(); 81 for (int32 i=0; i<len; i++) { 82 AddTarget(src.TargetAt(i)); 83 } 84 m_timeout = src.Timeout(); 85 m_replyHandler = src.HandlerForReply(); 86} 87 88void MultiInvoker::SetMessage(BMessage* message) 89{ 90 delete m_message; 91 m_message = message; 92} 93 94BMessage* MultiInvoker::Message() const 95{ 96 return m_message; 97} 98 99uint32 MultiInvoker::Command() const 100{ 101 return (m_message) ? m_message->what : 0; 102} 103 104status_t MultiInvoker::AddTarget(const BHandler* h, const BLooper* loop) 105{ 106 status_t err; 107 BMessenger* msgr = new BMessenger(h, loop, &err); 108 if (err == B_OK) 109 m_messengers.AddItem(msgr); 110 else 111 delete msgr; 112 return err; 113} 114 115status_t MultiInvoker::AddTarget(BMessenger* msgr) 116{ 117 if (msgr) { 118 m_messengers.AddItem(msgr); 119 return B_OK; 120 } else { 121 return B_BAD_VALUE; 122 } 123} 124 125void MultiInvoker::RemoveTarget(const BHandler* h) 126{ 127 int32 i = IndexOfTarget(h); 128 if (i >= 0) 129 RemoveTarget(i); 130} 131 132void MultiInvoker::RemoveTarget(int32 index) 133{ 134 BMessenger* msgr = static_cast<BMessenger*> 135 (m_messengers.RemoveItem(index)); 136 delete msgr; 137} 138 139int32 MultiInvoker::IndexOfTarget(const BHandler* h) const 140{ 141 int32 len = CountTargets(); 142 for (int32 i=0; i<len; i++) { 143 BMessenger* msgr = MessengerAt(i); 144 if (msgr && msgr->Target(0) == h) { 145 return i; 146 } 147 } 148 return -1; 149} 150 151int32 MultiInvoker::CountTargets() const 152{ 153 return m_messengers.CountItems(); 154} 155 156BHandler* MultiInvoker::TargetAt(int32 index, BLooper** looper) const 157{ 158 BMessenger* msgr = MessengerAt(index); 159 if (msgr) { 160 return msgr->Target(looper); 161 } else { 162 if (looper) *looper = 0; 163 return 0; 164 } 165} 166 167BMessenger* MultiInvoker::MessengerAt(int32 index) const 168{ 169 return static_cast<BMessenger*> 170 (m_messengers.ItemAt(index)); 171} 172 173bool MultiInvoker::IsTargetLocal(int32 index) const 174{ 175 BMessenger* msgr = MessengerAt(index); 176 return (msgr) ? msgr->IsTargetLocal() : false; 177} 178 179void MultiInvoker::SetTimeout(bigtime_t timeout) 180{ 181 m_timeout = timeout; 182} 183 184bigtime_t MultiInvoker::Timeout() const 185{ 186 return m_timeout; 187} 188 189void MultiInvoker::SetHandlerForReply(BHandler* h) 190{ 191 m_replyHandler = h; 192} 193 194BHandler* MultiInvoker::HandlerForReply() const 195{ 196 return m_replyHandler; 197} 198 199status_t MultiInvoker::Invoke(BMessage* msg) 200{ 201 BMessage* sendMsg = (msg) ? msg : m_message; 202 if (! sendMsg) 203 return B_BAD_VALUE; 204 205 status_t err, finalResult=B_OK; 206 BMessage replyMsg; 207 int32 len = CountTargets(); 208 for (int32 i=0; i<len; i++) { 209 BMessenger* msgr = MessengerAt(i); 210 if (msgr) { 211 err = msgr->SendMessage(sendMsg, 212 HandlerForReply(), m_timeout); 213 if (err != B_OK) finalResult = err; 214 } 215 } 216 return finalResult; 217} 218