Most in particular llevents.h, which comes along with the demand that the old events in llevent.h are put in a namespace LLOldEvents. Made all changes necessary to compile the rest of the code again (without changing the actual code: it's still using the old events). This patch also removes LLStopWhenHandled and LLStandardSignal from indra/llui/llnotifications.h because those are moved to llevents.h. That seems to be the only change to indra/llui/llnotifications.h that isn't floater related, so I left the rest of that file alone.
204 lines
7.1 KiB
C++
204 lines
7.1 KiB
C++
/**
|
|
* @file lleventfilter.h
|
|
* @author Nat Goodspeed
|
|
* @date 2009-03-05
|
|
* @brief Define LLEventFilter: LLEventStream subclass with conditions
|
|
*
|
|
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2010, Linden Research, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#if ! defined(LL_LLEVENTFILTER_H)
|
|
#define LL_LLEVENTFILTER_H
|
|
|
|
#include "llevents.h"
|
|
#include "stdtypes.h"
|
|
#include "lltimer.h"
|
|
#include <boost/function.hpp>
|
|
|
|
/**
|
|
* Generic base class
|
|
*/
|
|
class LL_COMMON_API LLEventFilter: public LLEventStream
|
|
{
|
|
public:
|
|
/// construct a standalone LLEventFilter
|
|
LLEventFilter(const std::string& name="filter", bool tweak=true):
|
|
LLEventStream(name, tweak)
|
|
{}
|
|
/// construct LLEventFilter and connect it to the specified LLEventPump
|
|
LLEventFilter(LLEventPump& source, const std::string& name="filter", bool tweak=true);
|
|
|
|
/// Post an event to all listeners
|
|
virtual bool post(const LLSD& event) = 0;
|
|
};
|
|
|
|
/**
|
|
* Pass through only events matching a specified pattern
|
|
*/
|
|
class LLEventMatching: public LLEventFilter
|
|
{
|
|
public:
|
|
/// Pass an LLSD map with keys and values the incoming event must match
|
|
LLEventMatching(const LLSD& pattern);
|
|
/// instantiate and connect
|
|
LLEventMatching(LLEventPump& source, const LLSD& pattern);
|
|
|
|
/// Only pass through events matching the pattern
|
|
virtual bool post(const LLSD& event);
|
|
|
|
private:
|
|
LLSD mPattern;
|
|
};
|
|
|
|
/**
|
|
* Wait for an event to be posted. If no such event arrives within a specified
|
|
* time, take a specified action. See LLEventTimeout for production
|
|
* implementation.
|
|
*
|
|
* @NOTE This is an abstract base class so that, for testing, we can use an
|
|
* alternate "timer" that doesn't actually consume real time.
|
|
*/
|
|
class LL_COMMON_API LLEventTimeoutBase: public LLEventFilter
|
|
{
|
|
public:
|
|
/// construct standalone
|
|
LLEventTimeoutBase();
|
|
/// construct and connect
|
|
LLEventTimeoutBase(LLEventPump& source);
|
|
|
|
/// Callable, can be constructed with boost::bind()
|
|
typedef boost::function<void()> Action;
|
|
|
|
/**
|
|
* Start countdown timer for the specified number of @a seconds. Forward
|
|
* all events. If any event arrives before timer expires, cancel timer. If
|
|
* no event arrives before timer expires, take specified @a action.
|
|
*
|
|
* This is a one-shot timer. Once it has either expired or been canceled,
|
|
* it is inert until another call to actionAfter().
|
|
*
|
|
* Calling actionAfter() while an existing timer is running cheaply
|
|
* replaces that original timer. Thus, a valid use case is to detect
|
|
* idleness of some event source by calling actionAfter() on each new
|
|
* event. A rapid sequence of events will keep the timer from expiring;
|
|
* the first gap in events longer than the specified timer will fire the
|
|
* specified Action.
|
|
*
|
|
* Any post() call cancels the timer. To be satisfied with only a
|
|
* particular event, chain on an LLEventMatching that only passes such
|
|
* events:
|
|
*
|
|
* @code
|
|
* event ultimate
|
|
* source ---> LLEventMatching ---> LLEventTimeout ---> listener
|
|
* @endcode
|
|
*
|
|
* @NOTE
|
|
* The implementation relies on frequent events on the LLEventPump named
|
|
* "mainloop".
|
|
*/
|
|
void actionAfter(F32 seconds, const Action& action);
|
|
|
|
/**
|
|
* Like actionAfter(), but where the desired Action is LL_ERRS
|
|
* termination. Pass the timeout time and the desired LL_ERRS @a message.
|
|
*
|
|
* This method is useful when, for instance, some async API guarantees an
|
|
* event, whether success or failure, within a stated time window.
|
|
* Instantiate an LLEventTimeout listening to that API and call
|
|
* errorAfter() on each async request with a timeout comfortably longer
|
|
* than the API's time guarantee (much longer than the anticipated
|
|
* "mainloop" granularity).
|
|
*
|
|
* Then if the async API breaks its promise, the program terminates with
|
|
* the specified LL_ERRS @a message. The client of the async API can
|
|
* therefore assume the guarantee is upheld.
|
|
*
|
|
* @NOTE
|
|
* errorAfter() is implemented in terms of actionAfter(), so all remarks
|
|
* about calling actionAfter() also apply to errorAfter().
|
|
*/
|
|
void errorAfter(F32 seconds, const std::string& message);
|
|
|
|
/**
|
|
* Like actionAfter(), but where the desired Action is a particular event
|
|
* for all listeners. Pass the timeout time and the desired @a event data.
|
|
*
|
|
* Suppose the timeout should only be satisfied by a particular event, but
|
|
* the ultimate listener must see all other incoming events as well, plus
|
|
* the timeout @a event if any:
|
|
*
|
|
* @code
|
|
* some LLEventMatching LLEventMatching
|
|
* event ---> for particular ---> LLEventTimeout ---> for timeout
|
|
* source event event \
|
|
* \ \ ultimate
|
|
* `-----------------------------------------------------> listener
|
|
* @endcode
|
|
*
|
|
* Since a given listener can listen on more than one LLEventPump, we can
|
|
* set things up so it sees the set union of events from LLEventTimeout
|
|
* and the original event source. However, as LLEventTimeout passes
|
|
* through all incoming events, the "particular event" that satisfies the
|
|
* left LLEventMatching would reach the ultimate listener twice. So we add
|
|
* an LLEventMatching that only passes timeout events.
|
|
*
|
|
* @NOTE
|
|
* eventAfter() is implemented in terms of actionAfter(), so all remarks
|
|
* about calling actionAfter() also apply to eventAfter().
|
|
*/
|
|
void eventAfter(F32 seconds, const LLSD& event);
|
|
|
|
/// Pass event through, canceling the countdown timer
|
|
virtual bool post(const LLSD& event);
|
|
|
|
/// Cancel timer without event
|
|
void cancel();
|
|
|
|
protected:
|
|
virtual void setCountdown(F32 seconds) = 0;
|
|
virtual bool countdownElapsed() const = 0;
|
|
|
|
private:
|
|
bool tick(const LLSD&);
|
|
|
|
LLBoundListener mMainloop;
|
|
Action mAction;
|
|
};
|
|
|
|
/// Production implementation of LLEventTimoutBase
|
|
class LL_COMMON_API LLEventTimeout: public LLEventTimeoutBase
|
|
{
|
|
public:
|
|
LLEventTimeout();
|
|
LLEventTimeout(LLEventPump& source);
|
|
|
|
protected:
|
|
virtual void setCountdown(F32 seconds);
|
|
virtual bool countdownElapsed() const;
|
|
|
|
private:
|
|
LLTimer mTimer;
|
|
};
|
|
|
|
#endif /* ! defined(LL_LLEVENTFILTER_H) */
|