* Added two new constructor forms that allow you to create a BMessageRunner

that is detached from its local object; ie. it will continue to send its
  messages when you delete the object.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16730 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-03-12 12:27:16 +00:00
parent dd48600aac
commit 43d7fe9753
2 changed files with 143 additions and 72 deletions
+43 -51
View File
@@ -1,67 +1,59 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, OpenBeOS * Copyright 2001-2006, Haiku.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Ingo Weinhold ([email protected])
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: MessageRunner.h
// Author: Ingo Weinhold ([email protected])
// Description: A BMessageRunner periodically sends a message to a
// specified target.
//------------------------------------------------------------------------------
#ifndef _MESSAGE_RUNNER_H #ifndef _MESSAGE_RUNNER_H
#define _MESSAGE_RUNNER_H #define _MESSAGE_RUNNER_H
#include <Messenger.h> #include <Messenger.h>
class BMessageRunner { class BMessageRunner {
public: public:
BMessageRunner(BMessenger target, const BMessage *message, BMessageRunner(BMessenger target, const BMessage *message,
bigtime_t interval, int32 count = -1); bigtime_t interval, int32 count = -1);
BMessageRunner(BMessenger target, const BMessage *message, BMessageRunner(BMessenger target, const BMessage *message,
bigtime_t interval, int32 count, BMessenger replyTo); bigtime_t interval, int32 count, BMessenger replyTo);
virtual ~BMessageRunner(); BMessageRunner(BMessenger target, const BMessage *message,
bigtime_t interval, int32 count, bool detach);
BMessageRunner(BMessenger target, const BMessage *message,
bigtime_t interval, int32 count, bool detach,
BMessenger replyTo);
virtual ~BMessageRunner();
status_t InitCheck() const; status_t InitCheck() const;
status_t SetInterval(bigtime_t interval); status_t SetInterval(bigtime_t interval);
status_t SetCount(int32 count); status_t SetCount(int32 count);
status_t GetInfo(bigtime_t *interval, int32 *count) const; status_t GetInfo(bigtime_t *interval, int32 *count) const;
private:
BMessageRunner(const BMessageRunner &);
BMessageRunner &operator=(const BMessageRunner &);
private: void _InitData(BMessenger target, const BMessage *message, bigtime_t interval,
BMessageRunner(const BMessageRunner &); int32 count, bool detach, BMessenger replyTo);
BMessageRunner &operator=(const BMessageRunner &); status_t _SetParams(bool resetInterval, bigtime_t interval, bool resetCount,
int32 count);
void InitData(BMessenger target, const BMessage *message, virtual void _ReservedMessageRunner1();
bigtime_t interval, int32 count, BMessenger replyTo); virtual void _ReservedMessageRunner2();
status_t SetParams(bool resetInterval, bigtime_t interval, bool resetCount, virtual void _ReservedMessageRunner3();
int32 count); virtual void _ReservedMessageRunner4();
virtual void _ReservedMessageRunner5();
virtual void _ReservedMessageRunner6();
virtual void _ReservedMessageRunner1(); int32 fToken;
virtual void _ReservedMessageRunner2(); bool fDetached;
virtual void _ReservedMessageRunner3();
virtual void _ReservedMessageRunner4();
virtual void _ReservedMessageRunner5();
virtual void _ReservedMessageRunner6();
int32 fToken; bool _unused0;
uint32 _reserved[6]; bool _unused1;
bool _unused2;
uint32 _reserved[5];
}; };
#endif // _MESSAGE_RUNNER_H #endif // _MESSAGE_RUNNER_H
+100 -21
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2005, Haiku. * Copyright 2001-2006, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -40,7 +40,7 @@ BMessageRunner::BMessageRunner(BMessenger target, const BMessage *message,
bigtime_t interval, int32 count) bigtime_t interval, int32 count)
: fToken(-1) : fToken(-1)
{ {
InitData(target, message, interval, count, be_app_messenger); _InitData(target, message, interval, count, false, be_app_messenger);
} }
// constructor // constructor
@@ -69,23 +69,94 @@ BMessageRunner::BMessageRunner(BMessenger target, const BMessage *message,
BMessenger replyTo) BMessenger replyTo)
: fToken(-1) : fToken(-1)
{ {
InitData(target, message, interval, count, replyTo); _InitData(target, message, interval, count, false, replyTo);
} }
/*! \brief Creates and initializes a new BMessageRunner.
The target for replies to the delivered message(s) is \c be_app_messenger.
The success of the initialization can (and should) be asked for via
InitCheck().
\note As soon as the last message has been sent, the message runner
becomes unusable. InitCheck() will still return \c B_OK, but
SetInterval(), SetCount() and GetInfo() will fail.
\note You can't change a detached messenger after the object has been
created.
\param target Target of the message(s).
\param message The message to be sent to the target.
\param interval Period of time before the first message is sent and
between messages (if more than one shall be sent) in microseconds.
\param count Specifies how many times the message shall be sent.
In this form of the constructor, only counts greater than 0 are allowed
if \a detach is \c true.
\param detach Detaches the runner from this object; when you delete this
object, the runner will continue to work.
*/
BMessageRunner::BMessageRunner(BMessenger target, const BMessage *message,
bigtime_t interval, int32 count, bool detach)
: fToken(-1)
{
_InitData(target, message, interval, count, detach, be_app_messenger);
}
/*!
\brief Creates and initializes a new BMessageRunner.
This constructor version additionally allows to specify the target for
replies to the delivered message(s).
The success of the initialization can (and should) be asked for via
InitCheck().
\note As soon as the last message has been sent, the message runner
becomes unusable. InitCheck() will still return \c B_OK, but
SetInterval(), SetCount() and GetInfo() will fail.
\note You can't change a detached messenger after the object has been
created.
\param target Target of the message(s).
\param message The message to be sent to the target.
\param interval Period of time before the first message is sent and
between messages (if more than one shall be sent) in microseconds.
\param count Specifies how many times the message shall be sent.
In this form of the constructor, only counts greater than 0 are allowed
if \a detach is \c true.
\param detach Detaches the runner from this object; when you delete this
object, the runner will continue to work.
\param replyTo Target replies to the delivered message(s) shall be sent to.
*/
BMessageRunner::BMessageRunner(BMessenger target, const BMessage *message,
bigtime_t interval, int32 count, bool detach,
BMessenger replyTo)
: fToken(-1)
{
_InitData(target, message, interval, count, detach, replyTo);
}
// destructor // destructor
/*! \brief Frees all resources associated with the object. /*! \brief Frees all resources associated with the object.
*/ */
BMessageRunner::~BMessageRunner() BMessageRunner::~BMessageRunner()
{ {
status_t error = B_OK; if (fDetached || fToken < B_OK)
return;
// compose the request message // compose the request message
BMessage request(B_REG_UNREGISTER_MESSAGE_RUNNER); BMessage request(B_REG_UNREGISTER_MESSAGE_RUNNER);
if (error == B_OK) status_t error = request.AddInt32("token", fToken);
error = request.AddInt32("token", fToken);
// send the request // send the request
BMessage reply; BMessage reply;
if (error == B_OK) if (error == B_OK)
error = BRoster::Private().SendTo(&request, &reply, false); error = BRoster::Private().SendTo(&request, &reply, false);
// ignore the reply, we can't do anything anyway // ignore the reply, we can't do anything anyway
} }
@@ -117,7 +188,7 @@ BMessageRunner::InitCheck() const
status_t status_t
BMessageRunner::SetInterval(bigtime_t interval) BMessageRunner::SetInterval(bigtime_t interval)
{ {
return SetParams(true, interval, false, 0); return _SetParams(true, interval, false, 0);
} }
// SetCount // SetCount
@@ -133,7 +204,7 @@ BMessageRunner::SetInterval(bigtime_t interval)
status_t status_t
BMessageRunner::SetCount(int32 count) BMessageRunner::SetCount(int32 count)
{ {
return SetParams(false, 0, true, count); return _SetParams(false, 0, true, count);
} }
// GetInfo // GetInfo
@@ -212,7 +283,7 @@ BMessageRunner::operator=(const BMessageRunner &)
return *this; return *this;
} }
// InitData
/*! \brief Initializes the BMessageRunner. /*! \brief Initializes the BMessageRunner.
The success of the initialization can (and should) be asked for via The success of the initialization can (and should) be asked for via
@@ -231,12 +302,13 @@ BMessageRunner::operator=(const BMessageRunner &)
\param replyTo Target replies to the delivered message(s) shall be sent to. \param replyTo Target replies to the delivered message(s) shall be sent to.
*/ */
void void
BMessageRunner::InitData(BMessenger target, const BMessage *message, BMessageRunner::_InitData(BMessenger target, const BMessage *message,
bigtime_t interval, int32 count, BMessenger replyTo) bigtime_t interval, int32 count, bool detach, BMessenger replyTo)
{ {
status_t error = (message ? B_OK : B_BAD_VALUE); status_t error = B_OK;
if (error == B_OK && count == 0) if (message == NULL || count == 0 || (count < 0 && detach))
error = B_ERROR; error = B_BAD_VALUE;
// compose the request message // compose the request message
BMessage request(B_REG_REGISTER_MESSAGE_RUNNER); BMessage request(B_REG_REGISTER_MESSAGE_RUNNER);
if (error == B_OK) if (error == B_OK)
@@ -251,23 +323,28 @@ BMessageRunner::InitData(BMessenger target, const BMessage *message,
error = request.AddInt32("count", count); error = request.AddInt32("count", count);
if (error == B_OK) if (error == B_OK)
error = request.AddMessenger("reply_target", replyTo); error = request.AddMessenger("reply_target", replyTo);
// send the request // send the request
BMessage reply; BMessage reply;
if (error == B_OK) if (error == B_OK)
error = BRoster::Private().SendTo(&request, &reply, false); error = BRoster::Private().SendTo(&request, &reply, false);
// evaluate the reply // evaluate the reply
if (error == B_OK) { if (error == B_OK) {
if (reply.what == B_REG_SUCCESS) { if (reply.what == B_REG_SUCCESS) {
if (reply.FindInt32("token", &fToken) != B_OK) if (reply.FindInt32("token", &fToken) != B_OK)
error = B_ERROR; error = B_ERROR;
else
fDetached = detach;
} else } else
reply.FindInt32("error", &error); reply.FindInt32("error", &error);
} }
if (error != B_OK) if (error != B_OK)
fToken = error; fToken = error;
} }
// SetParams
/*! \brief Sets the message runner's interval and count parameters. /*! \brief Sets the message runner's interval and count parameters.
The parameters \a resetInterval and \a resetCount specify whether The parameters \a resetInterval and \a resetCount specify whether
@@ -290,23 +367,25 @@ BMessageRunner::InitData(BMessenger target, const BMessage *message,
\a resetInterval and \a resetCount are \c false. \a resetInterval and \a resetCount are \c false.
*/ */
status_t status_t
BMessageRunner::SetParams(bool resetInterval, bigtime_t interval, BMessageRunner::_SetParams(bool resetInterval, bigtime_t interval,
bool resetCount, int32 count) bool resetCount, int32 count)
{ {
status_t error = ((resetInterval || resetCount) && fToken >= 0 if ((!resetInterval && !resetCount) || fToken < 0 || fDetached)
? B_OK : B_BAD_VALUE); return B_BAD_VALUE;
// compose the request message // compose the request message
BMessage request(B_REG_SET_MESSAGE_RUNNER_PARAMS); BMessage request(B_REG_SET_MESSAGE_RUNNER_PARAMS);
if (error == B_OK) status_t error = request.AddInt32("token", fToken);
error = request.AddInt32("token", fToken);
if (error == B_OK && resetInterval) if (error == B_OK && resetInterval)
error = request.AddInt64("interval", interval); error = request.AddInt64("interval", interval);
if (error == B_OK && resetCount) if (error == B_OK && resetCount)
error = request.AddInt32("count", count); error = request.AddInt32("count", count);
// send the request // send the request
BMessage reply; BMessage reply;
if (error == B_OK) if (error == B_OK)
error = BRoster::Private().SendTo(&request, &reply, false); error = BRoster::Private().SendTo(&request, &reply, false);
// evaluate the reply // evaluate the reply
if (error == B_OK) { if (error == B_OK) {
if (reply.what != B_REG_SUCCESS) if (reply.what != B_REG_SUCCESS)