phoenix-firestorm/indra/llcommon/llevent.h

197 lines
6.0 KiB
C++

/**
* @file llevent.h
* @author Tom Yedwab
* @brief LLEvent and LLEventListener base classes.
*
* $LicenseInfo:firstyear=2001&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$
*/
#ifndef LL_EVENT_H
#define LL_EVENT_H
#include "llsd.h"
#include "llrefcount.h"
#include "llpointer.h"
namespace LLOldEvents
{
class LLEventListener;
class LLEvent;
class LLEventDispatcher;
class LLObservable;
// Abstract event. All events derive from LLEvent
class LL_COMMON_API LLEvent : public LLThreadSafeRefCount
{
protected:
virtual ~LLEvent();
public:
LLEvent(LLObservable* source, const std::string& desc = "") : mSource(source), mDesc(desc) { }
LLObservable* getSource() { return mSource; }
virtual LLSD getValue() { return LLSD(); }
// Determines whether this particular listener
// should be notified of this event.
// If this function returns true, handleEvent is
// called on the listener with this event as the
// argument.
// Defaults to handling all events. Override this
// if associated with an Observable with many different listeners
virtual bool accept(LLEventListener* listener);
// return a string describing the event
virtual const std::string& desc();
private:
LLObservable* mSource;
std::string mDesc;
};
// Abstract listener. All listeners derive from LLEventListener
class LL_COMMON_API LLEventListener : public LLThreadSafeRefCount
{
protected:
virtual ~LLEventListener();
public:
// Processes the event.
// TODO: Make the return value less ambiguous?
virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) = 0;
// Called when an dispatcher starts/stops listening
virtual bool handleAttach(LLEventDispatcher *dispatcher) = 0;
virtual bool handleDetach(LLEventDispatcher *dispatcher) = 0;
};
// A listener which tracks references to it and cleans up when it's deallocated
class LL_COMMON_API LLSimpleListener : public LLEventListener
{
public:
void clearDispatchers();
virtual bool handleAttach(LLEventDispatcher *dispatcher);
virtual bool handleDetach(LLEventDispatcher *dispatcher);
protected:
~LLSimpleListener();
std::vector<LLEventDispatcher *> mDispatchers;
};
class LLObservable; // defined below
// A structure which stores a Listener and its metadata
struct LLListenerEntry
{
LLEventListener* listener;
LLSD filter;
LLSD userdata;
};
// Base class for a dispatcher - an object which listens
// to events being fired and relays them to their
// appropriate destinations.
class LL_COMMON_API LLEventDispatcher : public LLThreadSafeRefCount
{
protected:
virtual ~LLEventDispatcher();
public:
// The default constructor creates a default simple dispatcher implementation.
// The simple implementation has an array of listeners and fires every event to
// all of them.
LLEventDispatcher();
// This dispatcher is being attached to an observable object.
// If we return false, the attach fails.
bool engage(LLObservable* observable);
// This dispatcher is being detached from an observable object.
void disengage(LLObservable* observable);
// Adds a listener to this dispatcher, with a given user data
// that will be passed to the listener when an event is fired.
// Duplicate pointers are removed on addtion.
void addListener(LLEventListener *listener, LLSD filter, const LLSD& userdata);
// Removes a listener from this dispatcher
void removeListener(LLEventListener *listener);
// Gets a list of interested listeners
std::vector<LLListenerEntry> getListeners() const;
// Handle an event that has just been fired by communicating it
// to listeners, passing it across a network, etc.
bool fireEvent(LLPointer<LLEvent> event, LLSD filter);
public:
class Impl;
private:
Impl* impl;
};
// Interface for observable data (data that fires events)
// In order for this class to work properly, it needs
// an instance of an LLEventDispatcher to route events to their
// listeners.
class LL_COMMON_API LLObservable
{
public:
// Initialize with the default Dispatcher
LLObservable();
virtual ~LLObservable();
// Replaces the existing dispatcher pointer to the new one,
// informing the dispatcher of the change.
virtual bool setDispatcher(LLPointer<LLEventDispatcher> dispatcher);
// Returns the current dispatcher pointer.
virtual LLEventDispatcher* getDispatcher();
void addListener(LLEventListener *listener, LLSD filter = "", const LLSD& userdata = "")
{
if (mDispatcher.notNull()) mDispatcher->addListener(listener, filter, userdata);
}
void removeListener(LLEventListener *listener)
{
if (mDispatcher.notNull()) mDispatcher->removeListener(listener);
}
// Notifies the dispatcher of an event being fired.
void fireEvent(LLPointer<LLEvent> event, LLSD filter = LLSD());
protected:
LLPointer<LLEventDispatcher> mDispatcher;
};
class LLValueChangedEvent : public LLEvent
{
public:
LLValueChangedEvent(LLObservable* source, LLSD value) : LLEvent(source, "value_changed"), mValue(value) { }
LLSD getValue() { return mValue; }
LLSD mValue;
};
} // LLOldEvents
#endif // LL_EVENT_H