summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llassettype.cpp1
-rw-r--r--indra/llcommon/llassettype.h3
-rw-r--r--indra/llcommon/llavatarname.cpp131
-rw-r--r--indra/llcommon/llavatarname.h60
-rw-r--r--indra/llcommon/llhandle.h13
-rw-r--r--indra/llcommon/llinitparam.cpp82
-rw-r--r--indra/llcommon/llinitparam.h1657
-rw-r--r--indra/llcommon/llinstancetracker.h5
-rw-r--r--indra/llcommon/llrefcount.h19
-rw-r--r--indra/llcommon/llregistry.h4
-rw-r--r--indra/llcommon/llsdparam.cpp51
-rw-r--r--indra/llcommon/llthread.h17
-rw-r--r--indra/llcommon/llversionviewer.h4
-rw-r--r--indra/llcommon/stdenums.h3
14 files changed, 1320 insertions, 730 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 5e566d6c7c..5ae2df3994 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -95,6 +95,7 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
+ addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
};
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index d538accbf7..69b01731e5 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -112,6 +112,9 @@ public:
AT_WIDGET = 40,
// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
+ AT_PERSON = 45,
+ // A user uuid which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
+
AT_MESH = 49,
// Mesh data in our proprietary SLM format
diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index 3206843bf4..642bd82e90 100644
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -30,6 +30,7 @@
#include "llavatarname.h"
#include "lldate.h"
+#include "llframetimer.h"
#include "llsd.h"
// Store these in pre-built std::strings to avoid memory allocations in
@@ -42,6 +43,14 @@ static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default");
static const std::string DISPLAY_NAME_EXPIRES("display_name_expires");
static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
+bool LLAvatarName::sUseDisplayNames = true;
+
+// Minimum time-to-live (in seconds) for a name entry.
+// Avatar name should always guarantee to expire reasonably soon by default
+// so if the failure to get a valid expiration time was due to something temporary
+// we will eventually request and get the right data.
+const F64 MIN_ENTRY_LIFETIME = 60.0;
+
LLAvatarName::LLAvatarName()
: mUsername(),
mDisplayName(),
@@ -61,6 +70,17 @@ bool LLAvatarName::operator<(const LLAvatarName& rhs) const
return mUsername < rhs.mUsername;
}
+//static
+void LLAvatarName::setUseDisplayNames(bool use)
+{
+ sUseDisplayNames = use;
+}
+//static
+bool LLAvatarName::useDisplayNames()
+{
+ return sUseDisplayNames;
+}
+
LLSD LLAvatarName::asLLSD() const
{
LLSD sd;
@@ -85,21 +105,75 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
mExpires = expires.secondsSinceEpoch();
LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE];
mNextUpdate = next_update.secondsSinceEpoch();
+
+ // Some avatars don't have explicit display names set. Force a legible display name here.
+ if (mDisplayName.empty())
+ {
+ mDisplayName = mUsername;
+ }
+}
+
+// Transform a string (typically provided by the legacy service) into a decent
+// avatar name instance.
+void LLAvatarName::fromString(const std::string& full_name)
+{
+ mDisplayName = full_name;
+ std::string::size_type index = full_name.find(' ');
+ if (index != std::string::npos)
+ {
+ // The name is in 2 parts (first last)
+ mLegacyFirstName = full_name.substr(0, index);
+ mLegacyLastName = full_name.substr(index+1);
+ if (mLegacyLastName != "Resident")
+ {
+ mUsername = mLegacyFirstName + "." + mLegacyLastName;
+ mDisplayName = full_name;
+ LLStringUtil::toLower(mUsername);
+ }
+ else
+ {
+ // Very old names do have a dummy "Resident" last name
+ // that we choose to hide from users.
+ mUsername = mLegacyFirstName;
+ mDisplayName = mLegacyFirstName;
+ }
+ }
+ else
+ {
+ mLegacyFirstName = full_name;
+ mLegacyLastName = "";
+ mUsername = full_name;
+ mDisplayName = full_name;
+ }
+ mIsDisplayNameDefault = true;
+ mIsTemporaryName = true;
+ setExpires(MIN_ENTRY_LIFETIME);
+}
+
+void LLAvatarName::setExpires(F64 expires)
+{
+ mExpires = LLFrameTimer::getTotalSeconds() + expires;
}
std::string LLAvatarName::getCompleteName() const
{
std::string name;
- if (mUsername.empty() || mIsDisplayNameDefault)
- // If the display name feature is off
- // OR this particular display name is defaulted (i.e. based on user name),
- // then display only the easier to read instance of the person's name.
+ if (sUseDisplayNames)
{
- name = mDisplayName;
+ if (mUsername.empty() || mIsDisplayNameDefault)
+ {
+ // If this particular display name is defaulted (i.e. based on user name),
+ // then display only the easier to read instance of the person's name.
+ name = mDisplayName;
+ }
+ else
+ {
+ name = mDisplayName + " (" + mUsername + ")";
+ }
}
else
{
- name = mDisplayName + " (" + mUsername + ")";
+ name = getUserName();
}
return name;
}
@@ -118,3 +192,48 @@ std::string LLAvatarName::getLegacyName() const
name += mLegacyLastName;
return name;
}
+
+std::string LLAvatarName::getDisplayName() const
+{
+ if (sUseDisplayNames)
+ {
+ return mDisplayName;
+ }
+ else
+ {
+ return getUserName();
+ }
+}
+
+std::string LLAvatarName::getUserName() const
+{
+ std::string name;
+ if (mLegacyLastName.empty() || (mLegacyLastName == "Resident"))
+ {
+ if (mLegacyFirstName.empty())
+ {
+ // If we cannot create a user name from the legacy strings, use the display name
+ name = mDisplayName;
+ }
+ else
+ {
+ // The last name might be empty if it defaulted to "Resident"
+ name = mLegacyFirstName;
+ }
+ }
+ else
+ {
+ name = mLegacyFirstName + " " + mLegacyLastName;
+ }
+ return name;
+}
+
+void LLAvatarName::dump() const
+{
+ LL_DEBUGS("AvNameCache") << "LLAvatarName: "
+ << "user '" << mUsername << "' "
+ << "display '" << mDisplayName << "' "
+ << "expires in " << mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
+ << LL_ENDL;
+}
+
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index ba258d6d52..7542a8dece 100644
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -39,10 +39,27 @@ public:
bool operator<(const LLAvatarName& rhs) const;
+ // Conversion to and from LLSD (cache file or server response)
LLSD asLLSD() const;
-
void fromLLSD(const LLSD& sd);
+ // Used only in legacy mode when the display name capability is not provided server side
+ // or to otherwise create a temporary valid item.
+ void fromString(const std::string& full_name);
+
+ // Set the name object to become invalid in "expires" seconds from now
+ void setExpires(F64 expires);
+
+ // Set and get the display name flag set by the user in preferences.
+ static void setUseDisplayNames(bool use);
+ static bool useDisplayNames();
+
+ // A name object is valid if not temporary and not yet expired (default is expiration not checked)
+ bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); }
+
+ // Return true if the name is made up from legacy or temporary data
+ bool isDisplayNameDefault() const { return mIsDisplayNameDefault; }
+
// For normal names, returns "James Linden (james.linden)"
// When display names are disabled returns just "James Linden"
std::string getCompleteName() const;
@@ -51,11 +68,38 @@ public:
// compatibility with systems like voice and muting
// *TODO: Eliminate this in favor of username only
std::string getLegacyName() const;
+
+ // "José Sanchez" or "James Linden", UTF-8 encoded Unicode
+ // Takes the display name preference into account. This is truly the name that should
+ // be used for all UI where an avatar name has to be used unless we truly want something else (rare)
+ std::string getDisplayName() const;
+
+ // Returns "James Linden" or "bobsmith123 Resident"
+ // Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name
+ // Also used for backwards compatibility with systems like voice and muting
+ std::string getUserName() const;
+
+ // Returns "james.linden" or the legacy name for very old names
+ std::string getAccountName() const { return mUsername; }
+ // Debug print of the object
+ void dump() const;
+
+ // Names can change, so need to keep track of when name was
+ // last checked.
+ // Unix time-from-epoch seconds for efficiency
+ F64 mExpires;
+
+ // You can only change your name every N hours, so record
+ // when the next update is allowed
+ // Unix time-from-epoch seconds
+ F64 mNextUpdate;
+
+private:
// "bobsmith123" or "james.linden", US-ASCII only
std::string mUsername;
- // "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode
+ // "José Sanchez" or "James Linden", UTF-8 encoded Unicode
// Contains data whether or not user has explicitly set
// a display name; may duplicate their username.
std::string mDisplayName;
@@ -81,15 +125,9 @@ public:
// shown in UI, but are not serialized.
bool mIsTemporaryName;
- // Names can change, so need to keep track of when name was
- // last checked.
- // Unix time-from-epoch seconds for efficiency
- F64 mExpires;
-
- // You can only change your name every N hours, so record
- // when the next update is allowed
- // Unix time-from-epoch seconds
- F64 mNextUpdate;
+ // Global flag indicating if display name should be used or not
+ // This will affect the output of the high level "get" methods
+ static bool sUseDisplayNames;
};
#endif
diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h
index 6af5e198d6..401e4d759a 100644
--- a/indra/llcommon/llhandle.h
+++ b/indra/llcommon/llhandle.h
@@ -194,13 +194,6 @@ public:
return mHandle;
}
-protected:
- typedef LLHandle<T> handle_type_t;
- LLHandleProvider()
- {
- // provided here to enforce T deriving from LLHandleProvider<T>
- }
-
template <typename U>
LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
{
@@ -209,6 +202,12 @@ protected:
return downcast_handle;
}
+protected:
+ typedef LLHandle<T> handle_type_t;
+ LLHandleProvider()
+ {
+ // provided here to enforce T deriving from LLHandleProvider<T>
+ }
private:
mutable LLRootHandle<T> mHandle;
diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index db72aa19b9..89c831d296 100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -40,7 +40,9 @@ namespace LLInitParam
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
- mEnclosingBlockOffset = 0x7FFFffff & (U32)(my_addr - block_addr);
+ U32 enclosing_block_offset = 0x7FFFffff & (U32)(my_addr - block_addr);
+ mEnclosingBlockOffsetLow = enclosing_block_offset & 0x0000ffff;
+ mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;
}
//
@@ -112,6 +114,35 @@ namespace LLInitParam
std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
}
+ void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name)
+ {
+ // create a copy of the param descriptor in mAllParams
+ // so other data structures can store a pointer to it
+ mAllParams.push_back(in_param);
+ ParamDescriptorPtr param(mAllParams.back());
+
+ std::string name(char_name);
+ if ((size_t)param->mParamHandle > mMaxParamOffset)
+ {
+ llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
+ }
+
+ if (name.empty())
+ {
+ mUnnamedParams.push_back(param);
+ }
+ else
+ {
+ // don't use insert, since we want to overwrite existing entries
+ mNamedParams[name] = param;
+ }
+
+ if (param->mValidationFunc)
+ {
+ mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
+ }
+ }
+
BlockDescriptor::BlockDescriptor()
: mMaxParamOffset(0),
mInitializationState(UNINITIALIZED),
@@ -150,7 +181,8 @@ namespace LLInitParam
bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)
{
- if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true))
+ Parser::name_stack_range_t range = std::make_pair(name_stack.begin(), name_stack.end());
+ if (!deserializeBlock(p, range, true))
{
if (!silent)
{
@@ -196,12 +228,7 @@ namespace LLInitParam
if (serialize_func)
{
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
- // each param descriptor remembers its serial number
- // so we can inspect the same param under different names
- // and see that it has the same number
- name_stack.push_back(std::make_pair("", true));
serialize_func(*param, parser, name_stack, diff_param);
- name_stack.pop_back();
}
}
@@ -295,7 +322,7 @@ namespace LLInitParam
return true;
}
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored)
+ bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool ignored)
{
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
bool names_left = name_stack_range.first != name_stack_range.second;
@@ -308,15 +335,12 @@ namespace LLInitParam
{
const std::string& top_name = name_stack_range.first->first;
- ParamDescriptor::deserialize_func_t deserialize_func = NULL;
- Param* paramp = NULL;
-
BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
if (found_it != block_data.mNamedParams.end())
{
// find pointer to member parameter from offset table
- paramp = getParamFromHandle(found_it->second->mParamHandle);
- deserialize_func = found_it->second->mDeserializeFunc;
+ Param* paramp = getParamFromHandle(found_it->second->mParamHandle);
+ ParamDescriptor::deserialize_func_t deserialize_func = found_it->second->mDeserializeFunc;
Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);
++new_name_stack.first;
@@ -358,36 +382,6 @@ namespace LLInitParam
return false;
}
- //static
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
- {
- // create a copy of the param descriptor in mAllParams
- // so other data structures can store a pointer to it
- block_data.mAllParams.push_back(in_param);
- ParamDescriptorPtr param(block_data.mAllParams.back());
-
- std::string name(char_name);
- if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
- {
- llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
- }
-
- if (name.empty())
- {
- block_data.mUnnamedParams.push_back(param);
- }
- else
- {
- // don't use insert, since we want to overwrite existing entries
- block_data.mNamedParams[name] = param;
- }
-
- if (param->mValidationFunc)
- {
- block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
- }
- }
-
void BaseBlock::addSynonym(Param& param, const std::string& synonym)
{
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
@@ -460,7 +454,7 @@ namespace LLInitParam
if (merge_func)
{
Param* paramp = getParamFromHandle((*it)->mParamHandle);
- llassert(paramp->mEnclosingBlockOffset == (*it)->mParamHandle);
+ llassert(paramp->getEnclosingBlockOffset() == (*it)->mParamHandle);
some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
}
}
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 0dd6030fa2..ae836645b9 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -38,6 +38,71 @@
#include "llerror.h"
#include "llstl.h"
+namespace LLTypeTags
+{
+ template <typename INNER_TYPE, int _SORT_ORDER>
+ struct TypeTagBase
+ {
+ typedef void is_tag_t;
+ typedef INNER_TYPE inner_t;
+ static const int SORT_ORDER=_SORT_ORDER;
+ };
+
+ template <int VAL1, int VAL2>
+ struct GreaterThan
+ {
+ static const bool value = VAL1 > VAL2;
+ };
+
+ template<typename ITEM, typename REST, bool NEEDS_SWAP = GreaterThan<ITEM::SORT_ORDER, REST::SORT_ORDER>::value >
+ struct Swap
+ {
+ typedef typename ITEM::template Cons<REST>::value_t value_t;
+ };
+
+ template<typename ITEM, typename REST>
+ struct Swap<ITEM, REST, true>
+ {
+ typedef typename REST::template Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t;
+ };
+
+ template<typename T, typename SORTABLE = void>
+ struct IsSortable
+ {
+ static const bool value = false;
+ };
+
+ template<typename T>
+ struct IsSortable<T, typename T::is_tag_t>
+ {
+ static const bool value = true;
+ };
+
+ template<typename ITEM, typename REST, bool IS_REST_SORTABLE = IsSortable<REST>::value>
+ struct InsertInto
+ {
+ typedef typename ITEM::template Cons<REST>::value_t value_t;
+ };
+
+ template<typename ITEM, typename REST>
+ struct InsertInto <ITEM, REST, true>
+ {
+ typedef typename Swap<ITEM, REST>::value_t value_t;
+ };
+
+ template<typename T, bool SORTABLE = IsSortable<T>::value>
+ struct Sorted
+ {
+ typedef T value_t;
+ };
+
+ template<typename T>
+ struct Sorted <T, true>
+ {
+ typedef typename InsertInto<T, typename Sorted<typename T::inner_t>::value_t>::value_t value_t;
+ };
+}
+
namespace LLInitParam
{
// used to indicate no matching value to a given name when parsing
@@ -45,6 +110,8 @@ namespace LLInitParam
template<typename T> const T& defaultValue() { static T value; return value; }
+ // wraps comparison operator between any 2 values of the same type
+ // specialize to handle cases where equality isn't defined well, or at all
template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
struct ParamCompare
{
@@ -79,24 +146,123 @@ namespace LLInitParam
// helper functions and classes
typedef ptrdiff_t param_handle_t;
+ struct IS_A_BLOCK {};
+ struct NOT_BLOCK {};
+
+ // these templates allow us to distinguish between template parameters
+ // that derive from BaseBlock and those that don't
+ template<typename T, typename BLOCK_IDENTIFIER = void>
+ struct IsBlock
+ {
+ typedef NOT_BLOCK value_t;
+ };
+
+ template<typename T>
+ struct IsBlock<T, typename T::baseblock_base_class_t>
+ {
+ typedef IS_A_BLOCK value_t;
+ };
+
+ // ParamValue class directly manages the wrapped value
+ // by holding on to a copy (scalar params)
+ // or deriving from it (blocks)
+ // has specializations for custom value behavior
+ // and "tag" values like Lazy and Atomic
+ template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
+ class ParamValue
+ {
+ typedef ParamValue<T, VALUE_IS_BLOCK> self_t;
+
+ public:
+ typedef T default_value_t;
+ typedef T value_t;
+
+ ParamValue(): mValue() {}
+ ParamValue(const default_value_t& other) : mValue(other) {}
+
+ void setValue(const value_t& val)
+ {
+ mValue = val;
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue;
+ }
+
+ T& getValue()
+ {
+ return mValue;
+ }
+
+ protected:
+ T mValue;
+ };
+
+ template<typename T>
+ class ParamValue<T, IS_A_BLOCK>
+ : public T
+ {
+ typedef ParamValue<T, IS_A_BLOCK> self_t;
+ public:
+ typedef T default_value_t;
+ typedef T value_t;
+
+ ParamValue()
+ : T(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& other)
+ : T(other),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
+ {
+ *this = val;
+ }
+
+ const value_t& getValue() const
+ {
+ return *this;
+ }
+
+ T& getValue()
+ {
+ return *this;
+ }
+
+ protected:
+ mutable bool mValidated; // lazy validation flag
+ };
+
// empty default implementation of key cache
// leverages empty base class optimization
template <typename T>
class TypeValues
+ : public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
{
private:
struct Inaccessable{};
public:
typedef std::map<std::string, T> value_name_map_t;
typedef Inaccessable name_t;
+ typedef TypeValues<T> type_value_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::value_t value_t;
+
+ TypeValues(const typename param_value_t::value_t& val)
+ : param_value_t(val)
+ {}
void setValueName(const std::string& key) {}
std::string getValueName() const { return ""; }
- std::string calcValueName(const T& value) const { return ""; }
+ std::string calcValueName(const value_t& value) const { return ""; }
void clearValueName() const {}
- static bool getValueFromName(const std::string& name, T& value)
+ static bool getValueFromName(const std::string& name, value_t& value)
{
return false;
}
@@ -111,15 +277,39 @@ namespace LLInitParam
return NULL;
}
+ void assignNamedValue(const Inaccessable& name)
+ {}
+
+ operator const value_t&() const
+ {
+ return param_value_t::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return param_value_t::getValue();
+ }
+
static value_name_map_t* getValueNames() {return NULL;}
};
- template <typename T, typename DERIVED_TYPE = TypeValues<T> >
+ // helper class to implement name value lookups
+ // and caching of last used name
+ template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >
class TypeValuesHelper
+ : public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
{
+ typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;
public:
typedef typename std::map<std::string, T> value_name_map_t;
typedef std::string name_t;
+ typedef self_t type_value_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::value_t value_t;
+
+ TypeValuesHelper(const typename param_value_t::value_t& val)
+ : param_value_t(val)
+ {}
//TODO: cache key by index to save on param block size
void setValueName(const std::string& value_name)
@@ -132,7 +322,7 @@ namespace LLInitParam
return mValueName;
}
- std::string calcValueName(const T& value) const
+ std::string calcValueName(const value_t& value) const
{
value_name_map_t* map = getValueNames();
for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
@@ -153,7 +343,7 @@ namespace LLInitParam
mValueName.clear();
}
- static bool getValueFromName(const std::string& name, T& value)
+ static bool getValueFromName(const std::string& name, value_t& value)
{
value_name_map_t* map = getValueNames();
typename value_name_map_t::iterator found_it = map->find(name);
@@ -195,18 +385,90 @@ namespace LLInitParam
return &sValues;
}
- static void declare(const std::string& name, const T& value)
+ static void declare(const std::string& name, const value_t& value)
{
(*getValueNames())[name] = value;
}
+ void operator ()(const std::string& name)
+ {
+ *this = name;
+ }
+
+ void assignNamedValue(const std::string& name)
+ {
+ if (getValueFromName(name, param_value_t::getValue()))
+ {
+ setValueName(name);
+ }
+ }
+
+ operator const value_t&() const
+ {
+ return param_value_t::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return param_value_t::getValue();
+ }
+
protected:
- static void getName(const std::string& name, const T& value)
+ static void getName(const std::string& name, const value_t& value)
{}
mutable std::string mValueName;
};
+ // string types can support custom named values, but need
+ // to disambiguate in code between a string that is a named value
+ // and a string that is a name
+ template <typename DERIVED_TYPE>
+ class TypeValuesHelper<std::string, DERIVED_TYPE, true>
+ : public TypeValuesHelper<std::string, DERIVED_TYPE, false>
+ {
+ public:
+ typedef TypeValuesHelper<std::string, DERIVED_TYPE, true> self_t;
+ typedef TypeValuesHelper<std::string, DERIVED_TYPE, false> base_t;
+ typedef std::string value_t;
+ typedef std::string name_t;
+ typedef self_t type_value_t;
+
+ TypeValuesHelper(const std::string& val)
+ : TypeValuesHelper(val)
+ {}
+
+ void operator ()(const std::string& name)
+ {
+ *this = name;
+ }
+
+ self_t& operator =(const std::string& name)
+ {
+ if (base_t::getValueFromName(name, ParamValue<std::string>::getValue()))
+ {
+ base_t::setValueName(name);
+ }
+ else
+ {
+ ParamValue<std::string>::setValue(name);
+ }
+ return *this;
+ }
+
+ operator const value_t&() const
+ {
+ return ParamValue<std::string>::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return ParamValue<std::string>::getValue();
+ }
+
+ };
+
+ // parser base class with mechanisms for registering readers/writers/inspectors of different types
class LL_COMMON_API Parser
{
LOG_CLASS(Parser);
@@ -223,82 +485,58 @@ namespace LLInitParam
typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
- private:
- template<typename T, bool is_enum = boost::is_enum<T>::value>
- struct ReaderWriter
- {
- static bool read(T& param, Parser* parser)
+ public:
+
+ Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
+ : mParseSilently(false),
+ mParserReadFuncs(&read_map),
+ mParserWriteFuncs(&write_map),
+ mParserInspectFuncs(&inspect_map)
+ {}
+
+ virtual ~Parser();
+
+ template <typename T> bool readValue(T& param, typename boost::disable_if<boost::is_enum<T> >::type* dummy = 0)
{
- parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(T));
- if (found_it != parser->mParserReadFuncs->end())
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+ if (found_it != mParserReadFuncs->end())
{
- return found_it->second(*parser, (void*)&param);
+ return found_it->second(*this, (void*)&param);
}
+
return false;
}
- static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
+ template <typename T> bool readValue(T& param, typename boost::enable_if<boost::is_enum<T> >::type* dummy = 0)
{
- parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(T));
- if (found_it != parser->mParserWriteFuncs->end())
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+ if (found_it != mParserReadFuncs->end())
{
- return found_it->second(*parser, (const void*)&param, name_stack);
+ return found_it->second(*this, (void*)&param);
}
- return false;
- }
- };
-
- // read enums as ints
- template<typename T>
- struct ReaderWriter<T, true>
+ else
{
- static bool read(T& param, Parser* parser)
- {
- // read all enums as ints
- parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32));
- if (found_it != parser->mParserReadFuncs->end())
+ found_it = mParserReadFuncs->find(&typeid(S32));
+ if (found_it != mParserReadFuncs->end())
{
- S32 value;
- if (found_it->second(*parser, (void*)&value))
- {
- param = (T)value;
- return true;
+ S32 int_value;
+ bool parsed = found_it->second(*this, (void*)&int_value);
+ param = (T)int_value;
+ return parsed;
}
}
return false;
}
- static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
+ template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
{
- parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(S32));
- if (found_it != parser->mParserWriteFuncs->end())
+ parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
+ if (found_it != mParserWriteFuncs->end())
{
- return found_it->second(*parser, (const void*)&param, name_stack);
+ return found_it->second(*this, (const void*)&param, name_stack);
}
return false;
}
- };
-
- public:
-
- Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
- : mParseSilently(false),
- mParserReadFuncs(&read_map),
- mParserWriteFuncs(&write_map),
- mParserInspectFuncs(&inspect_map)
- {}
-
- virtual ~Parser();
-
- template <typename T> bool readValue(T& param)
- {
- return ReaderWriter<T>::read(param, this);
- }
-
- template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
- {
- return ReaderWriter<T>::write(param, this, name_stack);
- }
// dispatch inspection to registered inspection functions, for each parameter in a param block
template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
@@ -350,7 +588,7 @@ namespace LLInitParam
};
typedef bool(*merge_func_t)(Param&, const Param&, bool);
- typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool);
+ typedef bool(*deserialize_func_t)(Param&, Parser&, Parser::name_stack_range_t&, bool);
typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
typedef bool(*validation_func_t)(const Param*);
@@ -395,6 +633,7 @@ namespace LLInitParam
} EInitializationState;
void aggregateBlockData(BlockDescriptor& src_block_data);
+ void addParam(ParamDescriptorPtr param, const char* name);
typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
typedef std::vector<ParamDescriptorPtr> param_list_t;
@@ -410,48 +649,58 @@ namespace LLInitParam
class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
};
- class LL_COMMON_API BaseBlock
- {
- public:
//TODO: implement in terms of owned_ptr
template<typename T>
- class Lazy
+ class LazyValue
{
public:
- Lazy()
+ LazyValue()
: mPtr(NULL)
{}
- ~Lazy()
+ ~LazyValue()
{
delete mPtr;
}
- Lazy(const Lazy& other)
+ LazyValue(const T& value)
{
- if (other.mPtr)
+ mPtr = new T(value);
+ }
+
+ LazyValue(const LazyValue& other)
+ : mPtr(NULL)
{
- mPtr = new T(*other.mPtr);
+ *this = other;
}
- else
+
+ LazyValue& operator = (const LazyValue& other)
{
+ if (!other.mPtr)
+ {
+ delete mPtr;
mPtr = NULL;
}
- }
-
- Lazy<T>& operator = (const Lazy<T>& other)
+ else
{
- if (other.mPtr)
+ if (!mPtr)
{
mPtr = new T(*other.mPtr);
}
else
{
- mPtr = NULL;
+ *mPtr = *(other.mPtr);
+ }
}
return *this;
}
+ bool operator==(const LazyValue& other) const
+ {
+ if (empty() || other.empty()) return false;
+ return *mPtr == *other.mPtr;
+ }
+
bool empty() const
{
return mPtr == NULL;
@@ -459,18 +708,29 @@ namespace LLInitParam
void set(const T& other)
{
- delete mPtr;
+ if (!mPtr)
+ {
mPtr = new T(other);
}
+ else
+ {
+ *mPtr = other;
+ }
+ }
const T& get() const
{
- return ensureInstance();
+ return *ensureInstance();
}
T& get()
{
- return ensureInstance();
+ return *ensureInstance();
+ }
+
+ operator const T&() const
+ {
+ return get();
}
private:
@@ -485,13 +745,50 @@ namespace LLInitParam
}
private:
- // if you get a compilation error with this, that means you are using a forward declared struct for T
- // unfortunately, the type traits we rely on don't work with forward declared typed
- //static const int dummy = sizeof(T);
mutable T* mPtr;
};
+ // root class of all parameter blocks
+
+ class LL_COMMON_API BaseBlock
+ {
+ public:
+ // lift block tags into baseblock namespace so derived classes do not need to qualify them
+ typedef LLInitParam::IS_A_BLOCK IS_A_BLOCK;
+ typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK;
+
+ template<typename T>
+ struct Sequential : public LLTypeTags::TypeTagBase<T, 2>
+ {
+ template <typename S> struct Cons { typedef Sequential<ParamValue<S> > value_t; };
+ template <typename S> struct Cons<Sequential<S> > { typedef Sequential<S> value_t; };
+ };
+
+ template<typename T>
+ struct Atomic : public LLTypeTags::TypeTagBase<T, 1>
+ {
+ template <typename S> struct Cons { typedef Atomic<ParamValue<S> > value_t; };
+ template <typename S> struct Cons<Atomic<S> > { typedef Atomic<S> value_t; };
+ };
+
+ template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
+ struct Lazy : public LLTypeTags::TypeTagBase<T, 0>
+ {
+ template <typename S> struct Cons
+ {
+ typedef Lazy<ParamValue<S, BLOCK_T>, BLOCK_T> value_t;
+ };
+ template <typename S> struct Cons<Lazy<S, IS_A_BLOCK> >
+ {
+ typedef Lazy<S, IS_A_BLOCK> value_t;
+ };
+ template <typename S> struct Cons<Lazy<S, NOT_A_BLOCK> >
+ {
+ typedef Lazy<S, BLOCK_T> value_t;
+ };
+ };
+
// "Multiple" constraint types, put here in root class to avoid ambiguity during use
struct AnyAmount
{
@@ -557,12 +854,12 @@ namespace LLInitParam
// Blocks can override this to do custom tracking of changes
virtual void paramChanged(const Param& changed_param, bool user_provided) {}
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
// take all provided params from other and apply to self
bool overwriteFrom(const BaseBlock& other)
@@ -576,10 +873,17 @@ namespace LLInitParam
return false;
}
- static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name);
-
ParamDescriptorPtr findParamDescriptor(const Param& param);
+ // take all provided params from other and apply to self
+ bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ static BlockDescriptor sBlockDescriptor;
+ return sBlockDescriptor;
+ }
+
protected:
void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
@@ -588,25 +892,11 @@ namespace LLInitParam
{
return mergeBlock(block_data, source, overwrite);
}
- // take all provided params from other and apply to self
- bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
-
- static BlockDescriptor& selfBlockDescriptor()
- {
- static BlockDescriptor sBlockDescriptor;
- return sBlockDescriptor;
- }
private:
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
};
- template<typename T>
- struct ParamCompare<BaseBlock::Lazy<T>, false >
- {
- static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
- };
-
class LL_COMMON_API Param
{
public:
@@ -635,256 +925,68 @@ namespace LLInitParam
// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
return *const_cast<BaseBlock*>
(reinterpret_cast<const BaseBlock*>
- (my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
- }
-
- private:
- friend class BaseBlock;
-
- U32 mEnclosingBlockOffset:31;
- U32 mIsProvided:1;
-
- };
-
- // these templates allow us to distinguish between template parameters
- // that derive from BaseBlock and those that don't
- template<typename T, typename Void = void>
- struct IsBlock
- {
- static const bool value = false;
- struct EmptyBase {};
- typedef EmptyBase base_class_t;
- };
-
- template<typename T>
- struct IsBlock<T, typename T::baseblock_base_class_t>
- {
- static const bool value = true;
- typedef BaseBlock base_class_t;
- };
-
- template<typename T>
- struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t >
- {
- static const bool value = true;
- typedef BaseBlock base_class_t;
- };
-
- template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
- class ParamValue : public NAME_VALUE_LOOKUP
- {
- public:
- typedef const T& value_assignment_t;
- typedef T value_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK> self_t;
-
- ParamValue(): mValue() {}
- ParamValue(value_assignment_t other) : mValue(other) {}
-
- void setValue(value_assignment_t val)
- {
- mValue = val;
- }
-
- value_assignment_t getValue() const
- {
- return mValue;
- }
-
- T& getValue()
- {
- return mValue;
- }
-
- operator value_assignment_t() const
- {
- return mValue;
- }
-
- value_assignment_t operator()() const
- {
- return mValue;
- }
-
- void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- *this = name;
- }
-
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue))
- {
- setValueName(name);
- }
-
- return *this;
- }
-
- protected:
- T mValue;
- };
-
- template<typename T, typename NAME_VALUE_LOOKUP>
- class ParamValue<T, NAME_VALUE_LOOKUP, true>
- : public T,
- public NAME_VALUE_LOOKUP
- {
- public:
- typedef const T& value_assignment_t;
- typedef T value_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP, true> self_t;
-
- ParamValue()
- : T(),
- mValidated(false)
- {}
-
- ParamValue(value_assignment_t other)
- : T(other),
- mValidated(false)
- {}
-
- void setValue(value_assignment_t val)
- {
- *this = val;
- }
-
- value_assignment_t getValue() const
- {
- return *this;
- }
-
- T& getValue()
- {
- return *this;
- }
-
- operator value_assignment_t() const
- {
- return *this;
- }
-
- value_assignment_t operator()() const
- {
- return *this;
- }
-
- void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- *this = name;
- }
-
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(name, *this))
- {
- setValueName(name);
- }
-
- return *this;
+ (my_addr - (ptrdiff_t)getEnclosingBlockOffset()));
}
- protected:
- mutable bool mValidated; // lazy validation flag
- };
-
- template<typename NAME_VALUE_LOOKUP>
- class ParamValue<std::string, NAME_VALUE_LOOKUP, false>
- : public NAME_VALUE_LOOKUP
+ U32 getEnclosingBlockOffset() const
{
- public:
- typedef const std::string& value_assignment_t;
- typedef std::string value_t;
- typedef ParamValue<std::string, NAME_VALUE_LOOKUP, false> self_t;
-
- ParamValue(): mValue() {}
- ParamValue(value_assignment_t other) : mValue(other) {}
-
- void setValue(value_assignment_t val)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue))
- {
- NAME_VALUE_LOOKUP::setValueName(val);
- }
- else
- {
- mValue = val;
- }
- }
-
- value_assignment_t getValue() const
- {
- return mValue;
- }
-
- std::string& getValue()
- {
- return mValue;
+ return ((U32)mEnclosingBlockOffsetHigh << 16) | (U32)mEnclosingBlockOffsetLow;
}
- operator value_assignment_t() const
- {
- return mValue;
- }
+ private:
+ friend class BaseBlock;
- value_assignment_t operator()() const
- {
- return mValue;
- }
+ //24 bits for member offset field and 1 bit for provided flag
+ U16 mEnclosingBlockOffsetLow;
+ U8 mEnclosingBlockOffsetHigh:7;
+ U8 mIsProvided:1;
- protected:
- std::string mValue;
};
-
template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
struct ParamIterator
{
- typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator const_iterator;
- typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator iterator;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::const_iterator const_iterator;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::iterator iterator;
};
- // specialize for custom parsing/decomposition of specific classes
- // e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
+ // wrapper for parameter with a known type
+ // specialized to handle 4 cases:
+ // simple "scalar" value
+ // parameter that is itself a block
+ // multiple scalar values, stored in a vector
+ // multiple blocks, stored in a vector
template<typename T,
typename NAME_VALUE_LOOKUP = TypeValues<T>,
bool HAS_MULTIPLE_VALUES = false,
- bool VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>
+ typename VALUE_IS_BLOCK = typename IsBlock<ParamValue<typename LLTypeTags::Sorted<T>::value_t> >::value_t>
class TypedParam
: public Param,
- public ParamValue<T, NAME_VALUE_LOOKUP>
+ public NAME_VALUE_LOOKUP::type_value_t
{
+ protected:
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::default_value_t default_value_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename param_value_t::value_assignment_t value_assignment_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
+ typedef typename param_value_t::value_t value_t;
- using param_value_t::operator();
+ using named_value_t::operator();
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ named_value_t(value)
{
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ init(block_descriptor, validate_func, min_count, max_count, name);
}
-
- setValue(value);
}
bool isProvided() const { return Param::anyProvided(); }
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
self_t& typed_param = static_cast<self_t&>(param);
// no further names in stack, attempt to parse value now
@@ -893,9 +995,9 @@ namespace LLInitParam
std::string name;
// try to parse a known named value
- if(name_value_lookup_t::valueNamesExist()
+ if(named_value_t::valueNamesExist()
&& parser.readValue(name)
- && name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+ && named_value_t::getValueFromName(name, typed_param.getValue()))
{
typed_param.setValueName(name);
typed_param.setProvided();
@@ -939,7 +1041,9 @@ namespace LLInitParam
if (!parser.writeValue(typed_param.getValue(), name_stack))
{
std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
- if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key))
+ if (calculated_key.size()
+ && (!diff_param
+ || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)))
{
parser.writeValue(calculated_key, name_stack);
}
@@ -952,22 +1056,23 @@ namespace LLInitParam
// tell parser about our actual type
parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
- if (name_value_lookup_t::getPossibleValues())
+ if (named_value_t::getPossibleValues())
{
- parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
}
}
- void set(value_assignment_t val, bool flag_as_provided = true)
+ void set(const value_t& val, bool flag_as_provided = true)
{
- param_value_t::clearValueName();
+ named_value_t::clearValueName();
setValue(val);
setProvided(flag_as_provided);
}
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+ self_t& operator =(const typename named_value_t::name_t& name)
{
- return static_cast<self_t&>(param_value_t::operator =(name));
+ named_value_t::assignNamedValue(name);
+ return *this;
}
protected:
@@ -992,41 +1097,47 @@ namespace LLInitParam
}
return false;
}
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
};
// parameter that is a block
template <typename T, typename NAME_VALUE_LOOKUP>
- class TypedParam<T, NAME_VALUE_LOOKUP, false, true>
+ class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>
: public Param,
- public ParamValue<T, NAME_VALUE_LOOKUP>
+ public NAME_VALUE_LOOKUP::type_value_t
{
+ protected:
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::default_value_t default_value_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> self_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
public:
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename param_value_t::value_assignment_t value_assignment_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true> self_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
-
- using param_value_t::operator();
+ using named_value_t::operator();
+ typedef typename param_value_t::value_t value_t;
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr),
- param_value_t(value)
+ named_value_t(value)
{
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ init(block_descriptor, validate_func, min_count, max_count, name);
}
}
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
self_t& typed_param = static_cast<self_t&>(param);
@@ -1034,9 +1145,9 @@ namespace LLInitParam
{ // try to parse a known named value
std::string name;
- if(name_value_lookup_t::valueNamesExist()
+ if(named_value_t::valueNamesExist()
&& parser.readValue(name)
- && name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+ && named_value_t::getValueFromName(name, typed_param.getValue()))
{
typed_param.setValueName(name);
typed_param.setProvided();
@@ -1068,9 +1179,9 @@ namespace LLInitParam
std::string key = typed_param.getValueName();
if (!key.empty())
{
- if (!parser.writeValue(key, name_stack))
+ if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
{
- return;
+ parser.writeValue(key, name_stack);
}
}
else
@@ -1081,8 +1192,16 @@ namespace LLInitParam
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
- // I am a param that is also a block, so just recurse into my contents
const self_t& typed_param = static_cast<const self_t&>(param);
+
+ // tell parser about our actual type
+ parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+ // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+ if (named_value_t::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+ }
+
typed_param.inspectBlock(parser, name_stack, min_count, max_count);
}
@@ -1100,32 +1219,34 @@ namespace LLInitParam
}
// assign block contents to this param-that-is-a-block
- void set(value_assignment_t val, bool flag_as_provided = true)
+ void set(const value_t& val, bool flag_as_provided = true)
{
setValue(val);
- param_value_t::clearValueName();
+ named_value_t::clearValueName();
// force revalidation of block
// next call to isProvided() will update provision status based on validity
param_value_t::mValidated = false;
setProvided(flag_as_provided);
}
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+ self_t& operator =(const typename named_value_t::name_t& name)
{
- return static_cast<self_t&>(param_value_t::operator =(name));
+ named_value_t::assignNamedValue(name);
+ return *this;
}
// propagate changed status up to enclosing block
/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
param_value_t::paramChanged(changed_param, user_provided);
+
if (user_provided)
{
// a child param has been explicitly changed
// so *some* aspect of this block is now provided
param_value_t::mValidated = false;
setProvided();
- param_value_t::clearValueName();
+ named_value_t::clearValueName();
}
else
{
@@ -1149,7 +1270,7 @@ namespace LLInitParam
if (src_typed_param.anyProvided())
{
- if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+ if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::getBlockDescriptor(), src_typed_param, overwrite))
{
dst_typed_param.clearValueName();
dst_typed_param.setProvided(true);
@@ -1158,56 +1279,72 @@ namespace LLInitParam
}
return false;
}
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
};
- // container of non-block parameters
+ // list of non-block parameters
template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>
+ class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>
: public Param
{
+ protected:
+ typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
+ typedef container_t default_value_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+
public:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename std::vector<param_value_t> container_t;
- typedef const container_t& value_assignment_t;
-
typedef typename param_value_t::value_t value_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr)
{
std::copy(value.begin(), value.end(), std::back_inserter(mValues));
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ init(block_descriptor, validate_func, min_count, max_count, name);
+
}
}
bool isProvided() const { return Param::anyProvided(); }
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
+ Parser::name_stack_range_t new_name_stack_range(name_stack_range);
self_t& typed_param = static_cast<self_t&>(param);
value_t value;
+
+ // pop first element if empty string
+ if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
+ {
+ ++new_name_stack_range.first;
+ }
+
// no further names in stack, attempt to parse value now
if (name_stack_range.first == name_stack_range.second)
{
std::string name;
// try to parse a known named value
- if(name_value_lookup_t::valueNamesExist()
+ if(named_value_t::valueNamesExist()
&& parser.readValue(name)
- && name_value_lookup_t::getValueFromName(name, value))
+ && named_value_t::getValueFromName(name, value))
{
typed_param.add(value);
typed_param.mValues.back().setValueName(name);
@@ -1225,14 +1362,14 @@ namespace LLInitParam
static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
{
const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided() || name_stack.empty()) return;
+ if (!typed_param.isProvided()) return;
for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
it != end_it;
++it)
{
std::string key = it->getValueName();
- name_stack.back().second = true;
+ name_stack.push_back(std::make_pair(std::string(), true));
if(key.empty())
// not parsed via name values, write out value directly
@@ -1254,19 +1391,21 @@ namespace LLInitParam
break;
}
}
+
+ name_stack.pop_back();
}
}
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
- if (name_value_lookup_t::getPossibleValues())
+ if (named_value_t::getPossibleValues())
{
- parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
}
}
- void set(value_assignment_t val, bool flag_as_provided = true)
+ void set(const container_t& val, bool flag_as_provided = true)
{
mValues = val;
setProvided(flag_as_provided);
@@ -1274,26 +1413,24 @@ namespace LLInitParam
param_value_t& add()
{
- mValues.push_back(param_value_t(value_t()));
+ mValues.push_back(value_t());
Param::setProvided();
return mValues.back();
}
self_t& add(const value_t& item)
{
- param_value_t param_value;
- param_value.setValue(item);
- mValues.push_back(param_value);
+ mValues.push_back(item);
setProvided();
return *this;
}
- self_t& add(const typename name_value_lookup_t::name_t& name)
+ self_t& add(const typename named_value_t::name_t& name)
{
value_t value;
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value))
+ if (named_value_t::getValueFromName(name, value))
{
add(value);
mValues.back().setValueName(name);
@@ -1303,9 +1440,9 @@ namespace LLInitParam
}
// implicit conversion
- operator value_assignment_t() const { return mValues; }
+ operator const container_t&() const { return mValues; }
// explicit conversion
- value_assignment_t operator()() const { return mValues; }
+ const container_t& operator()() const { return mValues; }
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
@@ -1346,62 +1483,79 @@ namespace LLInitParam
}
container_t mValues;
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
};
- // container of block parameters
+ // list of block parameters
template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>
+ class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>
: public Param
{
+ protected:
+ typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+ typedef container_t default_value_t;
+ typedef typename container_t::iterator iterator;
+ typedef typename container_t::const_iterator const_iterator;
public:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename std::vector<param_value_t> container_t;
- typedef const container_t& value_assignment_t;
typedef typename param_value_t::value_t value_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr)
{
std::copy(value.begin(), value.end(), back_inserter(mValues));
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ init(block_descriptor, validate_func, min_count, max_count, name);
}
}
bool isProvided() const { return Param::anyProvided(); }
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
+ Parser::name_stack_range_t new_name_stack_range(name_stack_range);
self_t& typed_param = static_cast<self_t&>(param);
bool new_value = false;
+ bool new_array_value = false;
- if (new_name || typed_param.mValues.empty())
+ // pop first element if empty string
+ if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
+ {
+ new_array_value = new_name_stack_range.first->second;
+ ++new_name_stack_range.first;
+ }
+
+ if (new_name || new_array_value || typed_param.mValues.empty())
{
new_value = true;
typed_param.mValues.push_back(value_t());
}
-
param_value_t& value = typed_param.mValues.back();
if (name_stack_range.first == name_stack_range.second)
{ // try to parse a known named value
std::string name;
- if(name_value_lookup_t::valueNamesExist()
+ if(named_value_t::valueNamesExist()
&& parser.readValue(name)
- && name_value_lookup_t::getValueFromName(name, value.getValue()))
+ && named_value_t::getValueFromName(name, value.getValue()))
{
typed_param.mValues.back().setValueName(name);
typed_param.setProvided();
@@ -1410,9 +1564,13 @@ namespace LLInitParam
}
// attempt to parse block...
- if(value.deserializeBlock(parser, name_stack_range, new_name))
+ if(value.deserializeBlock(parser, new_name_stack_range, new_name))
{
typed_param.setProvided();
+ if (new_array_value)
+ {
+ name_stack_range.first->second = false;
+ }
return true;
}
@@ -1428,13 +1586,13 @@ namespace LLInitParam
static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
{
const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided() || name_stack.empty()) return;
+ if (!typed_param.isProvided()) return;
for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
it != end_it;
++it)
{
- name_stack.back().second = true;
+ name_stack.push_back(std::make_pair(std::string(), true));
std::string key = it->getValueName();
if (!key.empty())
@@ -1447,16 +1605,27 @@ namespace LLInitParam
{
it->serializeBlock(parser, name_stack, NULL);
}
+
+ name_stack.pop_back();
}
}
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
- // I am a vector of blocks, so describe my contents recursively
- param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);
+ const param_value_t& value_param = param_value_t(value_t());
+
+ // tell parser about our actual type
+ parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+ // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+ if (named_value_t::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
}
- void set(value_assignment_t val, bool flag_as_provided = true)
+ value_param.inspectBlock(parser, name_stack, min_count, max_count);
+ }
+
+ void set(const container_t& val, bool flag_as_provided = true)
{
mValues = val;
setProvided(flag_as_provided);
@@ -1476,12 +1645,12 @@ namespace LLInitParam
return *this;
}
- self_t& add(const typename name_value_lookup_t::name_t& name)
+ self_t& add(const typename named_value_t::name_t& name)
{
value_t value;
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value))
+ if (named_value_t::getValueFromName(name, value))
{
add(value);
mValues.back().setValueName(name);
@@ -1490,12 +1659,10 @@ namespace LLInitParam
}
// implicit conversion
- operator value_assignment_t() const { return mValues; }
+ operator const container_t&() const { return mValues; }
// explicit conversion
- value_assignment_t operator()() const { return mValues; }
+ const container_t& operator()() const { return mValues; }
- typedef typename container_t::iterator iterator;
- typedef typename container_t::const_iterator const_iterator;
iterator begin() { return mValues.begin(); }
iterator end() { return mValues.end(); }
const_iterator begin() const { return mValues.begin(); }
@@ -1542,6 +1709,20 @@ namespace LLInitParam
}
container_t mValues;
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
};
template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
@@ -1556,13 +1737,13 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
}
bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
@@ -1580,7 +1761,7 @@ namespace LLInitParam
bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
{
mCurChoice = other.mCurChoice;
- return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
+ return base_block_t::mergeBlock(getBlockDescriptor(), other, overwrite);
}
// clear out old choice when param has changed
@@ -1601,38 +1782,38 @@ namespace LLInitParam
base_block_t::paramChanged(changed_param, user_provided);
}
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
protected:
ChoiceBlock()
: mCurChoice(0)
{
- BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+ BaseBlock::init(getBlockDescriptor(), base_block_t::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
}
// Alternatives are mutually exclusive wrt other Alternatives in the same block.
// One alternative in a block will always have isChosen() == true.
// At most one alternative in a block will have isProvided() == true.
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+
public:
friend class ChoiceBlock<DERIVED_BLOCK>;
- typedef Alternative<T, NAME_VALUE_LOOKUP> self_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
-
using super_t::operator =;
- explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
+ explicit Alternative(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),
mOriginalValue(val)
{
// assign initial choice to first declared option
- DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
- if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
+ DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr);
+ if (LL_UNLIKELY(DERIVED_BLOCK::getBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
{
if(blockp->mCurChoice == 0)
{
@@ -1646,27 +1827,27 @@ namespace LLInitParam
static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
}
- void chooseAs(value_assignment_t val)
+ void chooseAs(const value_t& val)
{
super_t::set(val);
}
- void operator =(value_assignment_t val)
+ void operator =(const value_t& val)
{
super_t::set(val);
}
- void operator()(typename super_t::value_assignment_t val)
+ void operator()(const value_t& val)
{
super_t::set(val);
}
- operator value_assignment_t() const
+ operator const value_t&() const
{
return (*this)();
}
- value_assignment_t operator()() const
+ const value_t& operator()() const
{
if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
{
@@ -1681,11 +1862,11 @@ namespace LLInitParam
}
private:
- T mOriginalValue;
+ default_value_t mOriginalValue;
};
- protected:
- static BlockDescriptor& selfBlockDescriptor()
+ public:
+ static BlockDescriptor& getBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
@@ -1705,6 +1886,8 @@ namespace LLInitParam
: public BASE_BLOCK
{
typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
+
+ protected:
typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
public:
@@ -1713,80 +1896,82 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
}
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
protected:
Block()
{
//#pragma message("Parsing LLInitParam::Block")
- BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+ BaseBlock::init(getBlockDescriptor(), BASE_BLOCK::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
}
//
// Nested classes for declaring parameters
//
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+ public:
using super_t::operator();
using super_t::operator =;
- explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
+ explicit Optional(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)
{
//#pragma message("Parsing LLInitParam::Block::Optional")
}
- Optional& operator =(value_assignment_t val)
+ Optional& operator =(const value_t& val)
{
set(val);
return *this;
}
- DERIVED_BLOCK& operator()(value_assignment_t val)
+ DERIVED_BLOCK& operator()(const value_t& val)
{
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
}
};
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+ public:
using super_t::operator();
using super_t::operator =;
// mandatory parameters require a name to be parseable
- explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
+ explicit Mandatory(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)
{}
- Mandatory& operator =(value_assignment_t val)
+ Mandatory& operator =(const value_t& val)
{
set(val);
return *this;
}
- DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+ DERIVED_BLOCK& operator()(const value_t& val)
{
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1800,28 +1985,29 @@ namespace LLInitParam
};
- template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
{
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, true> super_t;
typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::container_t container_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
+ typedef typename super_t::value_t value_t;
+
+ public:
typedef typename super_t::iterator iterator;
typedef typename super_t::const_iterator const_iterator;
explicit Multiple(const char* name = "")
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
{}
- Multiple& operator =(value_assignment_t val)
+ Multiple& operator =(const container_t& val)
{
set(val);
return *this;
}
- DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+ DERIVED_BLOCK& operator()(const container_t& val)
{
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1834,13 +2020,15 @@ namespace LLInitParam
}
};
- class Deprecated : public Param
+ // can appear in data files, but will ignored during parsing
+ // cannot read or write in code
+ class Ignored : public Param
{
public:
- explicit Deprecated(const char* name)
- : Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
+ explicit Ignored(const char* name)
+ : Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)
{
- BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
+ BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
@@ -1851,11 +2039,11 @@ namespace LLInitParam
NULL,
NULL,
0, S32_MAX));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ block_descriptor.addParam(param_descriptor, name);
}
}
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
if (name_stack_range.first == name_stack_range.second)
{
@@ -1868,19 +2056,46 @@ namespace LLInitParam
}
};
- // different semantics for documentation purposes, but functionally identical
- typedef Deprecated Ignored;
+ // can appear in data files, or be written to in code, but data will be ignored
+ // cannot be read in code
+ class Deprecated : public Ignored
+ {
+ public:
+ explicit Deprecated(const char* name) : Ignored(name) {}
- protected:
- static BlockDescriptor& selfBlockDescriptor()
+ // dummy writer interfaces
+ template<typename T>
+ Deprecated& operator =(const T& val)
+ {
+ // do nothing
+ return *this;
+ }
+
+ template<typename T>
+ DERIVED_BLOCK& operator()(const T& val)
+ {
+ // do nothing
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+
+ template<typename T>
+ void set(const T& val, bool flag_as_provided = true)
+ {
+ // do nothing
+ }
+ };
+
+ public:
+ static BlockDescriptor& getBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
}
- template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
+ protected:
+ template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, typename is_block>
void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param,
- typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
+ const typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_t& value)
{
if (!param.isProvided())
{
@@ -1890,204 +2105,420 @@ namespace LLInitParam
};
- template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
- class BatchBlock
- : public Block<DERIVED_BLOCK, BASE_BLOCK>
+ template<typename T, typename BLOCK_T>
+ struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_A_BLOCK>, BLOCK_T >, void>
+ {
+ typedef IS_A_BLOCK value_t;
+ };
+
+ template<typename T, typename BLOCK_T>
+ struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_A_BLOCK>, BLOCK_T >, void>
+ {
+ typedef NOT_BLOCK value_t;
+ };
+
+ template<typename T, typename BLOCK_IDENTIFIER>
+ struct IsBlock<ParamValue<BaseBlock::Atomic<T>, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER>
+ {
+ typedef typename IsBlock<T>::value_t value_t;
+ };
+
+ template<typename T, typename BLOCK_IDENTIFIER>
+ struct IsBlock<ParamValue<BaseBlock::Sequential<T>, typename IsBlock<BaseBlock::Sequential<T> >::value_t >, BLOCK_IDENTIFIER>
{
+ typedef typename IsBlock<T>::value_t value_t;
+ };
+
+
+ template<typename T>
+ struct InnerMostType
+ {
+ typedef T value_t;
+ };
+
+ template<typename T>
+ struct InnerMostType<ParamValue<T, NOT_BLOCK> >
+ {
+ typedef typename InnerMostType<T>::value_t value_t;
+ };
+
+ template<typename T>
+ struct InnerMostType<ParamValue<T, IS_A_BLOCK> >
+ {
+ typedef typename InnerMostType<T>::value_t value_t;
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Atomic<T>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Atomic<T>, BLOCK_T> self_t;
+
public:
- typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
- typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
- BatchBlock()
+ ParamValue()
+ : mValue(),
+ mValidated(false)
{}
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+ ParamValue(const default_value_t& value)
+ : mValue(value),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
+ {
+ mValue.setValue(val);
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue.getValue();
+ }
+
+ value_t& getValue()
+ {
+ return mValue.getValue();
+ }
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
if (new_name)
{
- // reset block
- *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
+ resetToDefault();
}
- return super_t::deserializeBlock(p, name_stack_range, new_name);
+ return mValue.deserializeBlock(p, name_stack_range, new_name);
}
- bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
{
- if (overwrite)
+ const BaseBlock* base_block = diff_block
+ ? &(diff_block->mValue)
+ : NULL;
+ mValue.serializeBlock(p, name_stack, base_block);
+ }
+
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
{
- *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
- // merge individual parameters into destination
- return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
+ return mValue.inspectBlock(p, name_stack, min_count, max_count);
}
- return false;
+
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+ {
+ if ((overwrite && source_provided) // new values coming in on top or...
+ || (!overwrite && !dst_provided)) // values being pushed under with nothing already there
+ {
+ // clear away what is there and take the new stuff as a whole
+ resetToDefault();
+ return mValue.mergeBlock(block_data, source.getValue(), overwrite);
}
- protected:
- static const DERIVED_BLOCK& defaultBatchValue()
+
+
+ return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+ }
+
+ bool validateBlock(bool emit_errors = true) const
+ {
+ return mValue.validateBlock(emit_errors);
+ }
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ return value_t::getBlockDescriptor();
+ }
+
+
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ void resetToDefault()
{
- static DERIVED_BLOCK default_value;
- return default_value;
+ static T default_value;
+ mValue = default_value;
}
+
+ T mValue;
};
- // FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class
- // and not the derived class with the actual params
- template<typename DERIVED_BLOCK,
- typename BASE_BLOCK,
- typename NAME_VALUE_LOOKUP>
- class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
- NAME_VALUE_LOOKUP,
- true>
- : public NAME_VALUE_LOOKUP,
- protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
+ template<typename T>
+ class ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK>
{
+ typedef ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK> self_t;
+
public:
- typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
- typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& value_assignment_t;
- typedef block_t value_t;
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
ParamValue()
- : block_t(),
+ : mValue(),
mValidated(false)
- {}
+ {
+ mCurParam = getBlockDescriptor().mAllParams.begin();
+ }
- ParamValue(value_assignment_t other)
- : block_t(other),
+ ParamValue(const default_value_t& value)
+ : mValue(value),
mValidated(false)
{
+ mCurParam = getBlockDescriptor().mAllParams.begin();
}
- void setValue(value_assignment_t val)
+ void setValue(const value_t& val)
{
- *this = val;
+ mValue.setValue(val);
}
- value_assignment_t getValue() const
+ const value_t& getValue() const
{
- return *this;
+ return mValue.getValue();
}
- BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue()
+ value_t& getValue()
{
- return *this;
+ return mValue.getValue();
}
- operator value_assignment_t() const
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
- return *this;
+ if (new_name)
+ {
+ mCurParam = getBlockDescriptor().mAllParams.begin();
}
+ if (name_stack_range.first == name_stack_range.second
+ && mCurParam != getBlockDescriptor().mAllParams.end())
+ {
+ // deserialize to mCurParam
+ ParamDescriptor& pd = *(*mCurParam);
+ ParamDescriptor::deserialize_func_t deserialize_func = pd.mDeserializeFunc;
+ Param* paramp = mValue.getParamFromHandle(pd.mParamHandle);
- value_assignment_t operator()() const
+ if (deserialize_func
+ && paramp
+ && deserialize_func(*paramp, p, name_stack_range, new_name))
{
- return *this;
+ ++mCurParam;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return mValue.deserializeBlock(p, name_stack_range, new_name);
+ }
+ }
+
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+ {
+ const BaseBlock* base_block = diff_block
+ ? &(diff_block->mValue)
+ : NULL;
+ mValue.serializeBlock(p, name_stack, base_block);
+ }
+
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ {
+ return mValue.inspectBlock(p, name_stack, min_count, max_count);
+ }
+
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+ {
+ return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+ }
+
+ bool validateBlock(bool emit_errors = true) const
+ {
+ return mValue.validateBlock(emit_errors);
+ }
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ return value_t::getBlockDescriptor();
}
- protected:
mutable bool mValidated; // lazy validation flag
+
+ private:
+
+ BlockDescriptor::all_params_list_t::iterator mCurParam;
+ T mValue;
};
- template<typename T, bool IS_BLOCK>
- class ParamValue <BaseBlock::Lazy<T>,
- TypeValues<T>,
- IS_BLOCK>
- : public IsBlock<T>::base_class_t
+ template<typename T>
+ class ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK>
+ : public T
{
+ typedef ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> self_t;
+
public:
- typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
- typedef const T& value_assignment_t;
- typedef T value_t;
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
+
+ ParamValue()
+ : T(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& value)
+ : T(value.getValue()),
+ mValidated(false)
+ {}
+
+ mutable bool mValidated; // lazy validation flag
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef LazyValue<T> default_value_t;
ParamValue()
: mValue(),
mValidated(false)
{}
- ParamValue(value_assignment_t other)
+ ParamValue(const default_value_t& other)
: mValue(other),
mValidated(false)
{}
- void setValue(value_assignment_t val)
+ ParamValue(const T& value)
+ : mValue(value),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
{
mValue.set(val);
}
- value_assignment_t getValue() const
+ const value_t& getValue() const
{
- return mValue.get();
+ return mValue.get().getValue();
}
- T& getValue()
+ value_t& getValue()
{
- return mValue.get();
+ return mValue.get().getValue();
}
- operator value_assignment_t() const
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
- return mValue.get();
+ return mValue.get().deserializeBlock(p, name_stack_range, new_name);
}
- value_assignment_t operator()() const
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
{
- return mValue.get();
+ if (mValue.empty()) return;
+
+ const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())
+ ? &(diff_block->mValue.get().getValue())
+ : NULL;
+ mValue.get().serializeBlock(p, name_stack, base_block);
}
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
{
- return mValue.get().deserializeBlock(p, name_stack_range, new_name);
+ return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
}
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
{
- if (mValue.empty()) return;
+ return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite);
+ }
- mValue.get().serializeBlock(p, name_stack, diff_block);
+ bool validateBlock(bool emit_errors = true) const
+ {
+ return mValue.empty() || mValue.get().validateBlock(emit_errors);
}
- bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ static BlockDescriptor& getBlockDescriptor()
{
- if (mValue.empty()) return false;
+ return value_t::getBlockDescriptor();
+ }
- return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ LazyValue<T> mValue;
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef LazyValue<T> default_value_t;
+
+ ParamValue()
+ : mValue(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& other)
+ : mValue(other),
+ mValidated(false)
+ {}
+
+ ParamValue(const T& value)
+ : mValue(value),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
+ {
+ mValue.set(val);
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue.get().getValue();
+ }
+
+ value_t& getValue()
+ {
+ return mValue.get().getValue();
}
- protected:
mutable bool mValidated; // lazy validation flag
private:
- BaseBlock::Lazy<T> mValue;
+ LazyValue<T> mValue;
};
template <>
- class ParamValue <LLSD,
- TypeValues<LLSD>,
- false>
- : public TypeValues<LLSD>,
- public BaseBlock
+ class ParamValue <LLSD, NOT_BLOCK>
+ : public BaseBlock
{
public:
- typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t;
- typedef const LLSD& value_assignment_t;
+ typedef LLSD value_t;
+ typedef LLSD default_value_t;
ParamValue()
: mValidated(false)
{}
- ParamValue(value_assignment_t other)
+ ParamValue(const default_value_t& other)
: mValue(other),
mValidated(false)
{}
- void setValue(value_assignment_t val) { mValue = val; }
+ void setValue(const value_t& val) { mValue = val; }
- value_assignment_t getValue() const { return mValue; }
+ const value_t& getValue() const { return mValue; }
LLSD& getValue() { return mValue; }
- operator value_assignment_t() const { return mValue; }
- value_assignment_t operator()() const { return mValue; }
-
-
// block param interface
- LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
+ LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
{
@@ -2106,8 +2537,7 @@ namespace LLInitParam
template<typename T>
class CustomParamValue
- : public Block<ParamValue<T, TypeValues<T> > >,
- public TypeValues<T>
+ : public Block<ParamValue<T> >
{
public:
typedef enum e_value_age
@@ -2117,20 +2547,21 @@ namespace LLInitParam
BLOCK_AUTHORITATIVE // mValue is derived from the block parameters, which are authoritative
} EValueAge;
- typedef ParamValue<T, TypeValues<T> > derived_t;
+ typedef ParamValue<T> derived_t;
typedef CustomParamValue<T> self_t;
typedef Block<derived_t> block_t;
- typedef const T& value_assignment_t;
+ typedef T default_value_t;
typedef T value_t;
+ typedef void baseblock_base_class_t;
- CustomParamValue(const T& value = T())
+ CustomParamValue(const default_value_t& value = T())
: mValue(value),
mValueAge(VALUE_AUTHORITATIVE),
mValidated(false)
{}
- bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)
+ bool deserializeBlock(Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
derived_t& typed_param = static_cast<derived_t&>(*this);
// try to parse direct value T
@@ -2141,8 +2572,6 @@ namespace LLInitParam
typed_param.mValueAge = VALUE_AUTHORITATIVE;
typed_param.updateBlockFromValue(false);
- typed_param.clearValueName();
-
return true;
}
}
@@ -2156,18 +2585,8 @@ namespace LLInitParam
const derived_t& typed_param = static_cast<const derived_t&>(*this);
const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
- std::string key = typed_param.getValueName();
-
- // first try to write out name of name/value pair
- if (!key.empty())
- {
- if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
- {
- parser.writeValue(key, name_stack);
- }
- }
// then try to serialize value directly
- else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
+ if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
{
if (!parser.writeValue(typed_param.getValue(), name_stack))
@@ -2197,19 +2616,6 @@ namespace LLInitParam
}
}
- bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
- {
- // first, inspect with actual type...
- parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
- if (TypeValues<T>::getPossibleValues())
- {
- //...then inspect with possible string values...
- parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
- }
- // then recursively inspect contents...
- return block_t::inspectBlock(parser, name_stack, min_count, max_count);
- }
-
bool validateBlock(bool emit_errors = true) const
{
if (mValueAge == VALUE_NEEDS_UPDATE)
@@ -2217,7 +2623,6 @@ namespace LLInitParam
if (block_t::validateBlock(emit_errors))
{
// clear stale keyword associated with old value
- TypeValues<T>::clearValueName();
mValueAge = BLOCK_AUTHORITATIVE;
static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();
return true;
@@ -2247,17 +2652,15 @@ namespace LLInitParam
}
}
- void setValue(value_assignment_t val)
+ void setValue(const value_t& val)
{
- derived_t& typed_param = static_cast<derived_t&>(*this);
// set param version number to be up to date, so we ignore block contents
mValueAge = VALUE_AUTHORITATIVE;
mValue = val;
- typed_param.clearValueName();
static_cast<derived_t*>(this)->updateBlockFromValue(false);
}
- value_assignment_t getValue() const
+ const value_t& getValue() const
{
validateBlock(true);
return mValue;
@@ -2269,20 +2672,10 @@ namespace LLInitParam
return mValue;
}
- operator value_assignment_t() const
- {
- return getValue();
- }
-
- value_assignment_t operator()() const
- {
- return getValue();
- }
-
protected:
// use this from within updateValueFromBlock() to set the value without making it authoritative
- void updateValue(value_assignment_t value)
+ void updateValue(const value_t& value)
{
mValue = value;
}
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 403df08990..1eab270e3c 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -43,7 +43,7 @@
* semantics: one instance per process, rather than one instance per module as
* sometimes happens with data simply declared static.
*/
-class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
+class LL_COMMON_API LLInstanceTrackerBase
{
protected:
/// Get a process-unique void* pointer slot for the specified type_info
@@ -210,6 +210,9 @@ protected:
virtual const KEY& getKey() const { return mInstanceKey; }
private:
+ LLInstanceTracker( const LLInstanceTracker& );
+ const LLInstanceTracker& operator=( const LLInstanceTracker& );
+
void add_(KEY key)
{
mInstanceKey = key;
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 8eb5d53f3f..32ae15435a 100644
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -27,6 +27,7 @@
#define LLREFCOUNT_H
#include <boost/noncopyable.hpp>
+#include <boost/intrusive_ptr.hpp>
#define LL_REF_COUNT_DEBUG 0
#if LL_REF_COUNT_DEBUG
@@ -86,4 +87,22 @@ private:
#endif
};
+/**
+ * intrusive pointer support
+ * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
+ */
+namespace boost
+{
+ inline void intrusive_ptr_add_ref(LLRefCount* p)
+ {
+ p->ref();
+ }
+
+ inline void intrusive_ptr_release(LLRefCount* p)
+ {
+ p->unref();
+ }
+};
+
+
#endif
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
index 853c427a13..bb0d60247e 100644
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
@@ -307,6 +307,10 @@ public:
virtual ~StaticRegistrar() {}
StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
{
+ if (singleton_t::instance().exists(key))
+ {
+ llerrs << "Duplicate registry entry under key \"" << key << "\"" << llendl;
+ }
singleton_t::instance().mStaticScope->add(key, value);
}
};
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index 0e29873bb0..9f4460a988 100644
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
@@ -223,10 +223,14 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:
{
bool new_traversal = it->second;
- LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
-
- if (child_sd->isArray())
+ LLSD* child_sd;
+ if (it->first.empty())
{
+ child_sd = sd_to_write;
+ if (child_sd->isUndefined())
+ {
+ *child_sd = LLSD::emptyArray();
+ }
if (new_traversal)
{
// write to new element at end
@@ -240,22 +244,7 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:
}
else
{
- if (new_traversal
- && child_sd->isDefined()
- && !child_sd->isArray())
- {
- // copy child contents into first element of an array
- LLSD new_array = LLSD::emptyArray();
- new_array.append(*child_sd);
- // assign array to slot that previously held the single value
- *child_sd = new_array;
- // return next element in that array
- sd_to_write = &((*child_sd)[1]);
- }
- else
- {
- sd_to_write = child_sd;
- }
+ sd_to_write = &(*sd_to_write)[it->first];
}
it->second = false;
}
@@ -283,8 +272,9 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI
it != sd.endArray();
++it)
{
- stack.back().second = true;
+ stack.push_back(make_pair(std::string(), true));
readSDValues(cb, *it, stack);
+ stack.pop_back();
}
}
else if (sd.isUndefined())
@@ -313,8 +303,14 @@ namespace LLInitParam
{
// LLSD specialization
// block param interface
- bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
+ bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack, bool new_name)
{
+ if (name_stack.first == name_stack.second
+ && p.readValue<LLSD>(mValue))
+ {
+ return true;
+ }
+
LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
LLSD::String string;
@@ -328,15 +324,18 @@ namespace LLInitParam
}
//static
- void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
+ void ParamValue<LLSD, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
{
p.writeValue<LLSD::String>(sd.asString(), name_stack);
}
- void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
+ void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
{
- // read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
- Parser::name_stack_t stack;
- LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack);
+ // attempt to write LLSD out directly
+ if (!p.writeValue<LLSD>(mValue, name_stack))
+ {
+ // otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
+ LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
+ }
}
}
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 5c8bbca2ca..0fb89c5613 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -30,6 +30,7 @@
#include "llapp.h"
#include "llapr.h"
#include "apr_thread_cond.h"
+#include "boost/intrusive_ptr.hpp"
class LLThread;
class LLMutex;
@@ -284,6 +285,22 @@ private:
S32 mRef;
};
+/**
+ * intrusive pointer support for LLThreadSafeRefCount
+ * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
+ */
+namespace boost
+{
+ inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
+ {
+ p->ref();
+ }
+
+ inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
+ {
+ p->unref();
+ }
+};
//============================================================================
// Simple responder for self destructing callbacks
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index e41c59177a..ca8a05511a 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -28,8 +28,8 @@
#define LL_LLVERSIONVIEWER_H
const S32 LL_VERSION_MAJOR = 3;
-const S32 LL_VERSION_MINOR = 4;
-const S32 LL_VERSION_PATCH = 5;
+const S32 LL_VERSION_MINOR = 5;
+const S32 LL_VERSION_PATCH = 0;
const S32 LL_VERSION_BUILD = 264760;
const char * const LL_CHANNEL = "Second Life Developer";
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 40b3364b36..efcbe76795 100644
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -51,7 +51,8 @@ enum EDragAndDropType
DAD_LINK = 14,
DAD_MESH = 15,
DAD_WIDGET = 16,
- DAD_COUNT = 17, // number of types in this enum
+ DAD_PERSON = 17,
+ DAD_COUNT = 18, // number of types in this enum
};
// Reasons for drags to be denied.