1 /* 2 * Copyright 2001-2010 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ingo Weinhold, ingo_weinhold@gmx.de 7 */ 8 9 10 #include <MessageRunner.h> 11 12 #include <Application.h> 13 #include <AppMisc.h> 14 #include <RegistrarDefs.h> 15 #include <Roster.h> 16 #include <RosterPrivate.h> 17 18 19 using namespace BPrivate; 20 21 22 BMessageRunner::BMessageRunner(BMessenger target, const BMessage* message, 23 bigtime_t interval, int32 count) 24 : 25 fToken(-1) 26 { 27 _InitData(target, message, interval, count, be_app_messenger); 28 } 29 30 31 BMessageRunner::BMessageRunner(BMessenger target, const BMessage& message, 32 bigtime_t interval, int32 count) 33 : 34 fToken(-1) 35 { 36 _InitData(target, &message, interval, count, be_app_messenger); 37 } 38 39 40 BMessageRunner::BMessageRunner(BMessenger target, const BMessage* message, 41 bigtime_t interval, int32 count, BMessenger replyTo) 42 : 43 fToken(-1) 44 { 45 _InitData(target, message, interval, count, replyTo); 46 } 47 48 49 BMessageRunner::BMessageRunner(BMessenger target, const BMessage& message, 50 bigtime_t interval, int32 count, BMessenger replyTo) 51 : 52 fToken(-1) 53 { 54 _InitData(target, &message, interval, count, replyTo); 55 } 56 57 58 BMessageRunner::~BMessageRunner() 59 { 60 if (fToken < B_OK) 61 return; 62 63 // compose the request message 64 BMessage request(B_REG_UNREGISTER_MESSAGE_RUNNER); 65 status_t result = request.AddInt32("token", fToken); 66 67 // send the request 68 BMessage reply; 69 if (result == B_OK) 70 result = BRoster::Private().SendTo(&request, &reply, false); 71 72 // ignore the reply, we can't do anything anyway 73 } 74 75 76 status_t 77 BMessageRunner::InitCheck() const 78 { 79 return fToken >= 0 ? B_OK : fToken; 80 } 81 82 83 status_t 84 BMessageRunner::SetInterval(bigtime_t interval) 85 { 86 return _SetParams(true, interval, false, 0); 87 } 88 89 90 status_t 91 BMessageRunner::SetCount(int32 count) 92 { 93 return _SetParams(false, 0, true, count); 94 } 95 96 97 status_t 98 BMessageRunner::GetInfo(bigtime_t* interval, int32* count) const 99 { 100 status_t result = fToken >= 0 ? B_OK : B_BAD_VALUE; 101 102 // compose the request message 103 BMessage request(B_REG_GET_MESSAGE_RUNNER_INFO); 104 if (result == B_OK) 105 result = request.AddInt32("token", fToken); 106 107 // send the request 108 BMessage reply; 109 if (result == B_OK) 110 result = BRoster::Private().SendTo(&request, &reply, false); 111 112 // evaluate the reply 113 if (result == B_OK) { 114 if (reply.what == B_REG_SUCCESS) { 115 // count 116 int32 _count; 117 if (reply.FindInt32("count", &_count) == B_OK) { 118 if (count != 0) 119 *count = _count; 120 } else 121 result = B_ERROR; 122 123 // interval 124 bigtime_t _interval; 125 if (reply.FindInt64("interval", &_interval) == B_OK) { 126 if (interval != 0) 127 *interval = _interval; 128 } else 129 result = B_ERROR; 130 } else { 131 if (reply.FindInt32("error", &result) != B_OK) 132 result = B_ERROR; 133 } 134 } 135 136 return result; 137 } 138 139 140 /*static*/ status_t 141 BMessageRunner::StartSending(BMessenger target, const BMessage* message, 142 bigtime_t interval, int32 count) 143 { 144 int32 token = _RegisterRunner(target, message, interval, count, true, 145 be_app_messenger); 146 147 return token >= B_OK ? B_OK : token; 148 } 149 150 151 /*static*/ status_t 152 BMessageRunner::StartSending(BMessenger target, const BMessage* message, 153 bigtime_t interval, int32 count, BMessenger replyTo) 154 { 155 int32 token = _RegisterRunner(target, message, interval, count, true, 156 replyTo); 157 158 return token >= B_OK ? B_OK : token; 159 } 160 161 162 // FBC 163 void BMessageRunner::_ReservedMessageRunner1() {} 164 void BMessageRunner::_ReservedMessageRunner2() {} 165 void BMessageRunner::_ReservedMessageRunner3() {} 166 void BMessageRunner::_ReservedMessageRunner4() {} 167 void BMessageRunner::_ReservedMessageRunner5() {} 168 void BMessageRunner::_ReservedMessageRunner6() {} 169 170 171 //! Privatized copy constructor to prevent usage. 172 BMessageRunner::BMessageRunner(const BMessageRunner &) 173 : 174 fToken(-1) 175 { 176 } 177 178 179 //! Privatized assignment operator to prevent usage. 180 BMessageRunner& 181 BMessageRunner::operator=(const BMessageRunner&) 182 { 183 return* this; 184 } 185 186 187 /*! Initializes the BMessageRunner. 188 189 The success of the initialization can (and should) be asked for via 190 InitCheck(). 191 192 \note As soon as the last message has been sent, the message runner 193 becomes unusable. InitCheck() will still return \c B_OK, but 194 SetInterval(), SetCount() and GetInfo() will fail. 195 196 \param target Target of the message(s). 197 \param message The message to be sent to the target. 198 \param interval Period of time before the first message is sent and 199 between messages (if more than one shall be sent) in microseconds. 200 \param count Specifies how many times the message shall be sent. 201 A value less than \c 0 for an unlimited number of repetitions. 202 \param replyTo Target replies to the delivered message(s) shall be sent to. 203 */ 204 void 205 BMessageRunner::_InitData(BMessenger target, const BMessage* message, 206 bigtime_t interval, int32 count, BMessenger replyTo) 207 { 208 fToken = _RegisterRunner(target, message, interval, count, false, replyTo); 209 } 210 211 212 /*! Registers the BMessageRunner in the registrar. 213 214 \param target Target of the message(s). 215 \param message The message to be sent to the target. 216 \param interval Period of time before the first message is sent and 217 between messages (if more than one shall be sent) in microseconds. 218 \param count Specifies how many times the message shall be sent. 219 A value less than \c 0 for an unlimited number of repetitions. 220 \param replyTo Target replies to the delivered message(s) shall be sent to. 221 222 \return The token the message runner is registered with, or the error code 223 while trying to register it. 224 */ 225 /*static*/ int32 226 BMessageRunner::_RegisterRunner(BMessenger target, const BMessage* message, 227 bigtime_t interval, int32 count, bool detach, BMessenger replyTo) 228 { 229 status_t result = B_OK; 230 if (message == NULL || count == 0 || (count < 0 && detach)) 231 result = B_BAD_VALUE; 232 233 // compose the request message 234 BMessage request(B_REG_REGISTER_MESSAGE_RUNNER); 235 if (result == B_OK) 236 result = request.AddInt32("team", BPrivate::current_team()); 237 238 if (result == B_OK) 239 result = request.AddMessenger("target", target); 240 241 if (result == B_OK) 242 result = request.AddMessage("message", message); 243 244 if (result == B_OK) 245 result = request.AddInt64("interval", interval); 246 247 if (result == B_OK) 248 result = request.AddInt32("count", count); 249 250 if (result == B_OK) 251 result = request.AddMessenger("reply_target", replyTo); 252 253 // send the request 254 BMessage reply; 255 if (result == B_OK) 256 result = BRoster::Private().SendTo(&request, &reply, false); 257 258 int32 token; 259 260 // evaluate the reply 261 if (result == B_OK) { 262 if (reply.what == B_REG_SUCCESS) { 263 if (reply.FindInt32("token", &token) != B_OK) 264 result = B_ERROR; 265 } else { 266 if (reply.FindInt32("error", &result) != B_OK) 267 result = B_ERROR; 268 } 269 } 270 271 if (result == B_OK) 272 return token; 273 274 return result; 275 } 276 277 278 /*! Sets the message runner's interval and count parameters. 279 280 The parameters \a resetInterval and \a resetCount specify whether 281 the interval or the count parameter respectively shall be reset. 282 283 At least one parameter must be set, otherwise the methods returns 284 \c B_BAD_VALUE. 285 286 \param resetInterval \c true, if the interval shall be reset, \c false 287 otherwise -- then \a interval is ignored. 288 \param interval The new interval in microseconds. 289 \param resetCount \c true, if the count shall be reset, \c false 290 otherwise -- then \a count is ignored. 291 \param count Specifies how many times the message shall be sent. 292 A value less than \c 0 for an unlimited number of repetitions. 293 294 \return A status code. 295 \retval B_OK Everything went fine. 296 \retval B_BAD_VALUE The message runner is not longer valid. All the 297 messages that had to be sent have already been sent. Or both 298 \a resetInterval and \a resetCount are \c false. 299 */ 300 status_t 301 BMessageRunner::_SetParams(bool resetInterval, bigtime_t interval, 302 bool resetCount, int32 count) 303 { 304 if ((!resetInterval && !resetCount) || fToken < 0) 305 return B_BAD_VALUE; 306 307 // compose the request message 308 BMessage request(B_REG_SET_MESSAGE_RUNNER_PARAMS); 309 status_t result = request.AddInt32("token", fToken); 310 if (result == B_OK && resetInterval) 311 result = request.AddInt64("interval", interval); 312 313 if (result == B_OK && resetCount) 314 result = request.AddInt32("count", count); 315 316 // send the request 317 BMessage reply; 318 if (result == B_OK) 319 result = BRoster::Private().SendTo(&request, &reply, false); 320 321 // evaluate the reply 322 if (result == B_OK) { 323 if (reply.what != B_REG_SUCCESS) { 324 if (reply.FindInt32("error", &result) != B_OK) 325 result = B_ERROR; 326 } 327 } 328 329 return result; 330 } 331