summaryrefslogtreecommitdiff
path: root/indra/llxuixml
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llxuixml')
-rw-r--r--indra/llxuixml/llinitparam.cpp21
-rw-r--r--indra/llxuixml/llinitparam.h556
-rw-r--r--indra/llxuixml/llxuiparser.cpp256
3 files changed, 615 insertions, 218 deletions
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 482064ed7b..db72aa19b9 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -40,7 +40,7 @@ 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));
+ mEnclosingBlockOffset = 0x7FFFffff & (U32)(my_addr - block_addr);
}
//
@@ -118,16 +118,6 @@ namespace LLInitParam
mCurrentBlockPtr(NULL)
{}
- //
- // BaseBlock
- //
- BaseBlock::BaseBlock()
- : mChangeVersion(0)
- {}
-
- BaseBlock::~BaseBlock()
- {}
-
// called by each derived class in least to most derived order
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
@@ -427,14 +417,6 @@ namespace LLInitParam
}
}
- void BaseBlock::paramChanged(const Param& changed_param, bool user_provided)
- {
- if (user_provided)
- {
- mChangeVersion++;
- }
- }
-
const std::string& BaseBlock::getParamName(const BlockDescriptor& block_data, const Param* paramp) const
{
param_handle_t handle = getHandleFromParam(paramp);
@@ -478,6 +460,7 @@ namespace LLInitParam
if (merge_func)
{
Param* paramp = getParamFromHandle((*it)->mParamHandle);
+ llassert(paramp->mEnclosingBlockOffset == (*it)->mParamHandle);
some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
}
}
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 183472450d..80b6504c4f 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -51,7 +51,7 @@ namespace LLInitParam
return a == b;
}
};
-
+
// boost function types are not comparable
template<typename T>
struct ParamCompare<T, true>
@@ -74,6 +74,7 @@ namespace LLInitParam
static bool equals(const Flag& a, const Flag& b) { return false; }
};
+
// helper functions and classes
typedef ptrdiff_t param_handle_t;
@@ -82,8 +83,11 @@ namespace LLInitParam
template <typename T>
class TypeValues
{
+ private:
+ struct Inaccessable{};
public:
typedef std::map<std::string, T> value_name_map_t;
+ typedef Inaccessable name_t;
void setValueName(const std::string& key) {}
std::string getValueName() const { return ""; }
@@ -113,6 +117,7 @@ namespace LLInitParam
{
public:
typedef typename std::map<std::string, T> value_name_map_t;
+ typedef std::string name_t;
//TODO: cache key by index to save on param block size
void setValueName(const std::string& value_name)
@@ -293,36 +298,7 @@ namespace LLInitParam
parser_inspect_func_map_t* mParserInspectFuncs;
};
- class BaseBlock;
-
- class Param
- {
- public:
- // public to allow choice blocks to clear provided flag on stale choices
- void setProvided(bool is_provided) { mIsProvided = is_provided; }
-
- protected:
- bool anyProvided() const { return mIsProvided; }
-
- Param(BaseBlock* enclosing_block);
-
- // store pointer to enclosing block as offset to reduce space and allow for quick copying
- BaseBlock& enclosingBlock() const
- {
- const U8* my_addr = reinterpret_cast<const U8*>(this);
- // 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;
-
- };
+ class Param;
// various callbacks and constraints associated with an individual param
struct ParamDescriptor
@@ -390,12 +366,91 @@ namespace LLInitParam
all_params_list_t mAllParams; // all parameters, owns descriptors
size_t mMaxParamOffset;
EInitializationState mInitializationState; // whether or not static block data has been initialized
- BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
+ class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
};
class BaseBlock
{
public:
+ //TODO: implement in terms of owned_ptr
+ template<typename T>
+ class Lazy
+ {
+ public:
+ Lazy()
+ : mPtr(NULL)
+ {}
+
+ ~Lazy()
+ {
+ delete mPtr;
+ }
+
+ Lazy(const Lazy& other)
+ {
+ if (other.mPtr)
+ {
+ mPtr = new T(*other.mPtr);
+ }
+ else
+ {
+ mPtr = NULL;
+ }
+ }
+
+ Lazy<T>& operator = (const Lazy<T>& other)
+ {
+ if (other.mPtr)
+ {
+ mPtr = new T(*other.mPtr);
+ }
+ else
+ {
+ mPtr = NULL;
+ }
+ return *this;
+ }
+
+ bool empty() const
+ {
+ return mPtr == NULL;
+ }
+
+ void set(const T& other)
+ {
+ delete mPtr;
+ mPtr = new T(other);
+ }
+
+ const T& get() const
+ {
+ return ensureInstance();
+ }
+
+ T& get()
+ {
+ return ensureInstance();
+ }
+
+ private:
+ // lazily allocate an instance of T
+ T* ensureInstance() const
+ {
+ if (mPtr == NULL)
+ {
+ mPtr = new T();
+ }
+ return mPtr;
+ }
+
+ 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;
+ };
+
// "Multiple" constraint types, put here in root class to avoid ambiguity during use
struct AnyAmount
{
@@ -436,8 +491,7 @@ namespace LLInitParam
LOG_CLASS(BaseBlock);
friend class Param;
- BaseBlock();
- virtual ~BaseBlock();
+ virtual ~BaseBlock() {}
bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
param_handle_t getHandleFromParam(const Param* param) const;
@@ -460,9 +514,7 @@ namespace LLInitParam
void addSynonym(Param& param, const std::string& synonym);
// Blocks can override this to do custom tracking of changes
- virtual void paramChanged(const Param& changed_param, bool user_provided);
-
- S32 getLastChangeVersion() const { return mChangeVersion; }
+ 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);
void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
@@ -498,9 +550,6 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
- // can be updated in getters
- mutable S32 mChangeVersion;
-
static BlockDescriptor& selfBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
@@ -511,18 +560,73 @@ namespace LLInitParam
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 Param
+ {
+ public:
+ void setProvided(bool is_provided = true)
+ {
+ mIsProvided = is_provided;
+ enclosingBlock().paramChanged(*this, is_provided);
+ }
+
+ Param& operator =(const Param& other)
+ {
+ mIsProvided = other.mIsProvided;
+ // don't change mEnclosingblockoffset
+ return *this;
+ }
+ protected:
+
+ bool anyProvided() const { return mIsProvided; }
+
+ Param(BaseBlock* enclosing_block);
+
+ // store pointer to enclosing block as offset to reduce space and allow for quick copying
+ BaseBlock& enclosingBlock() const
+ {
+ const U8* my_addr = reinterpret_cast<const U8*>(this);
+ // 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 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>
@@ -530,6 +634,8 @@ namespace LLInitParam
{
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) {}
@@ -559,8 +665,22 @@ namespace LLInitParam
return mValue;
}
+ void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
+ {
+ *this = name;
+ }
- private:
+ 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;
};
@@ -571,18 +691,16 @@ namespace LLInitParam
{
public:
typedef const T& value_assignment_t;
+ typedef T value_t;
+ typedef ParamValue<T, NAME_VALUE_LOOKUP, true> self_t;
ParamValue()
: T(),
- mKeyVersion(0),
- mValidatedVersion(-1),
mValidated(false)
{}
ParamValue(value_assignment_t other)
: T(other),
- mKeyVersion(0),
- mValidatedVersion(-1),
mValidated(false)
{}
@@ -611,13 +729,74 @@ namespace LLInitParam
return *this;
}
- S32 mKeyVersion;
+ 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:
- mutable S32 mValidatedVersion;
mutable bool mValidated; // lazy validation flag
};
+ template<typename NAME_VALUE_LOOKUP>
+ class ParamValue<std::string, NAME_VALUE_LOOKUP, false>
+ : public NAME_VALUE_LOOKUP
+ {
+ 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))
+ {
+ setValueName(val);
+ }
+ else
+ {
+ mValue = val;
+ }
+ }
+
+ value_assignment_t getValue() const
+ {
+ return mValue;
+ }
+
+ std::string& getValue()
+ {
+ return mValue;
+ }
+
+ operator value_assignment_t() const
+ {
+ return mValue;
+ }
+
+ value_assignment_t operator()() const
+ {
+ return mValue;
+ }
+
+ protected:
+ std::string mValue;
+ };
+
+
template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
struct ParamIterator
{
@@ -636,10 +815,12 @@ namespace LLInitParam
public ParamValue<T, NAME_VALUE_LOOKUP>
{
public:
- typedef const T& value_assignment_t;
typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
+ typedef param_value_t::value_assignment_t value_assignment_t;
+ typedef NAME_VALUE_LOOKUP name_value_lookup_t;
+
+ using param_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)
@@ -671,8 +852,7 @@ namespace LLInitParam
if (parser.readValue(typed_param.getValue()))
{
typed_param.clearValueName();
- typed_param.setProvided(true);
- typed_param.enclosingBlock().paramChanged(param, true);
+ typed_param.setProvided();
return true;
}
@@ -687,8 +867,7 @@ namespace LLInitParam
if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
{
typed_param.setValueName(name);
- typed_param.setProvided(true);
- typed_param.enclosingBlock().paramChanged(param, true);
+ typed_param.setProvided();
return true;
}
@@ -746,14 +925,25 @@ namespace LLInitParam
void set(value_assignment_t val, bool flag_as_provided = true)
{
- setValue(val);
param_value_t::clearValueName();
+ setValue(val);
setProvided(flag_as_provided);
- Param::enclosingBlock().paramChanged(*this, flag_as_provided);
+ }
+
+ self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+ {
+ return static_cast<self_t&>(param_value_t::operator =(name));
}
protected:
+ self_t& operator =(const self_t& other)
+ {
+ param_value_t::operator =(other);
+ Param::operator =(other);
+ return *this;
+ }
+
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
@@ -776,12 +966,12 @@ namespace LLInitParam
public ParamValue<T, NAME_VALUE_LOOKUP>
{
public:
- typedef const T value_const_t;
- typedef T value_t;
- typedef value_const_t& value_assignment_t;
+ 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;
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
+
+ using param_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),
@@ -808,8 +998,7 @@ namespace LLInitParam
if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
{
typed_param.clearValueName();
- typed_param.enclosingBlock().paramChanged(param, true);
- typed_param.setProvided(true);
+ typed_param.setProvided();
return true;
}
@@ -822,10 +1011,8 @@ namespace LLInitParam
// try to parse a per type named value
if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
{
- typed_param.enclosingBlock().paramChanged(param, true);
typed_param.setValueName(name);
- typed_param.setProvided(true);
- typed_param.mKeyVersion = typed_param.getLastChangeVersion();
+ typed_param.setProvided();
return true;
}
@@ -845,7 +1032,7 @@ namespace LLInitParam
}
std::string key = typed_param.getValueName();
- if (!key.empty() && typed_param.mKeyVersion == typed_param.getLastChangeVersion())
+ if (!key.empty())
{
if (!parser.writeValue(key, name_stack))
{
@@ -870,11 +1057,10 @@ namespace LLInitParam
bool isProvided() const
{
// only validate block when it hasn't already passed validation with current data
- if (Param::anyProvided() && param_value_t::mValidatedVersion < param_value_t::getLastChangeVersion())
+ if (Param::anyProvided() && !param_value_t::mValidated)
{
// a sub-block is "provided" when it has been filled in enough to be valid
param_value_t::mValidated = param_value_t::validateBlock(false);
- param_value_t::mValidatedVersion = param_value_t::getLastChangeVersion();
}
return Param::anyProvided() && param_value_t::mValidated;
}
@@ -884,28 +1070,44 @@ namespace LLInitParam
{
setValue(val);
param_value_t::clearValueName();
- // force revalidation of block by clearing known provided version
+ // force revalidation of block
// next call to isProvided() will update provision status based on validity
- param_value_t::mValidatedVersion = -1;
+ param_value_t::mValidated = false;
setProvided(flag_as_provided);
- Param::enclosingBlock().paramChanged(*this, flag_as_provided);
+ }
+
+ self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+ {
+ return static_cast<self_t&>(param_value_t::operator =(name));
}
// 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);
- Param::enclosingBlock().paramChanged(*this, user_provided);
if (user_provided)
{
// a child param has been explicitly changed
// so *some* aspect of this block is now provided
- setProvided(true);
+ param_value_t::mValidated = false;
+ setProvided();
+ param_value_t::clearValueName();
+ }
+ else
+ {
+ Param::enclosingBlock().paramChanged(*this, user_provided);
}
}
protected:
+ self_t& operator =(const self_t& other)
+ {
+ param_value_t::operator =(other);
+ Param::operator =(other);
+ return *this;
+ }
+
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
@@ -917,7 +1119,6 @@ namespace LLInitParam
{
dst_typed_param.clearValueName();
dst_typed_param.setProvided(true);
- dst_typed_param.enclosingBlock().paramChanged(dst_typed_param, true);
return true;
}
}
@@ -936,7 +1137,7 @@ namespace LLInitParam
typedef typename std::vector<param_value_t> container_t;
typedef const container_t& value_assignment_t;
- typedef VALUE_TYPE value_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)
@@ -1004,7 +1205,7 @@ namespace LLInitParam
it != end_it;
++it)
{
- std::string key = it->getValue();
+ std::string key = it->getValueName();
name_stack.back().second = true;
if(key.empty())
@@ -1013,7 +1214,7 @@ namespace LLInitParam
bool value_written = parser.writeValue(*it, name_stack);
if (!value_written)
{
- std::string calculated_key = it->calcValueName(key);
+ std::string calculated_key = it->calcValueName(it->getValue());
if (!parser.writeValue(calculated_key, name_stack))
{
break;
@@ -1043,22 +1244,33 @@ namespace LLInitParam
{
mValues = val;
setProvided(flag_as_provided);
- Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
- value_t& add()
+ param_value_t& add()
{
mValues.push_back(param_value_t(value_t()));
- setProvided(true);
- Param::enclosingBlock().paramChanged(*this, true);
+ Param::setProvided();
return mValues.back();
}
void add(const value_t& item)
{
- mValues.push_back(param_value_t(item));
- setProvided(true);
- Param::enclosingBlock().paramChanged(*this, true);
+ param_value_t param_value;
+ param_value.setValue(item);
+ mValues.push_back(param_value);
+ setProvided();
+ }
+
+ void add(typename const name_value_lookup_t::name_t& name)
+ {
+ value_t value;
+
+ // try to parse a per type named value
+ if (name_value_lookup_t::getValueFromName(name, value))
+ {
+ add(value);
+ mValues.back().setValueName(name);
+ }
}
// implicit conversion
@@ -1099,8 +1311,7 @@ namespace LLInitParam
if (src_typed_param.begin() != src_typed_param.end())
{
- dst_typed_param.setProvided(true);
- dst_typed_param.enclosingBlock().paramChanged(dst_typed_param, true);
+ dst_typed_param.setProvided();
}
return true;
}
@@ -1116,9 +1327,9 @@ namespace LLInitParam
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 typename std::vector<param_value_t> container_t;
typedef const container_t& value_assignment_t;
- typedef VALUE_TYPE value_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)
@@ -1158,8 +1369,7 @@ namespace LLInitParam
// attempt to parse block...
if(value.deserializeBlock(parser, name_stack_range, new_name))
{
- typed_param.enclosingBlock().paramChanged(param, true);
- typed_param.setProvided(true);
+ typed_param.setProvided();
return true;
}
else if(name_value_lookup_t::valueNamesExist())
@@ -1172,9 +1382,7 @@ namespace LLInitParam
if (name_value_lookup_t::getValueFromName(name, value.getValue()))
{
typed_param.mValues.back().setValueName(name);
- typed_param.mValues.back().mKeyVersion = value.getLastChangeVersion();
- typed_param.enclosingBlock().paramChanged(param, true);
- typed_param.setProvided(true);
+ typed_param.setProvided();
return true;
}
@@ -1201,7 +1409,7 @@ namespace LLInitParam
name_stack.back().second = true;
std::string key = it->getValueName();
- if (!key.empty() && it->mKeyVersion == it->getLastChangeVersion())
+ if (!key.empty())
{
parser.writeValue(key, name_stack);
}
@@ -1224,22 +1432,31 @@ namespace LLInitParam
{
mValues = val;
setProvided(flag_as_provided);
- Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
- value_t& add()
+ param_value_t& add()
{
mValues.push_back(value_t());
- setProvided(true);
- Param::enclosingBlock().paramChanged(*this, true);
+ setProvided();
return mValues.back();
}
void add(const value_t& item)
{
mValues.push_back(item);
- setProvided(true);
- Param::enclosingBlock().paramChanged(*this, true);
+ setProvided();
+ }
+
+ void add(typename const name_value_lookup_t::name_t& name)
+ {
+ value_t value;
+
+ // try to parse a per type named value
+ if (name_value_lookup_t::getValueFromName(name, value))
+ {
+ add(value);
+ mValues.back().setValueName(name);
+ }
}
// implicit conversion
@@ -1288,8 +1505,7 @@ namespace LLInitParam
if (src_typed_param.begin() != src_typed_param.end())
{
- dst_typed_param.setProvided(true);
- dst_typed_param.enclosingBlock().paramChanged(dst_typed_param, true);
+ dst_typed_param.setProvided();
}
return true;
@@ -1298,24 +1514,25 @@ namespace LLInitParam
container_t mValues;
};
- template <typename DERIVED_BLOCK>
- class ChoiceBlock : public BaseBlock
+ template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+ class ChoiceBlock : public BASE_BLOCK
{
- typedef ChoiceBlock<DERIVED_BLOCK> self_t;
- typedef ChoiceBlock<DERIVED_BLOCK> enclosing_block_t;
+ typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
+ typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> enclosing_block_t;
+ typedef BASE_BLOCK base_block_t;
LOG_CLASS(self_t);
public:
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
- return mergeBlock(selfBlockDescriptor(), other, true);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
- return mergeBlock(selfBlockDescriptor(), other, false);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
}
bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
@@ -1333,25 +1550,25 @@ namespace LLInitParam
bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
{
mCurChoice = other.mCurChoice;
- return BaseBlock::mergeBlock(selfBlockDescriptor(), other, overwrite);
+ return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
}
// clear out old choice when param has changed
/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
- param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&changed_param);
+ param_handle_t changed_param_handle = base_block_t::getHandleFromParam(&changed_param);
// if we have a new choice...
if (changed_param_handle != mCurChoice)
{
// clear provided flag on previous choice
- Param* previous_choice = BaseBlock::getParamFromHandle(mCurChoice);
+ Param* previous_choice = base_block_t::getParamFromHandle(mCurChoice);
if (previous_choice)
{
previous_choice->setProvided(false);
}
mCurChoice = changed_param_handle;
}
- BaseBlock::paramChanged(changed_param, user_provided);
+ base_block_t::paramChanged(changed_param, user_provided);
}
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
@@ -1361,7 +1578,7 @@ namespace LLInitParam
ChoiceBlock()
: mCurChoice(0)
{
- BaseBlock::init(selfBlockDescriptor(), BaseBlock::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+ BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
}
// Alternatives are mutually exclusive wrt other Alternatives in the same block.
@@ -1377,6 +1594,8 @@ namespace LLInitParam
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),
mOriginalValue(val)
@@ -1402,7 +1621,7 @@ namespace LLInitParam
super_t::set(val);
}
- void operator=(value_assignment_t val)
+ void operator =(value_assignment_t val)
{
super_t::set(val);
}
@@ -1447,7 +1666,7 @@ namespace LLInitParam
const Param* getCurrentChoice() const
{
- return BaseBlock::getParamFromHandle(mCurChoice);
+ return base_block_t::getParamFromHandle(mCurChoice);
}
};
@@ -1493,13 +1712,16 @@ namespace LLInitParam
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();
+ 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)
{
//#pragma message("Parsing LLInitParam::Block::Optional")
}
- Optional& operator=(value_assignment_t val)
+ Optional& operator =(value_assignment_t val)
{
set(val);
return *this;
@@ -1510,7 +1732,6 @@ namespace LLInitParam
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
}
- using super_t::operator();
};
template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
@@ -1521,12 +1742,15 @@ namespace LLInitParam
typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::value_assignment_t value_assignment_t;
+ 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)
{}
- Mandatory& operator=(value_assignment_t val)
+ Mandatory& operator =(value_assignment_t val)
{
set(val);
return *this;
@@ -1537,7 +1761,6 @@ namespace LLInitParam
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
}
- using super_t::operator();
static bool validate(const Param* p)
{
@@ -1562,7 +1785,7 @@ namespace LLInitParam
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
{}
- Multiple& operator=(value_assignment_t val)
+ Multiple& operator =(value_assignment_t val)
{
set(val);
return *this;
@@ -1690,18 +1913,15 @@ namespace LLInitParam
public:
typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& value_assignment_t;
+ typedef block_t value_t;
ParamValue()
: block_t(),
- mKeyVersion(0),
- mValidatedVersion(-1),
mValidated(false)
{}
ParamValue(value_assignment_t other)
: block_t(other),
- mKeyVersion(0),
- mValidatedVersion(-1),
mValidated(false)
{
}
@@ -1731,11 +1951,80 @@ namespace LLInitParam
return *this;
}
- S32 mKeyVersion;
+ protected:
+ mutable bool mValidated; // lazy validation flag
+ };
+
+ template<typename T, bool IS_BLOCK>
+ class ParamValue <BaseBlock::Lazy<T>,
+ TypeValues<T>,
+ IS_BLOCK>
+ : public IsBlock<T>::base_class_t
+ {
+ public:
+ typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
+ typedef const T& value_assignment_t;
+ typedef T value_t;
+
+ ParamValue()
+ : mValue(),
+ mValidated(false)
+ {}
+
+ ParamValue(value_assignment_t other)
+ : mValue(other),
+ mValidated(false)
+ {}
+
+ void setValue(value_assignment_t val)
+ {
+ mValue.set(val);
+ }
+
+ value_assignment_t getValue() const
+ {
+ return mValue.get();
+ }
+
+ T& getValue()
+ {
+ return mValue.get();
+ }
+
+ operator value_assignment_t() const
+ {
+ return mValue.get();
+ }
+
+ value_assignment_t operator()() const
+ {
+ return mValue.get();
+ }
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+ {
+ return mValue.get().deserializeBlock(p, name_stack_range, new_name);
+ }
+
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+ {
+ if (mValue.empty()) return;
+
+ mValue.get().serializeBlock(p, name_stack, diff_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
+ {
+ if (mValue.empty()) return false;
+
+ return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
+ }
protected:
- mutable S32 mValidatedVersion;
mutable bool mValidated; // lazy validation flag
+
+ private:
+ BaseBlock::Lazy<T> mValue;
};
template <>
@@ -1750,15 +2039,11 @@ namespace LLInitParam
typedef const LLSD& value_assignment_t;
ParamValue()
- : mKeyVersion(0),
- mValidatedVersion(-1),
- mValidated(false)
+ : mValidated(false)
{}
ParamValue(value_assignment_t other)
: mValue(other),
- mKeyVersion(0),
- mValidatedVersion(-1),
mValidated(false)
{}
@@ -1770,7 +2055,6 @@ namespace LLInitParam
operator value_assignment_t() const { return mValue; }
value_assignment_t operator()() const { return mValue; }
- S32 mKeyVersion;
// block param interface
bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
@@ -1782,7 +2066,6 @@ namespace LLInitParam
}
protected:
- mutable S32 mValidatedVersion;
mutable bool mValidated; // lazy validation flag
private:
@@ -1806,14 +2089,14 @@ namespace LLInitParam
typedef ParamValue<T, TypeValues<T> > derived_t;
typedef CustomParamValue<T> self_t;
- typedef Block<derived_t> block_t;
+ typedef Block<derived_t> block_t;
typedef const T& value_assignment_t;
+ typedef T value_t;
+
CustomParamValue(const T& value = T())
: mValue(value),
mValueAge(VALUE_AUTHORITATIVE),
- mKeyVersion(0),
- mValidatedVersion(-1),
mValidated(false)
{}
@@ -1966,8 +2249,6 @@ namespace LLInitParam
return getValue();
}
- S32 mKeyVersion;
-
protected:
// use this from within updateValueFromBlock() to set the value without making it authoritative
@@ -2001,7 +2282,6 @@ namespace LLInitParam
return block_t::mergeBlock(block_data, source, overwrite);
}
- mutable S32 mValidatedVersion;
mutable bool mValidated; // lazy validation flag
private:
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 878f992178..90c2671242 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -59,28 +59,24 @@ const char* NO_VALUE_MARKER = "no_value";
const S32 LINE_NUMBER_HERE = 0;
-struct MaxOccur : public LLInitParam::ChoiceBlock<MaxOccur>
+struct MaxOccursValues : public LLInitParam::TypeValuesHelper<U32, MaxOccursValues>
{
- Alternative<int> count;
- Alternative<std::string> unbounded;
-
- MaxOccur()
- : unbounded("", "unbounded")
- {}
+ static void declareValues()
+ {
+ declare("unbounded", U32_MAX);
+ }
};
struct Occurs : public LLInitParam::Block<Occurs>
{
- Optional<S32> minOccurs;
- Optional<MaxOccur> maxOccurs;
+ Optional<U32> minOccurs;
+ Optional<U32, MaxOccursValues> maxOccurs;
Occurs()
- : minOccurs("minOccurs"),
- maxOccurs("maxOccurs")
- {
- minOccurs = 0;
- maxOccurs.unbounded.choose();
- }
+ : minOccurs("minOccurs", 0),
+ maxOccurs("maxOccurs", U32_MAX)
+
+ {}
};
@@ -103,18 +99,15 @@ namespace LLInitParam
};
}
-struct Name : public LLInitParam::Block<Name>
-{
- Mandatory<std::string> name;
-
- Name()
- : name("name")
- {}
-};
+struct Element;
+struct Group;
+struct Choice;
+struct Sequence;
+struct Any;
struct Attribute : public LLInitParam::Block<Attribute>
{
- Mandatory<Name> name;
+ Mandatory<std::string> name;
Mandatory<std::string> type;
Mandatory<EUse> use;
@@ -122,41 +115,170 @@ struct Attribute : public LLInitParam::Block<Attribute>
: name("name"),
type("type"),
use("use")
+ {}
+};
+
+struct Any : public LLInitParam::Block<Any, Occurs>
+{
+ Optional<std::string> _namespace;
+
+ Any()
+ : _namespace("namespace")
+ {}
+};
+
+struct All : public LLInitParam::Block<All, Occurs>
+{
+ Multiple<Lazy<Element>> elements;
+
+ All()
+ : elements("element")
{
+ maxOccurs = 1;
}
};
-struct ComplexType : public LLInitParam::Block<ComplexType>
+struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
+{
+ Alternative<Lazy<Element>> element;
+ Alternative<Lazy<Group>> group;
+ Alternative<Lazy<Choice>> choice;
+ Alternative<Lazy<Sequence>> sequence;
+ Alternative<Lazy<Any>> any;
+
+ Choice()
+ : element("element"),
+ group("group"),
+ choice("choice"),
+ sequence("sequence"),
+ any("any")
+ {}
+
+};
+
+struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
+{
+ Alternative<Lazy<Element>> element;
+ Alternative<Lazy<Group>> group;
+ Alternative<Lazy<Choice>> choice;
+ Alternative<Lazy<Sequence>> sequence;
+ Alternative<Lazy<Any>> any;
+};
+
+struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
+{
+ Alternative<All> all;
+ Alternative<Choice> choice;
+ Alternative<Sequence> sequence;
+
+ GroupContents()
+ : all("all"),
+ choice("choice"),
+ sequence("sequence")
+ {}
+};
+
+struct Group : public LLInitParam::Block<Group, GroupContents>
+{
+ Optional<std::string> name,
+ ref;
+
+ Group()
+ : name("name"),
+ ref("ref")
+ {}
+};
+
+struct Restriction : public LLInitParam::Block<Restriction>
+{
+};
+
+struct Extension : public LLInitParam::Block<Extension>
+{
+};
+
+struct SimpleContent : public LLInitParam::ChoiceBlock<SimpleContent>
+{
+ Alternative<Restriction> restriction;
+ Alternative<Extension> extension;
+
+ SimpleContent()
+ : restriction("restriction"),
+ extension("extension")
+ {}
+};
+
+struct SimpleType : public LLInitParam::Block<SimpleType>
+{
+ // TODO
+};
+
+struct ComplexContent : public LLInitParam::Block<ComplexContent, SimpleContent>
{
- Multiple<Attribute> attribute;
- //Multiple<struct Element> elements;
- Optional<bool> mixed;
+ Optional<bool> mixed;
+
+ ComplexContent()
+ : mixed("mixed", true)
+ {}
+};
+
+struct ComplexTypeContents : public LLInitParam::ChoiceBlock<ComplexTypeContents>
+{
+ Alternative<SimpleContent> simple_content;
+ Alternative<ComplexContent> complex_content;
+ Alternative<Group> group;
+ Alternative<All> all;
+ Alternative<Choice> choice;
+ Alternative<Sequence> sequence;
+
+ ComplexTypeContents()
+ : simple_content("simpleContent"),
+ complex_content("complexContent"),
+ group("group"),
+ all("all"),
+ choice("choice"),
+ sequence("sequence")
+ {}
+};
+
+struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>
+{
+ Optional<std::string> name;
+ Optional<bool> mixed;
+
+ Multiple<Attribute> attribute;
+ Multiple<Lazy<Element>> elements;
ComplexType()
- : attribute("xs:attribute"),
- //elements("xs:element"),
+ : name("name"),
+ attribute("xs:attribute"),
+ elements("xs:element"),
mixed("mixed")
{
- mixed = true;
}
};
-struct Element : public LLInitParam::Block<Element, Occurs>
+struct ElementContents : public LLInitParam::ChoiceBlock<ElementContents, Occurs>
{
- Mandatory<ComplexType> complexType;
- Mandatory<Name> name;
+ Alternative<SimpleType> simpleType;
+ Alternative<ComplexType> complexType;
- Element()
- : complexType("xs:complexType")
+ ElementContents()
+ : simpleType("simpleType"),
+ complexType("complexType")
{}
};
-struct Elements : public LLInitParam::Block<Elements, Occurs>
+struct Element : public LLInitParam::Block<Element, ElementContents>
{
- Multiple<Element> elements;
+ Optional<std::string> name,
+ ref,
+ type;
- Elements()
- : elements("xs:element")
+ Element()
+ : name("xs:name"),
+ ref("xs:ref"),
+ type("xs:type")
{}
};
@@ -164,28 +286,32 @@ struct Schema : public LLInitParam::Block<Schema>
{
private:
Mandatory<std::string> targetNamespace,
- xmlns;
+ xmlns,
+ xs;
public:
Optional<std::string> attributeFormDefault,
- elementFormDefault,
- xs;
+ elementFormDefault;
- Optional<Elements> elements;
+ Mandatory<Element> root_element;
void setNameSpace(const std::string& ns) {targetNamespace = ns; xmlns = ns;}
- Schema()
+ Schema(const std::string& ns = LLStringUtil::null)
: attributeFormDefault("attributeFormDefault"),
elementFormDefault("elementFormDefault"),
xs("xmlns:xs"),
targetNamespace("targetNamespace"),
xmlns("xmlns"),
- elements("xs:choice")
+ root_element("xs:element")
{
attributeFormDefault = "unqualified";
elementFormDefault = "qualified";
xs = "http://www.w3.org/2001/XMLSchema";
+ if (!ns.empty())
+ {
+ setNameSpace(ns);
+ };
}
};
@@ -214,22 +340,30 @@ LLXSDWriter::LLXSDWriter()
void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
{
+ Schema schema(xml_namespace);
+
+ schema.root_element.name = type_name;
+ Choice& choice = schema.root_element.complexType.choice;
+
+ choice.minOccurs = 0;
+ choice.maxOccurs = "unbounded";
+
mSchemaNode = node;
- node->setName("xs:schema");
- node->createChild("attributeFormDefault", true)->setStringValue("unqualified");
- node->createChild("elementFormDefault", true)->setStringValue("qualified");
- node->createChild("targetNamespace", true)->setStringValue(xml_namespace);
- node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema");
- node->createChild("xmlns", true)->setStringValue(xml_namespace);
-
- node = node->createChild("xs:complexType", false);
- node->createChild("name", true)->setStringValue(type_name);
- node->createChild("mixed", true)->setStringValue("true");
-
- mAttributeNode = node;
- mElementNode = node->createChild("xs:choice", false);
- mElementNode->createChild("minOccurs", true)->setStringValue("0");
- mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded");
+ //node->setName("xs:schema");
+ //node->createChild("attributeFormDefault", true)->setStringValue("unqualified");
+ //node->createChild("elementFormDefault", true)->setStringValue("qualified");
+ //node->createChild("targetNamespace", true)->setStringValue(xml_namespace);
+ //node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema");
+ //node->createChild("xmlns", true)->setStringValue(xml_namespace);
+
+ //node = node->createChild("xs:complexType", false);
+ //node->createChild("name", true)->setStringValue(type_name);
+ //node->createChild("mixed", true)->setStringValue("true");
+
+ //mAttributeNode = node;
+ //mElementNode = node->createChild("xs:choice", false);
+ //mElementNode->createChild("minOccurs", true)->setStringValue("0");
+ //mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded");
block.inspectBlock(*this);
// duplicate element choices