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 else 82 delete msgr; 83 return err; 84 } 85 86 status_t MultiInvoker::AddTarget(BMessenger* msgr) 87 { 88 if (msgr) { 89 m_messengers.AddItem(msgr); 90 return B_OK; 91 } else { 92 return B_BAD_VALUE; 93 } 94 } 95 96 void MultiInvoker::RemoveTarget(const BHandler* h) 97 { 98 int32 i = IndexOfTarget(h); 99 if (i >= 0) 100 RemoveTarget(i); 101 } 102 103 void MultiInvoker::RemoveTarget(int32 index) 104 { 105 BMessenger* msgr = static_cast<BMessenger*> 106 (m_messengers.RemoveItem(index)); 107 delete msgr; 108 } 109 110 int32 MultiInvoker::IndexOfTarget(const BHandler* h) const 111 { 112 int32 len = CountTargets(); 113 for (int32 i=0; i<len; i++) { 114 BMessenger* msgr = MessengerAt(i); 115 if (msgr && msgr->Target(0) == h) { 116 return i; 117 } 118 } 119 return -1; 120 } 121 122 int32 MultiInvoker::CountTargets() const 123 { 124 return m_messengers.CountItems(); 125 } 126 127 BHandler* MultiInvoker::TargetAt(int32 index, BLooper** looper) const 128 { 129 BMessenger* msgr = MessengerAt(index); 130 if (msgr) { 131 return msgr->Target(looper); 132 } else { 133 if (looper) *looper = 0; 134 return 0; 135 } 136 } 137 138 BMessenger* MultiInvoker::MessengerAt(int32 index) const 139 { 140 return static_cast<BMessenger*> 141 (m_messengers.ItemAt(index)); 142 } 143 144 bool MultiInvoker::IsTargetLocal(int32 index) const 145 { 146 BMessenger* msgr = MessengerAt(index); 147 return (msgr) ? msgr->IsTargetLocal() : false; 148 } 149 150 void MultiInvoker::SetTimeout(bigtime_t timeout) 151 { 152 m_timeout = timeout; 153 } 154 155 bigtime_t MultiInvoker::Timeout() const 156 { 157 return m_timeout; 158 } 159 160 void MultiInvoker::SetHandlerForReply(BHandler* h) 161 { 162 m_replyHandler = h; 163 } 164 165 BHandler* MultiInvoker::HandlerForReply() const 166 { 167 return m_replyHandler; 168 } 169 170 status_t MultiInvoker::Invoke(BMessage* msg) 171 { 172 BMessage* sendMsg = (msg) ? msg : m_message; 173 if (! sendMsg) 174 return B_BAD_VALUE; 175 176 status_t err, finalResult=B_OK; 177 BMessage replyMsg; 178 int32 len = CountTargets(); 179 for (int32 i=0; i<len; i++) { 180 BMessenger* msgr = MessengerAt(i); 181 if (msgr) { 182 err = msgr->SendMessage(sendMsg, 183 HandlerForReply(), m_timeout); 184 if (err != B_OK) finalResult = err; 185 } 186 } 187 return finalResult; 188 } 189