Incomplete attempt to clean up Mercurial branch build
parent
d01e9ccb75
commit
07a05e2c0a
|
|
@ -19,7 +19,6 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <stdexcept>
|
||||
#include <boost/signals2.hpp>
|
||||
|
|
@ -28,13 +27,9 @@
|
|||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/utility.hpp> // noncopyable
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
#include <boost/visit_each.hpp>
|
||||
#include <boost/ref.hpp> // reference_wrapper
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include "llsd.h"
|
||||
|
|
@ -111,6 +106,9 @@ typedef LLStandardSignal::slot_type LLEventListener;
|
|||
/// Result of registering a listener, supports <tt>connected()</tt>,
|
||||
/// <tt>disconnect()</tt> and <tt>blocked()</tt>
|
||||
typedef boost::signals2::connection LLBoundListener;
|
||||
/// Storing an LLBoundListener in LLTempBoundListener will disconnect the
|
||||
/// referenced listener when the LLTempBoundListener instance is destroyed.
|
||||
typedef boost::signals2::scoped_connection LLTempBoundListener;
|
||||
|
||||
/**
|
||||
* A common idiom for event-based code is to accept either a callable --
|
||||
|
|
@ -127,7 +125,7 @@ typedef boost::signals2::connection LLBoundListener;
|
|||
* LLListenerOrPumpName::Empty. Test for this condition beforehand using
|
||||
* either <tt>if (param)</tt> or <tt>if (! param)</tt>.
|
||||
*/
|
||||
class LLListenerOrPumpName
|
||||
class LL_COMMON_API LLListenerOrPumpName
|
||||
{
|
||||
public:
|
||||
/// passing string name of LLEventPump
|
||||
|
|
@ -174,13 +172,13 @@ private:
|
|||
/*****************************************************************************
|
||||
* LLEventPumps
|
||||
*****************************************************************************/
|
||||
class LLEventPump;
|
||||
class LL_COMMON_API LLEventPump;
|
||||
|
||||
/**
|
||||
* LLEventPumps is a Singleton manager through which one typically accesses
|
||||
* this subsystem.
|
||||
*/
|
||||
class LLEventPumps: public LLSingleton<LLEventPumps>
|
||||
class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps>
|
||||
{
|
||||
friend class LLSingleton<LLEventPumps>;
|
||||
public:
|
||||
|
|
@ -254,14 +252,62 @@ namespace LLEventDetail
|
|||
const ConnectFunc& connect_func);
|
||||
} // namespace LLEventDetail
|
||||
|
||||
/*****************************************************************************
|
||||
* LLEventTrackable
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* LLEventTrackable wraps boost::signals2::trackable, which resembles
|
||||
* boost::trackable. Derive your listener class from LLEventTrackable instead,
|
||||
* and use something like
|
||||
* <tt>LLEventPump::listen(boost::bind(&YourTrackableSubclass::method,
|
||||
* instance, _1))</tt>. This will implicitly disconnect when the object
|
||||
* referenced by @c instance is destroyed.
|
||||
*
|
||||
* @note
|
||||
* LLEventTrackable doesn't address a couple of cases:
|
||||
* * Object destroyed during call
|
||||
* - You enter a slot call in thread A.
|
||||
* - Thread B destroys the object, which of course disconnects it from any
|
||||
* future slot calls.
|
||||
* - Thread A's call uses 'this', which now refers to a defunct object.
|
||||
* Undefined behavior results.
|
||||
* * Call during destruction
|
||||
* - @c MySubclass is derived from LLEventTrackable.
|
||||
* - @c MySubclass registers one of its own methods using
|
||||
* <tt>LLEventPump::listen()</tt>.
|
||||
* - The @c MySubclass object begins destruction. <tt>~MySubclass()</tt>
|
||||
* runs, destroying state specific to the subclass. (For instance, a
|
||||
* <tt>Foo*</tt> data member is <tt>delete</tt>d but not zeroed.)
|
||||
* - The listening method will not be disconnected until
|
||||
* <tt>~LLEventTrackable()</tt> runs.
|
||||
* - Before we get there, another thread posts data to the @c LLEventPump
|
||||
* instance, calling the @c MySubclass method.
|
||||
* - The method in question relies on valid @c MySubclass state. (For
|
||||
* instance, it attempts to dereference the <tt>Foo*</tt> pointer that was
|
||||
* <tt>delete</tt>d but not zeroed.)
|
||||
* - Undefined behavior results.
|
||||
* If you suspect you may encounter any such scenario, you're better off
|
||||
* managing the lifespan of your object with <tt>boost::shared_ptr</tt>.
|
||||
* Passing <tt>LLEventPump::listen()</tt> a <tt>boost::bind()</tt> expression
|
||||
* involving a <tt>boost::weak_ptr<Foo></tt> is recognized specially, engaging
|
||||
* thread-safe Boost.Signals2 machinery.
|
||||
*/
|
||||
typedef boost::signals2::trackable LLEventTrackable;
|
||||
|
||||
/*****************************************************************************
|
||||
* LLEventPump
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* LLEventPump is the base class interface through which we access the
|
||||
* concrete subclasses LLEventStream and LLEventQueue.
|
||||
*
|
||||
* @NOTE
|
||||
* LLEventPump derives from LLEventTrackable so that when you "chain"
|
||||
* LLEventPump instances together, they will automatically disconnect on
|
||||
* destruction. Please see LLEventTrackable documentation for situations in
|
||||
* which this may be perilous across threads.
|
||||
*/
|
||||
class LLEventPump: boost::noncopyable
|
||||
class LL_COMMON_API LLEventPump: public LLEventTrackable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
|
@ -364,10 +410,22 @@ public:
|
|||
* themselves. listen() can throw any ListenError; see ListenError
|
||||
* subclasses.
|
||||
*
|
||||
* If (as is typical) you pass a <tt>boost::bind()</tt> expression,
|
||||
* listen() will inspect the components of that expression. If a bound
|
||||
* object matches any of several cases, the connection will automatically
|
||||
* be disconnected when that object is destroyed.
|
||||
* The listener name must be unique among active listeners for this
|
||||
* LLEventPump, else you get DupListenerName. If you don't care to invent
|
||||
* a name yourself, use inventName(). (I was tempted to recognize e.g. ""
|
||||
* and internally generate a distinct name for that case. But that would
|
||||
* handle badly the scenario in which you want to add, remove, re-add,
|
||||
* etc. the same listener: each new listen() call would necessarily
|
||||
* perform a new dependency sort. Assuming you specify the same
|
||||
* after/before lists each time, using inventName() when you first
|
||||
* instantiate your listener, then passing the same name on each listen()
|
||||
* call, allows us to optimize away the second and subsequent dependency
|
||||
* sorts.
|
||||
*
|
||||
* If (as is typical) you pass a <tt>boost::bind()</tt> expression as @a
|
||||
* listener, listen() will inspect the components of that expression. If a
|
||||
* bound object matches any of several cases, the connection will
|
||||
* automatically be disconnected when that object is destroyed.
|
||||
*
|
||||
* * You bind a <tt>boost::weak_ptr</tt>.
|
||||
* * Binding a <tt>boost::shared_ptr</tt> that way would ensure that the
|
||||
|
|
@ -429,6 +487,9 @@ public:
|
|||
/// query
|
||||
virtual bool enabled() const { return mEnabled; }
|
||||
|
||||
/// Generate a distinct name for a listener -- see listen()
|
||||
static std::string inventName(const std::string& pfx="listener");
|
||||
|
||||
private:
|
||||
friend class LLEventPumps;
|
||||
/// flush queued events
|
||||
|
|
@ -467,7 +528,7 @@ protected:
|
|||
* LLEventStream is a thin wrapper around LLStandardSignal. Posting an
|
||||
* event immediately calls all registered listeners.
|
||||
*/
|
||||
class LLEventStream: public LLEventPump
|
||||
class LL_COMMON_API LLEventStream: public LLEventPump
|
||||
{
|
||||
public:
|
||||
LLEventStream(const std::string& name, bool tweak=false): LLEventPump(name, tweak) {}
|
||||
|
|
@ -484,7 +545,7 @@ public:
|
|||
* LLEventQueue isa LLEventPump whose post() method defers calling registered
|
||||
* listeners until flush() is called.
|
||||
*/
|
||||
class LLEventQueue: public LLEventPump
|
||||
class LL_COMMON_API LLEventQueue: public LLEventPump
|
||||
{
|
||||
public:
|
||||
LLEventQueue(const std::string& name, bool tweak=false): LLEventPump(name, tweak) {}
|
||||
|
|
@ -503,47 +564,89 @@ private:
|
|||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LLEventTrackable and underpinnings
|
||||
* LLReqID
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* LLEventTrackable wraps boost::signals2::trackable, which resembles
|
||||
* boost::trackable. Derive your listener class from LLEventTrackable instead,
|
||||
* and use something like
|
||||
* <tt>LLEventPump::listen(boost::bind(&YourTrackableSubclass::method,
|
||||
* instance, _1))</tt>. This will implicitly disconnect when the object
|
||||
* referenced by @c instance is destroyed.
|
||||
* This class helps the implementer of a given event API to honor the
|
||||
* ["reqid"] convention. By this convention, each event API stamps into its
|
||||
* response LLSD a ["reqid"] key whose value echoes the ["reqid"] value, if
|
||||
* any, from the corresponding request.
|
||||
*
|
||||
* This supports an (atypical, but occasionally necessary) use case in which
|
||||
* two or more asynchronous requests are multiplexed onto the same ["reply"]
|
||||
* LLEventPump. Since the response events could arrive in arbitrary order, the
|
||||
* caller must be able to demux them. It does so by matching the ["reqid"]
|
||||
* value in each response with the ["reqid"] value in the corresponding
|
||||
* request.
|
||||
*
|
||||
* It is the caller's responsibility to ensure distinct ["reqid"] values for
|
||||
* that case. Though LLSD::UUID is guaranteed to work, it might be overkill:
|
||||
* the "namespace" of unique ["reqid"] values is simply the set of requests
|
||||
* specifying the same ["reply"] LLEventPump name.
|
||||
*
|
||||
* Making a given event API echo the request's ["reqid"] into the response is
|
||||
* nearly trivial. This helper is mostly for mnemonic purposes, to serve as a
|
||||
* place to put these comments. We hope that each time a coder implements a
|
||||
* new event API based on some existing one, s/he will say, "Huh, what's an
|
||||
* LLReqID?" and look up this material.
|
||||
*
|
||||
* The hardest part about the convention is deciding where to store the
|
||||
* ["reqid"] value. Ironically, LLReqID can't help with that: you must store
|
||||
* an LLReqID instance in whatever storage will persist until the reply is
|
||||
* sent. For example, if the request ultimately ends up using a Responder
|
||||
* subclass, storing an LLReqID instance in the Responder works.
|
||||
*
|
||||
* @note
|
||||
* LLEventTrackable doesn't address a couple of cases:
|
||||
* * Object destroyed during call
|
||||
* - You enter a slot call in thread A.
|
||||
* - Thread B destroys the object, which of course disconnects it from any
|
||||
* future slot calls.
|
||||
* - Thread A's call uses 'this', which now refers to a defunct object.
|
||||
* Undefined behavior results.
|
||||
* * Call during destruction
|
||||
* - @c MySubclass is derived from LLEventTrackable.
|
||||
* - @c MySubclass registers one of its own methods using
|
||||
* <tt>LLEventPump::listen()</tt>.
|
||||
* - The @c MySubclass object begins destruction. <tt>~MySubclass()</tt>
|
||||
* runs, destroying state specific to the subclass. (For instance, a
|
||||
* <tt>Foo*</tt> data member is <tt>delete</tt>d but not zeroed.)
|
||||
* - The listening method will not be disconnected until
|
||||
* <tt>~LLEventTrackable()</tt> runs.
|
||||
* - Before we get there, another thread posts data to the @c LLEventPump
|
||||
* instance, calling the @c MySubclass method.
|
||||
* - The method in question relies on valid @c MySubclass state. (For
|
||||
* instance, it attempts to dereference the <tt>Foo*</tt> pointer that was
|
||||
* <tt>delete</tt>d but not zeroed.)
|
||||
* - Undefined behavior results.
|
||||
* If you suspect you may encounter any such scenario, you're better off
|
||||
* managing the lifespan of your object with <tt>boost::shared_ptr</tt>.
|
||||
* Passing <tt>LLEventPump::listen()</tt> a <tt>boost::bind()</tt> expression
|
||||
* involving a <tt>boost::weak_ptr<Foo></tt> is recognized specially, engaging
|
||||
* thread-safe Boost.Signals2 machinery.
|
||||
* The @em implementer of an event API must honor the ["reqid"] convention.
|
||||
* However, the @em caller of an event API need only use it if s/he is sharing
|
||||
* the same ["reply"] LLEventPump for two or more asynchronous event API
|
||||
* requests.
|
||||
*
|
||||
* In most cases, it's far easier for the caller to instantiate a local
|
||||
* LLEventStream and pass its name to the event API in question. Then it's
|
||||
* perfectly reasonable not to set a ["reqid"] key in the request, ignoring
|
||||
* the @c isUndefined() ["reqid"] value in the response.
|
||||
*/
|
||||
typedef boost::signals2::trackable LLEventTrackable;
|
||||
class LLReqID
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* If you have the request in hand at the time you instantiate the
|
||||
* LLReqID, pass that request to extract its ["reqid"].
|
||||
*/
|
||||
LLReqID(const LLSD& request):
|
||||
mReqid(request["reqid"])
|
||||
{}
|
||||
/// If you don't yet have the request, use setFrom() later.
|
||||
LLReqID() {}
|
||||
|
||||
/// Extract and store the ["reqid"] value from an incoming request.
|
||||
void setFrom(const LLSD& request)
|
||||
{
|
||||
mReqid = request["reqid"];
|
||||
}
|
||||
|
||||
/// Set ["reqid"] key into a pending response LLSD object.
|
||||
void stamp(LLSD& response) const;
|
||||
|
||||
/// Make a whole new response LLSD object with our ["reqid"].
|
||||
LLSD makeResponse() const
|
||||
{
|
||||
LLSD response;
|
||||
stamp(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/// Not really sure of a use case for this accessor...
|
||||
LLSD getReqID() const { return mReqid; }
|
||||
|
||||
private:
|
||||
LLSD mReqid;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Underpinnings
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* We originally provided a suite of overloaded
|
||||
* LLEventTrackable::listenTo(LLEventPump&, ...) methods that would call
|
||||
|
|
|
|||
|
|
@ -229,5 +229,5 @@ IF (NOT LINUX AND VIEWER)
|
|||
# Commented out - see rationale at bottom of newview's build file + poppy 2009-06-05
|
||||
# Don't make llmessage depend on llsdmessage_test because ADD_COMM_BUILD_TEST depends on llmessage!
|
||||
# ADD_COMM_BUILD_TEST(llsdmessage "" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py")
|
||||
ADD_BUILD_TEST(llareslistener llmessage)
|
||||
# ADD_BUILD_TEST(llareslistener llmessage)
|
||||
ENDIF (NOT LINUX AND VIEWER)
|
||||
|
|
|
|||
|
|
@ -3652,7 +3652,7 @@ void LLAppViewer::idleShutdown()
|
|||
if (!saved_teleport_history)
|
||||
{
|
||||
saved_teleport_history = true;
|
||||
LLTeleportHistory::getInstance()->save();
|
||||
LLTeleportHistory::getInstance()->dump();
|
||||
LLLocationHistory::getInstance()->save(); // *TODO: find a better place for doing this
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -562,165 +562,6 @@ protected:
|
|||
EWearableType mWearableType;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInvFVBridgeAction (& it's derived classes)
|
||||
//
|
||||
// This is an implementation class to be able to
|
||||
// perform action to view inventory items.
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLInvFVBridgeAction
|
||||
{
|
||||
public:
|
||||
// This method is a convenience function which creates the correct
|
||||
// type of bridge action based on some basic information
|
||||
static LLInvFVBridgeAction* createAction(LLAssetType::EType asset_type,
|
||||
const LLUUID& uuid,LLInventoryModel* model);
|
||||
|
||||
static void doAction(LLAssetType::EType asset_type,
|
||||
const LLUUID& uuid,LLInventoryModel* model);
|
||||
|
||||
virtual void doIt() { };
|
||||
virtual ~LLInvFVBridgeAction(){}//need this because of warning on OSX
|
||||
protected:
|
||||
LLInvFVBridgeAction(const LLUUID& id,LLInventoryModel* model):mUUID(id),mModel(model){}
|
||||
|
||||
LLViewerInventoryItem* getItem() const;
|
||||
protected:
|
||||
const LLUUID& mUUID; // item id
|
||||
LLInventoryModel* mModel;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LLTextureBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLTextureBridgeAction(){}
|
||||
protected:
|
||||
LLTextureBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLSoundBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLSoundBridgeAction(){}
|
||||
protected:
|
||||
LLSoundBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLLandmarkBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLLandmarkBridgeAction(){}
|
||||
protected:
|
||||
LLLandmarkBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLCallingCardBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLCallingCardBridgeAction(){}
|
||||
protected:
|
||||
LLCallingCardBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLNotecardBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLNotecardBridgeAction(){}
|
||||
protected:
|
||||
LLNotecardBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLGestureBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLGestureBridgeAction(){}
|
||||
protected:
|
||||
LLGestureBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLAnimationBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLAnimationBridgeAction(){}
|
||||
protected:
|
||||
LLAnimationBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLObjectBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLObjectBridgeAction(){}
|
||||
protected:
|
||||
LLObjectBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLLSLTextBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt() ;
|
||||
virtual ~LLLSLTextBridgeAction(){}
|
||||
protected:
|
||||
LLLSLTextBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLWearableBridgeAction: public LLInvFVBridgeAction
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
virtual void doIt();
|
||||
virtual ~LLWearableBridgeAction(){}
|
||||
protected:
|
||||
LLWearableBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
|
||||
|
||||
|
||||
BOOL isInTrash() const;
|
||||
// return true if the item is in agent inventory. if false, it
|
||||
// must be lost or in the inventory library.
|
||||
BOOL isAgentInventory() const;
|
||||
|
||||
void wearOnAvatar();
|
||||
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInvFVBridgeAction (& it's derived classes)
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1844,7 +1844,7 @@ bool LLInventoryModel::isCategoryComplete(const LLUUID& cat_id) const
|
|||
}
|
||||
|
||||
bool LLInventoryModel::loadSkeleton(
|
||||
const LLInventoryModel::options_t& options,
|
||||
const LLSD& options,
|
||||
const LLUUID& owner_id)
|
||||
{
|
||||
lldebugs << "importing inventory skeleton for " << owner_id << llendl;
|
||||
|
|
@ -1857,44 +1857,41 @@ bool LLInventoryModel::loadSkeleton(
|
|||
LLUUID id;
|
||||
LLAssetType::EType preferred_type;
|
||||
bool rv = true;
|
||||
for(options_t::const_iterator it = options.begin(); it < options.end(); ++it)
|
||||
|
||||
for(LLSD::array_const_iterator it = options.beginArray(),
|
||||
end = options.endArray(); it != end; ++it)
|
||||
{
|
||||
LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(owner_id);
|
||||
response_t::const_iterator no_response = (*it).end();
|
||||
response_t::const_iterator skel;
|
||||
skel = (*it).find("name");
|
||||
if(skel == no_response) goto clean_cat;
|
||||
cat->rename(std::string((*skel).second));
|
||||
skel = (*it).find("folder_id");
|
||||
if(skel == no_response) goto clean_cat;
|
||||
id.set((*skel).second);
|
||||
// if an id is null, it locks the viewer.
|
||||
if(id.isNull()) goto clean_cat;
|
||||
cat->setUUID(id);
|
||||
skel = (*it).find("parent_id");
|
||||
if(skel == no_response) goto clean_cat;
|
||||
id.set((*skel).second);
|
||||
cat->setParent(id);
|
||||
skel = (*it).find("type_default");
|
||||
if(skel == no_response)
|
||||
LLSD name = (*it)["name"];
|
||||
LLSD folder_id = (*it)["folder_id"];
|
||||
LLSD parent_id = (*it)["parent_id"];
|
||||
LLSD version = (*it)["version"];
|
||||
if(name.isDefined()
|
||||
&& folder_id.isDefined()
|
||||
&& parent_id.isDefined()
|
||||
&& version.isDefined()
|
||||
&& folder_id.asUUID().notNull() // if an id is null, it locks the viewer.
|
||||
)
|
||||
{
|
||||
preferred_type = LLAssetType::AT_NONE;
|
||||
LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(owner_id);
|
||||
cat->rename(name.asString());
|
||||
cat->setUUID(folder_id.asUUID());
|
||||
cat->setParent(parent_id.asUUID());
|
||||
|
||||
LLAssetType::EType preferred_type = LLAssetType::AT_NONE;
|
||||
LLSD type_default = (*it)["type_default"];
|
||||
if(type_default.isDefined())
|
||||
{
|
||||
preferred_type = (LLAssetType::EType)type_default.asInteger();
|
||||
}
|
||||
cat->setPreferredType(preferred_type);
|
||||
cat->setVersion(version.asInteger());
|
||||
temp_cats.insert(cat);
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 t = atoi((*skel).second.c_str());
|
||||
preferred_type = (LLAssetType::EType)t;
|
||||
llwarns << "Unable to import near " << name.asString() << llendl;
|
||||
rv = false;
|
||||
}
|
||||
cat->setPreferredType(preferred_type);
|
||||
skel = (*it).find("version");
|
||||
if(skel == no_response) goto clean_cat;
|
||||
cat->setVersion(atoi((*skel).second.c_str()));
|
||||
temp_cats.insert(cat);
|
||||
continue;
|
||||
clean_cat:
|
||||
llwarns << "Unable to import near " << cat->getName() << llendl;
|
||||
rv = false;
|
||||
//delete cat; // automatic when cat is reasigned or destroyed
|
||||
}
|
||||
|
||||
S32 cached_category_count = 0;
|
||||
|
|
@ -2053,85 +2050,84 @@ bool LLInventoryModel::loadSkeleton(
|
|||
return rv;
|
||||
}
|
||||
|
||||
bool LLInventoryModel::loadMeat(
|
||||
const LLInventoryModel::options_t& options, const LLUUID& owner_id)
|
||||
bool LLInventoryModel::loadMeat(const LLSD& options, const LLUUID& owner_id)
|
||||
{
|
||||
llinfos << "importing inventory for " << owner_id << llendl;
|
||||
LLPermissions default_perm;
|
||||
default_perm.init(LLUUID::null, owner_id, LLUUID::null, LLUUID::null);
|
||||
LLPointer<LLViewerInventoryItem> item;
|
||||
LLUUID id;
|
||||
LLAssetType::EType type;
|
||||
LLInventoryType::EType inv_type;
|
||||
bool rv = true;
|
||||
for(options_t::const_iterator it = options.begin(); it < options.end(); ++it)
|
||||
for(LLSD::array_const_iterator it = options.beginArray(),
|
||||
end = options.endArray(); it != end; ++it)
|
||||
{
|
||||
item = new LLViewerInventoryItem;
|
||||
response_t::const_iterator no_response = (*it).end();
|
||||
response_t::const_iterator meat;
|
||||
meat = (*it).find("name");
|
||||
if(meat == no_response) goto clean_item;
|
||||
item->rename(std::string((*meat).second));
|
||||
meat = (*it).find("item_id");
|
||||
if(meat == no_response) goto clean_item;
|
||||
id.set((*meat).second);
|
||||
item->setUUID(id);
|
||||
meat = (*it).find("parent_id");
|
||||
if(meat == no_response) goto clean_item;
|
||||
id.set((*meat).second);
|
||||
item->setParent(id);
|
||||
meat = (*it).find("type");
|
||||
if(meat == no_response) goto clean_item;
|
||||
type = (LLAssetType::EType)atoi((*meat).second.c_str());
|
||||
item->setType(type);
|
||||
meat = (*it).find("inv_type");
|
||||
if(meat != no_response)
|
||||
LLSD name = (*it)["name"];
|
||||
LLSD item_id = (*it)["item_id"];
|
||||
LLSD parent_id = (*it)["parent_id"];
|
||||
LLSD asset_type = (*it)["type"];
|
||||
LLSD data_id = (*it)["data_id"];
|
||||
if(name.isDefined()
|
||||
&& item_id.isDefined()
|
||||
&& parent_id.isDefined()
|
||||
&& asset_type.isDefined()
|
||||
&& data_id.isDefined())
|
||||
{
|
||||
inv_type = (LLInventoryType::EType)atoi((*meat).second.c_str());
|
||||
item->setInventoryType(inv_type);
|
||||
}
|
||||
meat = (*it).find("data_id");
|
||||
if(meat == no_response) goto clean_item;
|
||||
id.set((*meat).second);
|
||||
if(LLAssetType::AT_CALLINGCARD == type)
|
||||
{
|
||||
LLPermissions perm;
|
||||
perm.init(id, owner_id, LLUUID::null, LLUUID::null);
|
||||
item->setPermissions(perm);
|
||||
LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem;
|
||||
item->rename(name.asString());
|
||||
item->setUUID(item_id.asUUID());
|
||||
item->setParent(parent_id.asUUID());
|
||||
LLAssetType::EType type = (LLAssetType::EType)asset_type.asInteger();
|
||||
item->setType(type);
|
||||
|
||||
LLSD llsd_inv_type = (*it)["inv_type"];
|
||||
if(llsd_inv_type.isDefined())
|
||||
{
|
||||
LLInventoryType::EType inv_type = (LLInventoryType::EType)llsd_inv_type.asInteger();
|
||||
item->setInventoryType(inv_type);
|
||||
}
|
||||
|
||||
if(LLAssetType::AT_CALLINGCARD == type)
|
||||
{
|
||||
LLPermissions perm;
|
||||
perm.init(data_id.asUUID(), owner_id, LLUUID::null, LLUUID::null);
|
||||
item->setPermissions(perm);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPermissions default_perm;
|
||||
default_perm.init(LLUUID::null, owner_id, LLUUID::null, LLUUID::null);
|
||||
LLSD llsd_perm_mask = (*it)["perm_mask"];
|
||||
if(llsd_perm_mask.isDefined())
|
||||
{
|
||||
PermissionMask perm_mask = llsd_perm_mask.asInteger();
|
||||
default_perm.initMasks(
|
||||
perm_mask, perm_mask, perm_mask, perm_mask, perm_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
default_perm.initMasks(
|
||||
PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE);
|
||||
}
|
||||
item->setPermissions(default_perm);
|
||||
item->setAssetUUID(data_id.asUUID());
|
||||
}
|
||||
|
||||
LLSD flags = (*it)["flags"];
|
||||
if(flags.isDefined())
|
||||
{
|
||||
// Not sure how well LLSD.asInteger() maps to
|
||||
// unsigned long - using strtoul()
|
||||
item->setFlags(strtoul(flags.asString().c_str(), NULL, 0));
|
||||
}
|
||||
|
||||
LLSD time = (*it)["time"];
|
||||
if(time.isDefined())
|
||||
{
|
||||
item->setCreationDate(time.asInteger());
|
||||
}
|
||||
addItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
meat = (*it).find("perm_mask");
|
||||
if(meat != no_response)
|
||||
{
|
||||
PermissionMask perm_mask = atoi((*meat).second.c_str());
|
||||
default_perm.initMasks(
|
||||
perm_mask, perm_mask, perm_mask, perm_mask, perm_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
default_perm.initMasks(
|
||||
PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE);
|
||||
}
|
||||
item->setPermissions(default_perm);
|
||||
item->setAssetUUID(id);
|
||||
llwarns << "Unable to import near " << name.asString() << llendl;
|
||||
rv = false;
|
||||
}
|
||||
meat = (*it).find("flags");
|
||||
if(meat != no_response)
|
||||
{
|
||||
item->setFlags(strtoul((*meat).second.c_str(), NULL, 0));
|
||||
}
|
||||
meat = (*it).find("time");
|
||||
if(meat != no_response)
|
||||
{
|
||||
item->setCreationDate(atoi((*meat).second.c_str()));
|
||||
}
|
||||
addItem(item);
|
||||
continue;
|
||||
clean_item:
|
||||
llwarns << "Unable to import near " << item->getName() << llendl;
|
||||
rv = false;
|
||||
//delete item; // automatic when item is reassigned or destroyed
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include "lluictrlfactory.h"
|
||||
#include "llweb.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsdutil_math.h"
|
||||
|
||||
static LLRegisterPanelClassWrapper<LLPanelPlaceInfo> t_places("panel_landmark_info");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue