1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: MessageRunner.cpp 23 // Author: Ingo Weinhold (bonefish@users.sf.net) 24 // Description: A BMessageRunner periodically sends a message to a 25 // specified target. 26 //------------------------------------------------------------------------------ 27 #include <Application.h> 28 #include <AppMisc.h> 29 #include <MessageRunner.h> 30 #include <RegistrarDefs.h> 31 #include <Roster.h> 32 #include <RosterPrivate.h> 33 34 // constructor 35 /*! \brief Creates and initializes a new BMessageRunner. 36 37 The target for replies to the delivered message(s) is \c be_app_messenger. 38 39 The success of the initialization can (and should) be asked for via 40 InitCheck(). 41 42 \note As soon as the last message has been sent, the message runner 43 becomes unusable. InitCheck() will still return \c B_OK, but 44 SetInterval(), SetCount() and GetInfo() will fail. 45 46 \param target Target of the message(s). 47 \param message The message to be sent to the target. 48 \param interval Period of time before the first message is sent and 49 between messages (if more than one shall be sent) in microseconds. 50 \param count Specifies how many times the message shall be sent. 51 A value less than \c 0 for an unlimited number of repetitions. 52 */ 53 BMessageRunner::BMessageRunner(BMessenger target, const BMessage *message, 54 bigtime_t interval, int32 count) 55 : fToken(-1) 56 { 57 InitData(target, message, interval, count, be_app_messenger); 58 } 59 60 // constructor 61 /*! \brief Creates and initializes a new BMessageRunner. 62 63 This constructor version additionally allows to specify the target for 64 replies to the delivered message(s). 65 66 The success of the initialization can (and should) be asked for via 67 InitCheck(). 68 69 \note As soon as the last message has been sent, the message runner 70 becomes unusable. InitCheck() will still return \c B_OK, but 71 SetInterval(), SetCount() and GetInfo() will fail. 72 73 \param target Target of the message(s). 74 \param message The message to be sent to the target. 75 \param interval Period of time before the first message is sent and 76 between messages (if more than one shall be sent) in microseconds. 77 \param count Specifies how many times the message shall be sent. 78 A value less than \c 0 for an unlimited number of repetitions. 79 \param replyTo Target replies to the delivered message(s) shall be sent to. 80 */ 81 BMessageRunner::BMessageRunner(BMessenger target, const BMessage *message, 82 bigtime_t interval, int32 count, 83 BMessenger replyTo) 84 : fToken(-1) 85 { 86 InitData(target, message, interval, count, replyTo); 87 } 88 89 // destructor 90 /*! \brief Frees all resources associated with the object. 91 */ 92 BMessageRunner::~BMessageRunner() 93 { 94 status_t error = B_OK; 95 // compose the request message 96 BMessage request(B_REG_UNREGISTER_MESSAGE_RUNNER); 97 if (error == B_OK) 98 error = request.AddInt32("token", fToken); 99 // send the request 100 BMessage reply; 101 if (error == B_OK) 102 error = BRoster::Private().SendTo(&request, &reply, false); 103 // ignore the reply, we can't do anything anyway 104 } 105 106 // InitCheck 107 /*! \brief Returns the status of the initialization. 108 109 \note As soon as the last message has been sent, the message runner 110 becomes unusable. InitCheck() will still return \c B_OK, but 111 SetInterval(), SetCount() and GetInfo() will fail. 112 113 \return \c B_OK, if the object is properly initialized, an error code 114 otherwise. 115 */ 116 status_t 117 BMessageRunner::InitCheck() const 118 { 119 return (fToken >= 0 ? B_OK : fToken); 120 } 121 122 // SetInterval 123 /*! \brief Sets the interval of time between messages. 124 \param interval The new interval in microseconds. 125 \return 126 - \c B_OK: Everything went fine. 127 - \c B_NO_INIT: The message runner is not properly initialized. 128 - \c B_BAD_VALUE: \a interval is \c 0 or negative, or the message runner 129 has already sent all messages to be sent and has become unusable. 130 */ 131 status_t 132 BMessageRunner::SetInterval(bigtime_t interval) 133 { 134 return SetParams(true, interval, false, 0); 135 } 136 137 // SetCount 138 /*! \brief Sets the number of times message shall be sent. 139 \param count Specifies how many times the message shall be sent. 140 A value less than \c 0 for an unlimited number of repetitions. 141 - \c B_BAD_VALUE: The message runner has already sent all messages to be 142 sent and has become unusable. 143 \return 144 - \c B_OK: Everything went fine. 145 - \c B_NO_INIT: The message runner is not properly initialized. 146 */ 147 status_t 148 BMessageRunner::SetCount(int32 count) 149 { 150 return SetParams(false, 0, true, count); 151 } 152 153 // GetInfo 154 /*! \brief Returns the time interval between two messages and the number of 155 times the message has still to be sent. 156 157 Both parameters (\a interval and \a count) may be \c NULL. 158 159 \param interval Pointer to a pre-allocated bigtime_t variable to be set 160 to the time interval. May be \c NULL. 161 \param count Pointer to a pre-allocated int32 variable to be set 162 to the number of times the message has still to be sent. 163 May be \c NULL. 164 \return 165 - \c B_OK: Everything went fine. 166 - \c B_BAD_VALUE: The message runner is not longer valid. All the 167 messages that had to be sent have already been sent. 168 */ 169 status_t 170 BMessageRunner::GetInfo(bigtime_t *interval, int32 *count) const 171 { 172 status_t error = (fToken >= 0 ? B_OK : B_BAD_VALUE); 173 // compose the request message 174 BMessage request(B_REG_GET_MESSAGE_RUNNER_INFO); 175 if (error == B_OK) 176 error = request.AddInt32("token", fToken); 177 // send the request 178 BMessage reply; 179 if (error == B_OK) 180 error = BRoster::Private().SendTo(&request, &reply, false); 181 // evaluate the reply 182 if (error == B_OK) { 183 if (reply.what == B_REG_SUCCESS) { 184 // count 185 int32 _count; 186 if (reply.FindInt32("count", &_count) == B_OK) { 187 if (count) 188 *count = _count; 189 } else 190 error = B_ERROR; 191 // interval 192 bigtime_t _interval; 193 if (reply.FindInt64("interval", &_interval) == B_OK) { 194 if (interval) 195 *interval = _interval; 196 } else 197 error = B_ERROR; 198 } else 199 reply.FindInt32("error", &error); 200 } 201 return error; 202 } 203 204 // FBC 205 void BMessageRunner::_ReservedMessageRunner1() {} 206 void BMessageRunner::_ReservedMessageRunner2() {} 207 void BMessageRunner::_ReservedMessageRunner3() {} 208 void BMessageRunner::_ReservedMessageRunner4() {} 209 void BMessageRunner::_ReservedMessageRunner5() {} 210 void BMessageRunner::_ReservedMessageRunner6() {} 211 212 // copy constructor 213 /*! \brief Privatized copy constructor to prevent usage. 214 */ 215 BMessageRunner::BMessageRunner(const BMessageRunner &) 216 : fToken(-1) 217 { 218 } 219 220 // = 221 /*! \brief Privatized assignment operator to prevent usage. 222 */ 223 BMessageRunner & 224 BMessageRunner::operator=(const BMessageRunner &) 225 { 226 return *this; 227 } 228 229 // InitData 230 /*! \brief Initializes the BMessageRunner. 231 232 The success of the initialization can (and should) be asked for via 233 InitCheck(). 234 235 \note As soon as the last message has been sent, the message runner 236 becomes unusable. InitCheck() will still return \c B_OK, but 237 SetInterval(), SetCount() and GetInfo() will fail. 238 239 \param target Target of the message(s). 240 \param message The message to be sent to the target. 241 \param interval Period of time before the first message is sent and 242 between messages (if more than one shall be sent) in microseconds. 243 \param count Specifies how many times the message shall be sent. 244 A value less than \c 0 for an unlimited number of repetitions. 245 \param replyTo Target replies to the delivered message(s) shall be sent to. 246 */ 247 void 248 BMessageRunner::InitData(BMessenger target, const BMessage *message, 249 bigtime_t interval, int32 count, BMessenger replyTo) 250 { 251 status_t error = (message ? B_OK : B_BAD_VALUE); 252 if (error == B_OK && count == 0) 253 error = B_ERROR; 254 // compose the request message 255 BMessage request(B_REG_REGISTER_MESSAGE_RUNNER); 256 if (error == B_OK) 257 error = request.AddInt32("team", BPrivate::current_team()); 258 if (error == B_OK) 259 error = request.AddMessenger("target", target); 260 if (error == B_OK) 261 error = request.AddMessage("message", message); 262 if (error == B_OK) 263 error = request.AddInt64("interval", interval); 264 if (error == B_OK) 265 error = request.AddInt32("count", count); 266 if (error == B_OK) 267 error = request.AddMessenger("reply_target", replyTo); 268 // send the request 269 BMessage reply; 270 if (error == B_OK) 271 error = BRoster::Private().SendTo(&request, &reply, false); 272 // evaluate the reply 273 if (error == B_OK) { 274 if (reply.what == B_REG_SUCCESS) { 275 if (reply.FindInt32("token", &fToken) != B_OK) 276 error = B_ERROR; 277 } else 278 reply.FindInt32("error", &error); 279 } 280 if (error != B_OK) 281 fToken = error; 282 } 283 284 // SetParams 285 /*! \brief Sets the message runner's interval and count parameters. 286 287 The parameters \a resetInterval and \a resetCount specify whether 288 the interval or the count parameter respectively shall be reset. 289 290 At least one parameter must be set, otherwise the methods returns 291 \c B_BAD_VALUE. 292 293 \param resetInterval \c true, if the interval shall be reset, \c false 294 otherwise -- then \a interval is ignored. 295 \param interval The new interval in microseconds. 296 \param resetCount \c true, if the count shall be reset, \c false 297 otherwise -- then \a count is ignored. 298 \param count Specifies how many times the message shall be sent. 299 A value less than \c 0 for an unlimited number of repetitions. 300 \return 301 - \c B_OK: Everything went fine. 302 - \c B_BAD_VALUE: The message runner is not longer valid. All the 303 messages that had to be sent have already been sent. Or both 304 \a resetInterval and \a resetCount are \c false. 305 */ 306 status_t 307 BMessageRunner::SetParams(bool resetInterval, bigtime_t interval, 308 bool resetCount, int32 count) 309 { 310 status_t error = ((resetInterval || resetCount) && fToken >= 0 311 ? B_OK : B_BAD_VALUE); 312 // compose the request message 313 BMessage request(B_REG_SET_MESSAGE_RUNNER_PARAMS); 314 if (error == B_OK) 315 error = request.AddInt32("token", fToken); 316 if (error == B_OK && resetInterval) 317 error = request.AddInt64("interval", interval); 318 if (error == B_OK && resetCount) 319 error = request.AddInt32("count", count); 320 // send the request 321 BMessage reply; 322 if (error == B_OK) 323 error = BRoster::Private().SendTo(&request, &reply, false); 324 // evaluate the reply 325 if (error == B_OK) { 326 if (reply.what != B_REG_SUCCESS) 327 reply.FindInt32("error", &error); 328 } 329 return error; 330 } 331 332