lleventfilter.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file   lleventfilter.h
  3.  * @author Nat Goodspeed
  4.  * @date   2009-03-05
  5.  * @brief  Define LLEventFilter: LLEventStream subclass with conditions
  6.  * 
  7.  * $LicenseInfo:firstyear=2009&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2009-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #if ! defined(LL_LLEVENTFILTER_H)
  35. #define LL_LLEVENTFILTER_H
  36. #include "llevents.h"
  37. #include "stdtypes.h"
  38. #include "lltimer.h"
  39. #include <boost/function.hpp>
  40. /**
  41.  * Generic base class
  42.  */
  43. class LL_COMMON_API LLEventFilter: public LLEventStream
  44. {
  45. public:
  46.     /// construct a standalone LLEventFilter
  47.     LLEventFilter(const std::string& name="filter", bool tweak=true):
  48.         LLEventStream(name, tweak)
  49.     {}
  50.     /// construct LLEventFilter and connect it to the specified LLEventPump
  51.     LLEventFilter(LLEventPump& source, const std::string& name="filter", bool tweak=true);
  52.     /// Post an event to all listeners
  53.     virtual bool post(const LLSD& event) = 0;
  54. };
  55. /**
  56.  * Pass through only events matching a specified pattern
  57.  */
  58. class LLEventMatching: public LLEventFilter
  59. {
  60. public:
  61.     /// Pass an LLSD map with keys and values the incoming event must match
  62.     LLEventMatching(const LLSD& pattern);
  63.     /// instantiate and connect
  64.     LLEventMatching(LLEventPump& source, const LLSD& pattern);
  65.     /// Only pass through events matching the pattern
  66.     virtual bool post(const LLSD& event);
  67. private:
  68.     LLSD mPattern;
  69. };
  70. /**
  71.  * Wait for an event to be posted. If no such event arrives within a specified
  72.  * time, take a specified action. See LLEventTimeout for production
  73.  * implementation.
  74.  *
  75.  * @NOTE This is an abstract base class so that, for testing, we can use an
  76.  * alternate "timer" that doesn't actually consume real time.
  77.  */
  78. class LL_COMMON_API LLEventTimeoutBase: public LLEventFilter
  79. {
  80. public:
  81.     /// construct standalone
  82.     LLEventTimeoutBase();
  83.     /// construct and connect
  84.     LLEventTimeoutBase(LLEventPump& source);
  85.     /// Callable, can be constructed with boost::bind()
  86.     typedef boost::function<void()> Action;
  87.     /**
  88.      * Start countdown timer for the specified number of @a seconds. Forward
  89.      * all events. If any event arrives before timer expires, cancel timer. If
  90.      * no event arrives before timer expires, take specified @a action.
  91.      *
  92.      * This is a one-shot timer. Once it has either expired or been canceled,
  93.      * it is inert until another call to actionAfter().
  94.      *
  95.      * Calling actionAfter() while an existing timer is running cheaply
  96.      * replaces that original timer. Thus, a valid use case is to detect
  97.      * idleness of some event source by calling actionAfter() on each new
  98.      * event. A rapid sequence of events will keep the timer from expiring;
  99.      * the first gap in events longer than the specified timer will fire the
  100.      * specified Action.
  101.      *
  102.      * Any post() call cancels the timer. To be satisfied with only a
  103.      * particular event, chain on an LLEventMatching that only passes such
  104.      * events:
  105.      *
  106.      * @code
  107.      * event                                                 ultimate
  108.      * source ---> LLEventMatching ---> LLEventTimeout  ---> listener
  109.      * @endcode
  110.      *
  111.      * @NOTE
  112.      * The implementation relies on frequent events on the LLEventPump named
  113.      * "mainloop".
  114.      */
  115.     void actionAfter(F32 seconds, const Action& action);
  116.     /**
  117.      * Like actionAfter(), but where the desired Action is LL_ERRS
  118.      * termination. Pass the timeout time and the desired LL_ERRS @a message.
  119.      *
  120.      * This method is useful when, for instance, some async API guarantees an
  121.      * event, whether success or failure, within a stated time window.
  122.      * Instantiate an LLEventTimeout listening to that API and call
  123.      * errorAfter() on each async request with a timeout comfortably longer
  124.      * than the API's time guarantee (much longer than the anticipated
  125.      * "mainloop" granularity).
  126.      *
  127.      * Then if the async API breaks its promise, the program terminates with
  128.      * the specified LL_ERRS @a message. The client of the async API can
  129.      * therefore assume the guarantee is upheld.
  130.      *
  131.      * @NOTE
  132.      * errorAfter() is implemented in terms of actionAfter(), so all remarks
  133.      * about calling actionAfter() also apply to errorAfter().
  134.      */
  135.     void errorAfter(F32 seconds, const std::string& message);
  136.     /**
  137.      * Like actionAfter(), but where the desired Action is a particular event
  138.      * for all listeners. Pass the timeout time and the desired @a event data.
  139.      * 
  140.      * Suppose the timeout should only be satisfied by a particular event, but
  141.      * the ultimate listener must see all other incoming events as well, plus
  142.      * the timeout @a event if any:
  143.      * 
  144.      * @code
  145.      * some        LLEventMatching                           LLEventMatching
  146.      * event  ---> for particular  ---> LLEventTimeout  ---> for timeout
  147.      * source      event                                     event 
  148.      *                                                              ultimate
  149.      *        `-----------------------------------------------------> listener
  150.      * @endcode
  151.      * 
  152.      * Since a given listener can listen on more than one LLEventPump, we can
  153.      * set things up so it sees the set union of events from LLEventTimeout
  154.      * and the original event source. However, as LLEventTimeout passes
  155.      * through all incoming events, the "particular event" that satisfies the
  156.      * left LLEventMatching would reach the ultimate listener twice. So we add
  157.      * an LLEventMatching that only passes timeout events.
  158.      *
  159.      * @NOTE
  160.      * eventAfter() is implemented in terms of actionAfter(), so all remarks
  161.      * about calling actionAfter() also apply to eventAfter().
  162.      */
  163.     void eventAfter(F32 seconds, const LLSD& event);
  164.     /// Pass event through, canceling the countdown timer
  165.     virtual bool post(const LLSD& event);
  166.     /// Cancel timer without event
  167.     void cancel();
  168. protected:
  169.     virtual void setCountdown(F32 seconds) = 0;
  170.     virtual bool countdownElapsed() const = 0;
  171. private:
  172.     bool tick(const LLSD&);
  173.     LLBoundListener mMainloop;
  174.     Action mAction;
  175. };
  176. /// Production implementation of LLEventTimoutBase
  177. class LL_COMMON_API LLEventTimeout: public LLEventTimeoutBase
  178. {
  179. public:
  180.     LLEventTimeout();
  181.     LLEventTimeout(LLEventPump& source);
  182. protected:
  183.     virtual void setCountdown(F32 seconds);
  184.     virtual bool countdownElapsed() const;
  185. private:
  186.     LLTimer mTimer;
  187. };
  188. #endif /* ! defined(LL_LLEVENTFILTER_H) */