1 //////////////////////////////////////////////////////////// 2 // MultiInvoker.cpp 3 // ---------------- 4 // Implements the MultiInvoker class. 5 // 6 // Copyright 1999, Be Incorporated. All Rights Reserved. 7 // This file may be used under the terms of the Be Sample 8 // Code License. 9 10 #include <Messenger.h> 11 #include "MultiInvoker.h" 12 13 MultiInvoker::MultiInvoker() 14 { 15 m_message = 0; 16 m_timeout = B_INFINITE_TIMEOUT; 17 m_replyHandler = 0; 18 } 19 20 MultiInvoker::MultiInvoker(const MultiInvoker& src) 21 { 22 Clone(src); 23 } 24 25 MultiInvoker::~MultiInvoker() 26 { 27 Clear(); 28 } 29 30 MultiInvoker& MultiInvoker::operator=(const MultiInvoker& src) 31 { 32 if (this != &src) { 33 Clear(); 34 Clone(src); 35 } 36 return *this; 37 } 38 39 void MultiInvoker::Clear() 40 { 41 delete m_message; 42 int32 i=CountTargets(); 43 while (--i >=0) { 44 RemoveTarget(i); 45 } 46 } 47 48 void MultiInvoker::Clone(const MultiInvoker& src) 49 { 50 m_message = new BMessage(*src.Message()); 51 int32 len=src.CountTargets(); 52 for (int32 i=0; i<len; i++) { 53 AddTarget(src.TargetAt(i)); 54 } 55 m_timeout = src.Timeout(); 56 m_replyHandler = src.HandlerForReply(); 57 } 58 59 void MultiInvoker::SetMessage(BMessage* message) 60 { 61 delete m_message; 62 m_message = message; 63 } 64 65 BMessage* MultiInvoker::Message() const 66 { 67 return m_message; 68 } 69 70 uint32 MultiInvoker::Command() const 71 { 72 return (m_message) ? m_message->what : 0; 73 } 74 75 status_t MultiInvoker::AddTarget(const BHandler* h, const BLooper* loop) 76 { 77 status_t err; 78 BMessenger* msgr = new BMessenger(h, loop, &err); 79 if (err == B_OK) 80 m_messengers.AddItem(msgr); 81 82 return err; 83 } 84 85 status_t MultiInvoker::AddTarget(BMessenger* msgr) 86 { 87 if (msgr) { 88 m_messengers.AddItem(msgr); 89 return B_OK; 90 } else { 91 return B_BAD_VALUE; 92 } 93 } 94 95 void MultiInvoker::RemoveTarget(const BHandler* h) 96 { 97 int32 i = IndexOfTarget(h); 98 if (i >= 0) 99 RemoveTarget(i); 100 } 101 102 void MultiInvoker::RemoveTarget(int32 index) 103 { 104 BMessenger* msgr = static_cast<BMessenger*> 105 (m_messengers.RemoveItem(index)); 106 delete msgr; 107 } 108 109 int32 MultiInvoker::IndexOfTarget(const BHandler* h) const 110 { 111 int32 len = CountTargets(); 112 for (int32 i=0; i<len; i++) { 113 BMessenger* msgr = MessengerAt(i); 114 if (msgr && msgr->Target(0) == h) { 115 return i; 116 } 117 } 118 return -1; 119 } 120 121 int32 MultiInvoker::CountTargets() const 122 { 123 return m_messengers.CountItems(); 124 } 125 126 BHandler* MultiInvoker::TargetAt(int32 index, BLooper** looper) const 127 { 128 BMessenger* msgr = MessengerAt(index); 129 if (msgr) { 130 return msgr->Target(looper); 131 } else { 132 if (looper) *looper = 0; 133 return 0; 134 } 135 } 136 137 BMessenger* MultiInvoker::MessengerAt(int32 index) const 138 { 139 return static_cast<BMessenger*> 140 (m_messengers.ItemAt(index)); 141 } 142 143 bool MultiInvoker::IsTargetLocal(int32 index) const 144 { 145 BMessenger* msgr = MessengerAt(index); 146 return (msgr) ? msgr->IsTargetLocal() : false; 147 } 148 149 void MultiInvoker::SetTimeout(bigtime_t timeout) 150 { 151 m_timeout = timeout; 152 } 153 154 bigtime_t MultiInvoker::Timeout() const 155 { 156 return m_timeout; 157 } 158 159 void MultiInvoker::SetHandlerForReply(BHandler* h) 160 { 161 m_replyHandler = h; 162 } 163 164 BHandler* MultiInvoker::HandlerForReply() const 165 { 166 return m_replyHandler; 167 } 168 169 status_t MultiInvoker::Invoke(BMessage* msg) 170 { 171 BMessage* sendMsg = (msg) ? msg : m_message; 172 if (! sendMsg) 173 return B_BAD_VALUE; 174 175 status_t err, finalResult=B_OK; 176 BMessage replyMsg; 177 int32 len = CountTargets(); 178 for (int32 i=0; i<len; i++) { 179 BMessenger* msgr = MessengerAt(i); 180 if (msgr) { 181 err = msgr->SendMessage(sendMsg, 182 HandlerForReply(), m_timeout); 183 if (err != B_OK) finalResult = err; 184 } 185 } 186 return finalResult; 187 } 188