/indra/llcommon/tests/listener.h

https://bitbucket.org/lindenlab/viewer-beta/ · C Header · 156 lines · 77 code · 8 blank · 71 comment · 4 complexity · 6fec4ef56bde5cba4dc6f042b5cb3946 MD5 · raw file

  1. /**
  2. * @file listener.h
  3. * @author Nat Goodspeed
  4. * @date 2009-03-06
  5. * @brief Useful for tests of the LLEventPump family of classes
  6. *
  7. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #if ! defined(LL_LISTENER_H)
  29. #define LL_LISTENER_H
  30. #include "llsd.h"
  31. #include <iostream>
  32. /*****************************************************************************
  33. * test listener class
  34. *****************************************************************************/
  35. class Listener;
  36. std::ostream& operator<<(std::ostream&, const Listener&);
  37. /// Bear in mind that this is strictly for testing
  38. class Listener
  39. {
  40. public:
  41. /// Every Listener is instantiated with a name
  42. Listener(const std::string& name):
  43. mName(name)
  44. {
  45. // std::cout << *this << ": ctor\n";
  46. }
  47. /*==========================================================================*|
  48. // These methods are only useful when trying to track Listener instance
  49. // lifespan
  50. Listener(const Listener& that):
  51. mName(that.mName),
  52. mLastEvent(that.mLastEvent)
  53. {
  54. std::cout << *this << ": copy\n";
  55. }
  56. virtual ~Listener()
  57. {
  58. std::cout << *this << ": dtor\n";
  59. }
  60. |*==========================================================================*/
  61. /// You can request the name
  62. std::string getName() const { return mName; }
  63. /// This is a typical listener method that returns 'false' when done,
  64. /// allowing subsequent listeners on the LLEventPump to process the
  65. /// incoming event.
  66. bool call(const LLSD& event)
  67. {
  68. // std::cout << *this << "::call(" << event << ")\n";
  69. mLastEvent = event;
  70. return false;
  71. }
  72. /// This is an alternate listener that returns 'true' when done, which
  73. /// stops processing of the incoming event.
  74. bool callstop(const LLSD& event)
  75. {
  76. // std::cout << *this << "::callstop(" << event << ")\n";
  77. mLastEvent = event;
  78. return true;
  79. }
  80. /// ListenMethod can represent either call() or callstop().
  81. typedef bool (Listener::*ListenMethod)(const LLSD&);
  82. /**
  83. * This helper method is only because our test code makes so many
  84. * repetitive listen() calls to ListenerMethods. In real code, you should
  85. * call LLEventPump::listen() directly so it can examine the specific
  86. * object you pass to boost::bind().
  87. */
  88. LLBoundListener listenTo(LLEventPump& pump,
  89. ListenMethod method=&Listener::call,
  90. const LLEventPump::NameList& after=LLEventPump::empty,
  91. const LLEventPump::NameList& before=LLEventPump::empty)
  92. {
  93. return pump.listen(getName(), boost::bind(method, this, _1), after, before);
  94. }
  95. /// Both call() and callstop() set mLastEvent. Retrieve it.
  96. LLSD getLastEvent() const
  97. {
  98. // std::cout << *this << "::getLastEvent() -> " << mLastEvent << "\n";
  99. return mLastEvent;
  100. }
  101. /// Reset mLastEvent to a known state.
  102. void reset(const LLSD& to = LLSD())
  103. {
  104. // std::cout << *this << "::reset(" << to << ")\n";
  105. mLastEvent = to;
  106. }
  107. private:
  108. std::string mName;
  109. LLSD mLastEvent;
  110. };
  111. std::ostream& operator<<(std::ostream& out, const Listener& listener)
  112. {
  113. out << "Listener(" << listener.getName() /* << "@" << &listener */ << ')';
  114. return out;
  115. }
  116. /**
  117. * This class tests the relative order in which various listeners on a given
  118. * LLEventPump are called. Each listen() call binds a particular string, which
  119. * we collect for later examination. The actual event is ignored.
  120. */
  121. struct Collect
  122. {
  123. bool add(const std::string& bound, const LLSD& event)
  124. {
  125. result.push_back(bound);
  126. return false;
  127. }
  128. void clear() { result.clear(); }
  129. typedef std::vector<std::string> StringList;
  130. StringList result;
  131. };
  132. std::ostream& operator<<(std::ostream& out, const Collect::StringList& strings)
  133. {
  134. out << '(';
  135. Collect::StringList::const_iterator begin(strings.begin()), end(strings.end());
  136. if (begin != end)
  137. {
  138. out << '"' << *begin << '"';
  139. while (++begin != end)
  140. {
  141. out << ", \"" << *begin << '"';
  142. }
  143. }
  144. out << ')';
  145. return out;
  146. }
  147. #endif /* ! defined(LL_LISTENER_H) */