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