DRTVWR-476: Remove llwrap(), LLListenerWrapper[Base] and support.
The only usage of any of this was in test code.meow-7.2.2
parent
bdb87556ff
commit
401023ec7a
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# -*- cmake -*-
|
||||
|
||||
project(llcommon)
|
||||
|
|
@ -185,7 +184,6 @@ set(llcommon_HEADER_FILES
|
|||
llkeythrottle.h
|
||||
llleap.h
|
||||
llleaplistener.h
|
||||
lllistenerwrapper.h
|
||||
llliveappconfig.h
|
||||
lllivefile.h
|
||||
llmd5.h
|
||||
|
|
|
|||
|
|
@ -814,62 +814,6 @@ private:
|
|||
LL_COMMON_API bool sendReply(const LLSD& reply, const LLSD& request,
|
||||
const std::string& replyKey="reply");
|
||||
|
||||
/**
|
||||
* Base class for LLListenerWrapper. See visit_and_connect() and llwrap(). We
|
||||
* provide virtual @c accept_xxx() methods, customization points allowing a
|
||||
* subclass access to certain data visible at LLEventPump::listen() time.
|
||||
* Example subclass usage:
|
||||
*
|
||||
* @code
|
||||
* myEventPump.listen("somename",
|
||||
* llwrap<MyListenerWrapper>(boost::bind(&MyClass::method, instance, _1)));
|
||||
* @endcode
|
||||
*
|
||||
* Because of the anticipated usage (note the anonymous temporary
|
||||
* MyListenerWrapper instance in the example above), the @c accept_xxx()
|
||||
* methods must be @c const.
|
||||
*/
|
||||
class LL_COMMON_API LLListenerWrapperBase
|
||||
{
|
||||
public:
|
||||
/// New instance. The accept_xxx() machinery makes it important to use
|
||||
/// shared_ptrs for our data. Many copies of this object are made before
|
||||
/// the instance that actually ends up in the signal, yet accept_xxx()
|
||||
/// will later be called on the @em original instance. All copies of the
|
||||
/// same original instance must share the same data.
|
||||
LLListenerWrapperBase():
|
||||
mName(new std::string),
|
||||
mConnection(new LLBoundListener)
|
||||
{
|
||||
}
|
||||
|
||||
/// Copy constructor. Copy shared_ptrs to original instance data.
|
||||
LLListenerWrapperBase(const LLListenerWrapperBase& that):
|
||||
mName(that.mName),
|
||||
mConnection(that.mConnection)
|
||||
{
|
||||
}
|
||||
virtual ~LLListenerWrapperBase() {}
|
||||
|
||||
/// Ask LLEventPump::listen() for the listener name
|
||||
virtual void accept_name(const std::string& name) const
|
||||
{
|
||||
*mName = name;
|
||||
}
|
||||
|
||||
/// Ask LLEventPump::listen() for the new connection
|
||||
virtual void accept_connection(const LLBoundListener& connection) const
|
||||
{
|
||||
*mConnection = connection;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Listener name.
|
||||
boost::shared_ptr<std::string> mName;
|
||||
/// Connection.
|
||||
boost::shared_ptr<LLBoundListener> mConnection;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Underpinnings
|
||||
*****************************************************************************/
|
||||
|
|
@ -1121,19 +1065,7 @@ namespace LLEventDetail
|
|||
// Boost.Signals, in case we were passed a boost::ref().
|
||||
visit_each(visitor, LLEventDetail::unwrap(raw_listener));
|
||||
// Make the connection using passed function.
|
||||
LLBoundListener connection(connect_func(listener));
|
||||
// If the LISTENER is an LLListenerWrapperBase subclass, pass it the
|
||||
// desired information. It's important that we pass the raw_listener
|
||||
// so the compiler can make decisions based on its original type.
|
||||
const LLListenerWrapperBase* lwb =
|
||||
ll_template_cast<const LLListenerWrapperBase*>(&raw_listener);
|
||||
if (lwb)
|
||||
{
|
||||
lwb->accept_name(name);
|
||||
lwb->accept_connection(connection);
|
||||
}
|
||||
// In any case, show new connection to caller.
|
||||
return connection;
|
||||
return connect_func(listener);
|
||||
}
|
||||
} // namespace LLEventDetail
|
||||
|
||||
|
|
|
|||
|
|
@ -1,198 +0,0 @@
|
|||
/**
|
||||
* @file lllistenerwrapper.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2009-11-30
|
||||
* @brief Introduce LLListenerWrapper template
|
||||
*
|
||||
* $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_LLLISTENERWRAPPER_H)
|
||||
#define LL_LLLISTENERWRAPPER_H
|
||||
|
||||
#include "llevents.h" // LLListenerWrapperBase
|
||||
#include <boost/visit_each.hpp>
|
||||
|
||||
/**
|
||||
* Template base class for coding wrappers for LLEventPump listeners.
|
||||
*
|
||||
* Derive your listener wrapper from LLListenerWrapper. You must use
|
||||
* LLLISTENER_WRAPPER_SUBCLASS() so your subclass will play nicely with
|
||||
* boost::visit_each (q.v.). That way boost::signals2 can still detect
|
||||
* derivation from LLEventTrackable, and so forth.
|
||||
*/
|
||||
template <typename LISTENER>
|
||||
class LLListenerWrapper: public LLListenerWrapperBase
|
||||
{
|
||||
public:
|
||||
/// Wrap an arbitrary listener object
|
||||
LLListenerWrapper(const LISTENER& listener):
|
||||
mListener(listener)
|
||||
{}
|
||||
|
||||
/// call
|
||||
virtual bool operator()(const LLSD& event)
|
||||
{
|
||||
return mListener(event);
|
||||
}
|
||||
|
||||
/// Allow boost::visit_each() to peek at our mListener.
|
||||
template <class V>
|
||||
void accept_visitor(V& visitor) const
|
||||
{
|
||||
using boost::visit_each;
|
||||
visit_each(visitor, mListener, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
LISTENER mListener;
|
||||
};
|
||||
|
||||
/**
|
||||
* Specialize boost::visit_each() (leveraging ADL) to peek inside an
|
||||
* LLListenerWrapper<T> to traverse its LISTENER. We borrow the
|
||||
* accept_visitor() pattern from boost::bind(), avoiding the need to make
|
||||
* mListener public.
|
||||
*/
|
||||
template <class V, typename T>
|
||||
void visit_each(V& visitor, const LLListenerWrapper<T>& wrapper, int)
|
||||
{
|
||||
wrapper.accept_visitor(visitor);
|
||||
}
|
||||
|
||||
/// use this (sigh!) for each subclass of LLListenerWrapper<T> you write
|
||||
#define LLLISTENER_WRAPPER_SUBCLASS(CLASS) \
|
||||
template <class V, typename T> \
|
||||
void visit_each(V& visitor, const CLASS<T>& wrapper, int) \
|
||||
{ \
|
||||
visit_each(visitor, static_cast<const LLListenerWrapper<T>&>(wrapper), 0); \
|
||||
} \
|
||||
\
|
||||
/* Have to state this explicitly, rather than using LL_TEMPLATE_CONVERTIBLE, */ \
|
||||
/* because the source type is itself a template. */ \
|
||||
template <typename T> \
|
||||
struct ll_template_cast_impl<const LLListenerWrapperBase*, const CLASS<T>*> \
|
||||
{ \
|
||||
const LLListenerWrapperBase* operator()(const CLASS<T>* wrapper) \
|
||||
{ \
|
||||
return wrapper; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an instance of a listener wrapper. Every wrapper class must be a
|
||||
* template accepting a listener object of arbitrary type. In particular, the
|
||||
* type of a boost::bind() expression is deliberately undocumented. So we
|
||||
* can't just write Wrapper<CorrectType>(boost::bind(...)). Instead we must
|
||||
* write llwrap<Wrapper>(boost::bind(...)).
|
||||
*/
|
||||
template <template<typename> class WRAPPER, typename T>
|
||||
WRAPPER<T> llwrap(const T& listener)
|
||||
{
|
||||
return WRAPPER<T>(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* This LLListenerWrapper template subclass is used to report entry/exit to an
|
||||
* event listener, by changing this:
|
||||
* @code
|
||||
* someEventPump.listen("MyClass",
|
||||
* boost::bind(&MyClass::method, ptr, _1));
|
||||
* @endcode
|
||||
* to this:
|
||||
* @code
|
||||
* someEventPump.listen("MyClass",
|
||||
* llwrap<LLCoutListener>(
|
||||
* boost::bind(&MyClass::method, ptr, _1)));
|
||||
* @endcode
|
||||
*/
|
||||
template <class LISTENER>
|
||||
class LLCoutListener: public LLListenerWrapper<LISTENER>
|
||||
{
|
||||
typedef LLListenerWrapper<LISTENER> super;
|
||||
|
||||
public:
|
||||
/// Wrap an arbitrary listener object
|
||||
LLCoutListener(const LISTENER& listener):
|
||||
super(listener)
|
||||
{}
|
||||
|
||||
/// call
|
||||
virtual bool operator()(const LLSD& event)
|
||||
{
|
||||
std::cout << "Entering listener " << *super::mName << " with " << event << std::endl;
|
||||
bool handled = super::operator()(event);
|
||||
std::cout << "Leaving listener " << *super::mName;
|
||||
if (handled)
|
||||
{
|
||||
std::cout << " (handled)";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return handled;
|
||||
}
|
||||
};
|
||||
|
||||
LLLISTENER_WRAPPER_SUBCLASS(LLCoutListener);
|
||||
|
||||
/**
|
||||
* This LLListenerWrapper template subclass is used to log entry/exit to an
|
||||
* event listener, by changing this:
|
||||
* @code
|
||||
* someEventPump.listen("MyClass",
|
||||
* boost::bind(&MyClass::method, ptr, _1));
|
||||
* @endcode
|
||||
* to this:
|
||||
* @code
|
||||
* someEventPump.listen("MyClass",
|
||||
* llwrap<LLLogListener>(
|
||||
* boost::bind(&MyClass::method, ptr, _1)));
|
||||
* @endcode
|
||||
*/
|
||||
template <class LISTENER>
|
||||
class LLLogListener: public LLListenerWrapper<LISTENER>
|
||||
{
|
||||
typedef LLListenerWrapper<LISTENER> super;
|
||||
|
||||
public:
|
||||
/// Wrap an arbitrary listener object
|
||||
LLLogListener(const LISTENER& listener):
|
||||
super(listener)
|
||||
{}
|
||||
|
||||
/// call
|
||||
virtual bool operator()(const LLSD& event)
|
||||
{
|
||||
LL_DEBUGS("LLLogListener") << "Entering listener " << *super::mName << " with " << event << LL_ENDL;
|
||||
bool handled = super::operator()(event);
|
||||
LL_DEBUGS("LLLogListener") << "Leaving listener " << *super::mName;
|
||||
if (handled)
|
||||
{
|
||||
LL_CONT << " (handled)";
|
||||
}
|
||||
LL_CONT << LL_ENDL;
|
||||
return handled;
|
||||
}
|
||||
};
|
||||
|
||||
LLLISTENER_WRAPPER_SUBCLASS(LLLogListener);
|
||||
|
||||
#endif /* ! defined(LL_LLLISTENERWRAPPER_H) */
|
||||
|
|
@ -38,7 +38,6 @@
|
|||
#define testable public
|
||||
#include "llevents.h"
|
||||
#undef testable
|
||||
#include "lllistenerwrapper.h"
|
||||
// STL headers
|
||||
// std headers
|
||||
#include <iostream>
|
||||
|
|
@ -643,33 +642,6 @@ ensure("implicit disconnect", ! connection.connected());
|
|||
heaptest.post(2);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void events_object::test<15>()
|
||||
{
|
||||
// This test ensures that using an LLListenerWrapper subclass doesn't
|
||||
// block Boost.Signals2 from recognizing a bound LLEventTrackable
|
||||
// subclass.
|
||||
set_test_name("listen(llwrap<LLLogListener>(boost::bind(...TempTrackableListener ref...)))");
|
||||
bool live = false;
|
||||
LLEventPump& heaptest(pumps.obtain("heaptest"));
|
||||
LLBoundListener connection;
|
||||
{
|
||||
TempTrackableListener tempListener("temp", live);
|
||||
ensure("TempTrackableListener constructed", live);
|
||||
connection = heaptest.listen(tempListener.getName(),
|
||||
llwrap<LLLogListener>(
|
||||
boost::bind(&TempTrackableListener::call,
|
||||
boost::ref(tempListener), _1)));
|
||||
heaptest.post(1);
|
||||
check_listener("received", tempListener, 1);
|
||||
} // presumably this will make tempListener go away?
|
||||
// verify that
|
||||
ensure("TempTrackableListener destroyed", ! live);
|
||||
ensure("implicit disconnect", ! connection.connected());
|
||||
// now just make sure we don't blow up trying to access a freed object!
|
||||
heaptest.post(2);
|
||||
}
|
||||
|
||||
class TempSharedListener: public TempListener,
|
||||
public boost::enable_shared_from_this<TempSharedListener>
|
||||
{
|
||||
|
|
@ -680,7 +652,7 @@ TempSharedListener(const std::string& name, bool& liveFlag):
|
|||
};
|
||||
|
||||
template<> template<>
|
||||
void events_object::test<16>()
|
||||
void events_object::test<15>()
|
||||
{
|
||||
set_test_name("listen(boost::bind(...TempSharedListener ref...))");
|
||||
#if 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue