summaryrefslogtreecommitdiff
path: root/indra/llxuixml/llinitparam.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llxuixml/llinitparam.h')
-rw-r--r--indra/llxuixml/llinitparam.h650
1 files changed, 368 insertions, 282 deletions
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 35c889b69f..183472450d 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -38,6 +38,9 @@
namespace LLInitParam
{
+ // used to indicate no matching value to a given name when parsing
+ struct Flag{};
+
template<typename T> const T& defaultValue() { static T value; return value; }
template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
@@ -65,6 +68,12 @@ namespace LLInitParam
static bool equals(const LLSD &a, const LLSD &b) { return false; }
};
+ template<>
+ struct ParamCompare<Flag, false>
+ {
+ static bool equals(const Flag& a, const Flag& b) { return false; }
+ };
+
// helper functions and classes
typedef ptrdiff_t param_handle_t;
@@ -78,6 +87,7 @@ namespace LLInitParam
void setValueName(const std::string& key) {}
std::string getValueName() const { return ""; }
+ std::string calcValueName(const T& value) const { return ""; }
void clearValueName() const {}
static bool getValueFromName(const std::string& name, T& value)
@@ -115,6 +125,22 @@ namespace LLInitParam
return mValueName;
}
+ std::string calcValueName(const T& value) const
+ {
+ value_name_map_t* map = getValueNames();
+ for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
+ it != end_it;
+ ++it)
+ {
+ if (ParamCompare<T>::equals(it->second, value))
+ {
+ return it->first;
+ }
+ }
+
+ return "";
+ }
+
void clearValueName() const
{
mValueName.clear();
@@ -188,13 +214,13 @@ namespace LLInitParam
}
};
- typedef std::vector<std::pair<std::string, S32> > name_stack_t;
- typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator> name_stack_range_t;
- typedef std::vector<std::string> possible_values_t;
+ typedef std::vector<std::pair<std::string, bool> > name_stack_t;
+ typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t;
+ typedef std::vector<std::string> possible_values_t;
typedef bool (*parser_read_func_t)(Parser& parser, void* output);
- typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&);
- typedef boost::function<void (const name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
+ typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
+ typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t;
typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t;
@@ -202,7 +228,6 @@ namespace LLInitParam
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
: mParseSilently(false),
- mParseGeneration(sNextParseGeneration),
mParserReadFuncs(&read_map),
mParserWriteFuncs(&write_map),
mParserInspectFuncs(&inspect_map)
@@ -219,7 +244,7 @@ namespace LLInitParam
return false;
}
- template <typename T> bool writeValue(const T& param, const 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 = mParserWriteFuncs->find(&typeid(T));
if (found_it != mParserWriteFuncs->end())
@@ -230,7 +255,7 @@ namespace LLInitParam
}
// dispatch inspection to registered inspection functions, for each parameter in a param block
- template <typename T> bool inspectValue(const name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
+ template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
{
parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
if (found_it != mParserInspectFuncs->end())
@@ -246,10 +271,6 @@ namespace LLInitParam
virtual void parserError(const std::string& message);
void setParseSilently(bool silent) { mParseSilently = silent; }
- S32 getParseGeneration() { return mParseGeneration; }
- S32 newParseGeneration() { return mParseGeneration = ++sNextParseGeneration; }
-
-
protected:
template <typename T>
void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
@@ -270,14 +291,8 @@ namespace LLInitParam
parser_read_func_map_t* mParserReadFuncs;
parser_write_func_map_t* mParserWriteFuncs;
parser_inspect_func_map_t* mParserInspectFuncs;
- S32 mParseGeneration;
-
- static S32 sNextParseGeneration;
};
- // used to indicate no matching value to a given name when parsing
- struct NoParamValue{};
-
class BaseBlock;
class Param
@@ -289,15 +304,15 @@ namespace LLInitParam
protected:
bool anyProvided() const { return mIsProvided; }
- Param(class BaseBlock* enclosing_block);
+ Param(BaseBlock* enclosing_block);
// store pointer to enclosing block as offset to reduce space and allow for quick copying
- class BaseBlock& enclosingBlock() const
+ 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<class BaseBlock*>
- (reinterpret_cast<const class BaseBlock*>
+ return *const_cast<BaseBlock*>
+ (reinterpret_cast<const BaseBlock*>
(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
}
@@ -318,7 +333,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&, S32);
+ typedef bool(*deserialize_func_t)(Param&, Parser&, const 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*);
@@ -343,7 +358,6 @@ namespace LLInitParam
validation_func_t mValidationFunc;
S32 mMinCount;
S32 mMaxCount;
- S32 mGeneration;
S32 mNumRefs;
UserData* mUserData;
};
@@ -367,18 +381,16 @@ namespace LLInitParam
typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
typedef std::vector<ParamDescriptorPtr> param_list_t;
- typedef std::list<ParamDescriptorPtr> all_params_list_t;
+ typedef std::list<ParamDescriptorPtr> all_params_list_t;
typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
param_map_t mNamedParams; // parameters with associated names
param_list_t mUnnamedParams; // parameters with_out_ associated names
param_validation_list_t mValidationList; // parameters that must be validated
all_params_list_t mAllParams; // all parameters, owns descriptors
-
- size_t mMaxParamOffset;
-
- EInitializationState mInitializationState; // whether or not static block data has been initialized
- class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
+ size_t mMaxParamOffset;
+ EInitializationState mInitializationState; // whether or not static block data has been initialized
+ BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
};
class BaseBlock
@@ -387,36 +399,36 @@ namespace LLInitParam
// "Multiple" constraint types, put here in root class to avoid ambiguity during use
struct AnyAmount
{
- static U32 minCount() { return 0; }
- static U32 maxCount() { return U32_MAX; }
+ enum { minCount = 0 };
+ enum { maxCount = U32_MAX };
};
template<U32 MIN_AMOUNT>
struct AtLeast
{
- static U32 minCount() { return MIN_AMOUNT; }
- static U32 maxCount() { return U32_MAX; }
+ enum { minCount = MIN_AMOUNT };
+ enum { maxCount = U32_MAX };
};
template<U32 MAX_AMOUNT>
struct AtMost
{
- static U32 minCount() { return 0; }
- static U32 maxCount() { return MAX_AMOUNT; }
+ enum { minCount = 0 };
+ enum { maxCount = MAX_AMOUNT };
};
template<U32 MIN_AMOUNT, U32 MAX_AMOUNT>
struct Between
{
- static U32 minCount() { return MIN_AMOUNT; }
- static U32 maxCount() { return MAX_AMOUNT; }
+ enum { minCount = MIN_AMOUNT };
+ enum { maxCount = MAX_AMOUNT };
};
template<U32 EXACT_COUNT>
struct Exactly
{
- static U32 minCount() { return EXACT_COUNT; }
- static U32 maxCount() { return EXACT_COUNT; }
+ enum { minCount = EXACT_COUNT };
+ enum { maxCount = EXACT_COUNT };
};
// this typedef identifies derived classes as being blocks
@@ -426,7 +438,7 @@ namespace LLInitParam
BaseBlock();
virtual ~BaseBlock();
- bool submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
+ bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
param_handle_t getHandleFromParam(const Param* param) const;
bool validateBlock(bool emit_errors = true) const;
@@ -452,8 +464,8 @@ namespace LLInitParam
S32 getLastChangeVersion() const { return mChangeVersion; }
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation);
- void serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
+ 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(); }
@@ -479,9 +491,9 @@ namespace LLInitParam
void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
- bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
{
- return mergeBlock(block_data, other, overwrite);
+ 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);
@@ -520,7 +532,7 @@ namespace LLInitParam
typedef const T& value_assignment_t;
ParamValue(): mValue() {}
- ParamValue(const T& other) : mValue(other) {}
+ ParamValue(value_assignment_t other) : mValue(other) {}
void setValue(value_assignment_t val)
{
@@ -537,6 +549,17 @@ namespace LLInitParam
return mValue;
}
+ operator value_assignment_t() const
+ {
+ return mValue;
+ }
+
+ value_assignment_t operator()() const
+ {
+ return mValue;
+ }
+
+
private:
T mValue;
};
@@ -549,10 +572,6 @@ namespace LLInitParam
public:
typedef const T& value_assignment_t;
- S32 mKeyVersion;
- mutable S32 mValidatedVersion;
- mutable bool mValidated; // lazy validation flag
-
ParamValue()
: T(),
mKeyVersion(0),
@@ -560,13 +579,12 @@ namespace LLInitParam
mValidated(false)
{}
- ParamValue(const T& other)
+ ParamValue(value_assignment_t other)
: T(other),
mKeyVersion(0),
mValidatedVersion(-1),
mValidated(false)
- {
- }
+ {}
void setValue(value_assignment_t val)
{
@@ -582,6 +600,22 @@ namespace LLInitParam
{
return *this;
}
+
+ operator value_assignment_t() const
+ {
+ return *this;
+ }
+
+ value_assignment_t operator()() const
+ {
+ return *this;
+ }
+
+ S32 mKeyVersion;
+
+ protected:
+ mutable S32 mValidatedVersion;
+ mutable bool mValidated; // lazy validation flag
};
template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
@@ -628,11 +662,11 @@ namespace LLInitParam
bool isProvided() const { return Param::anyProvided(); }
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ static bool deserializeParam(Param& param, Parser& parser, const 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
- if (name_stack.first == name_stack.second)
+ if (name_stack_range.first == name_stack_range.second)
{
if (parser.readValue(typed_param.getValue()))
{
@@ -671,7 +705,7 @@ namespace LLInitParam
if (!name_stack.empty())
{
- name_stack.back().second = parser.newParseGeneration();
+ name_stack.back().second = true;
}
std::string key = typed_param.getValueName();
@@ -682,10 +716,7 @@ namespace LLInitParam
{
if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
{
- if (!parser.writeValue(key, name_stack))
- {
- return;
- }
+ parser.writeValue(key, name_stack);
}
}
// then try to serialize value directly
@@ -693,7 +724,11 @@ namespace LLInitParam
{
if (!parser.writeValue(typed_param.getValue(), name_stack))
{
- return;
+ 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))
+ {
+ parser.writeValue(calculated_key, name_stack);
+ }
}
}
}
@@ -717,19 +752,6 @@ namespace LLInitParam
Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
- void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
- {
- if (!isProvided())
- {
- set(val, flag_as_provided);
- }
- }
-
- // implicit conversion
- operator value_assignment_t() const { return param_value_t::getValue(); }
- // explicit conversion
- value_assignment_t operator()() const { return param_value_t::getValue(); }
-
protected:
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
@@ -740,7 +762,6 @@ namespace LLInitParam
if (src_typed_param.isProvided()
&& (overwrite || !dst_typed_param.isProvided()))
{
- dst_typed_param.clearValueName();
dst_typed_param.set(src_typed_param.getValue());
return true;
}
@@ -780,11 +801,11 @@ namespace LLInitParam
}
}
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
{
self_t& typed_param = static_cast<self_t&>(param);
// attempt to parse block...
- if(typed_param.deserializeBlock(parser, name_stack, generation))
+ if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
{
typed_param.clearValueName();
typed_param.enclosingBlock().paramChanged(param, true);
@@ -820,7 +841,7 @@ namespace LLInitParam
if (!name_stack.empty())
{
- name_stack.back().second = parser.newParseGeneration();
+ name_stack.back().second = true;
}
std::string key = typed_param.getValueName();
@@ -870,18 +891,10 @@ namespace LLInitParam
Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
- void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
- {
- if (!isProvided())
- {
- set(val, flag_as_provided);
- }
- }
-
// propagate changed status up to enclosing block
/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
- ParamValue<T, NAME_VALUE_LOOKUP>::paramChanged(changed_param, user_provided);
+ param_value_t::paramChanged(changed_param, user_provided);
Param::enclosingBlock().paramChanged(*this, user_provided);
if (user_provided)
{
@@ -891,11 +904,6 @@ namespace LLInitParam
}
}
- // implicit conversion
- operator value_assignment_t() const { return param_value_t::getValue(); }
- // explicit conversion
- value_assignment_t operator()() const { return param_value_t::getValue(); }
-
protected:
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
@@ -905,8 +913,7 @@ namespace LLInitParam
if (src_typed_param.anyProvided())
{
- bool param_provided = src_typed_param.isProvided() && (overwrite || !dst_typed_param.isProvided());
- if (dst_typed_param.mergeBlockParam(param_provided, param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+ if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
{
dst_typed_param.clearValueName();
dst_typed_param.setProvided(true);
@@ -925,7 +932,7 @@ namespace LLInitParam
{
public:
typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_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;
@@ -953,12 +960,12 @@ namespace LLInitParam
bool isProvided() const { return Param::anyProvided(); }
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
{
self_t& typed_param = static_cast<self_t&>(param);
value_t value;
// no further names in stack, attempt to parse value now
- if (name_stack.first == name_stack.second)
+ if (name_stack_range.first == name_stack_range.second)
{
// attempt to read value directly
if (parser.readValue(value))
@@ -975,7 +982,7 @@ namespace LLInitParam
if (parser.readValue(name))
{
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, typed_param.mValues))
+ if (name_value_lookup_t::getValueFromName(name, value))
{
typed_param.add(value);
typed_param.mValues.back().setValueName(name);
@@ -998,14 +1005,19 @@ namespace LLInitParam
++it)
{
std::string key = it->getValue();
- name_stack.back().second = parser.newParseGeneration();
+ name_stack.back().second = true;
if(key.empty())
// not parsed via name values, write out value directly
{
- if (!parser.writeValue(*it, name_stack))
+ bool value_written = parser.writeValue(*it, name_stack);
+ if (!value_written)
{
- break;
+ std::string calculated_key = it->calcValueName(key);
+ if (!parser.writeValue(calculated_key, name_stack))
+ {
+ break;
+ }
}
}
else
@@ -1034,15 +1046,6 @@ namespace LLInitParam
Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
-
- void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
- {
- if (!isProvided())
- {
- set(val, flag_as_provided);
- }
- }
-
value_t& add()
{
mValues.push_back(param_value_t(value_t()));
@@ -1060,6 +1063,8 @@ namespace LLInitParam
// implicit conversion
operator value_assignment_t() const { return mValues; }
+ // explicit conversion
+ value_assignment_t operator()() const { return mValues; }
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
@@ -1111,14 +1116,13 @@ 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 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)
- : Param(block_descriptor.mCurrentBlockPtr),
- mLastParseGeneration(0)
+ : Param(block_descriptor.mCurrentBlockPtr)
{
std::copy(value.begin(), value.end(), back_inserter(mValues));
@@ -1138,13 +1142,12 @@ namespace LLInitParam
bool isProvided() const { return Param::anyProvided(); }
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
{
self_t& typed_param = static_cast<self_t&>(param);
bool new_value = false;
- if (generation != typed_param.mLastParseGeneration
- || typed_param.mValues.empty())
+ if (new_name || typed_param.mValues.empty())
{
new_value = true;
typed_param.mValues.push_back(value_t());
@@ -1153,12 +1156,8 @@ namespace LLInitParam
param_value_t& value = typed_param.mValues.back();
// attempt to parse block...
- if(value.deserializeBlock(parser, name_stack, generation))
+ if(value.deserializeBlock(parser, name_stack_range, new_name))
{
- if (new_value)
- { // successfully parsed new value, let's keep it
- typed_param.mLastParseGeneration = generation;
- }
typed_param.enclosingBlock().paramChanged(param, true);
typed_param.setProvided(true);
return true;
@@ -1172,11 +1171,6 @@ namespace LLInitParam
// try to parse a per type named value
if (name_value_lookup_t::getValueFromName(name, value.getValue()))
{
- if (new_value)
- { // successfully parsed new value, let's keep it
- typed_param.mLastParseGeneration = generation;
- }
-
typed_param.mValues.back().setValueName(name);
typed_param.mValues.back().mKeyVersion = value.getLastChangeVersion();
typed_param.enclosingBlock().paramChanged(param, true);
@@ -1204,7 +1198,7 @@ namespace LLInitParam
it != end_it;
++it)
{
- name_stack.back().second = parser.newParseGeneration();
+ name_stack.back().second = true;
std::string key = it->getValueName();
if (!key.empty() && it->mKeyVersion == it->getLastChangeVersion())
@@ -1233,14 +1227,6 @@ namespace LLInitParam
Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
- void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
- {
- if (!isProvided())
- {
- set(val, flag_as_provided);
- }
- }
-
value_t& add()
{
mValues.push_back(value_t());
@@ -1258,6 +1244,8 @@ namespace LLInitParam
// implicit conversion
operator value_assignment_t() const { return mValues; }
+ // explicit conversion
+ value_assignment_t operator()() const { return mValues; }
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
@@ -1308,15 +1296,13 @@ namespace LLInitParam
}
container_t mValues;
-
- S32 mLastParseGeneration;
};
template <typename DERIVED_BLOCK>
- class Choice : public BaseBlock
+ class ChoiceBlock : public BaseBlock
{
- typedef Choice<DERIVED_BLOCK> self_t;
- typedef Choice<DERIVED_BLOCK> enclosing_block_t;
+ typedef ChoiceBlock<DERIVED_BLOCK> self_t;
+ typedef ChoiceBlock<DERIVED_BLOCK> enclosing_block_t;
LOG_CLASS(self_t);
public:
@@ -1332,11 +1318,13 @@ namespace LLInitParam
return mergeBlock(selfBlockDescriptor(), other, false);
}
- bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const self_t& other, bool overwrite)
+ bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
{
- if (param_provided)
+ bool source_override = source_provided && (overwrite || !dest_provided);
+
+ if (source_override || source.mCurChoice == mCurChoice)
{
- return mergeBlock(block_data, other, overwrite);
+ return mergeBlock(block_data, source, overwrite);
}
return false;
}
@@ -1370,7 +1358,7 @@ namespace LLInitParam
virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
protected:
- Choice()
+ ChoiceBlock()
: mCurChoice(0)
{
BaseBlock::init(selfBlockDescriptor(), BaseBlock::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
@@ -1383,13 +1371,13 @@ namespace LLInitParam
class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
public:
- friend class Choice<DERIVED_BLOCK>;
+ 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;
- explicit Alternative(const char* name, value_assignment_t val = defaultValue<T>())
+ explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
mOriginalValue(val)
{
@@ -1404,10 +1392,19 @@ namespace LLInitParam
}
}
- Alternative& operator=(value_assignment_t val)
+ void choose()
+ {
+ static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
+ }
+
+ void chooseAs(value_assignment_t val)
+ {
+ super_t::set(val);
+ }
+
+ void operator=(value_assignment_t val)
{
super_t::set(val);
- return *this;
}
void operator()(typename super_t::value_assignment_t val)
@@ -1416,12 +1413,8 @@ namespace LLInitParam
}
operator value_assignment_t() const
- {
- if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
- {
- return super_t::getValue();
- }
- return mOriginalValue;
+ {
+ return (*this)();
}
value_assignment_t operator()() const
@@ -1566,7 +1559,7 @@ namespace LLInitParam
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::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
{}
Multiple& operator=(value_assignment_t val)
@@ -1584,98 +1577,8 @@ namespace LLInitParam
static bool validate(const Param* paramp)
{
U32 num_valid = ((super_t*)paramp)->numValidElements();
- return RANGE::minCount() <= num_valid && num_valid <= RANGE::maxCount();
- }
- };
-
- template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
- class Batch : private TypedParam<T, NAME_VALUE_LOOKUP, false>
- {
- public:
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<param_value_t>::value> super_t;
- typedef Batch<T, RANGE, NAME_VALUE_LOOKUP> self_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
- typedef typename super_t::value_t value_t;
-
- struct BatchDefaultValue : public ParamDescriptor::UserData
- {
- BatchDefaultValue(const T& value)
- : mValue(value)
- {}
-
- T mValue;
- };
-
- explicit Batch(const char* name, value_assignment_t val)
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
- mLastParseGeneration(-1)
- {
- BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
- if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
- {
- ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this);
-
- if (param_descriptorp)
- {
- param_descriptorp->mDeserializeFunc = &deserializeParam;
- param_descriptorp->mUserData = new BatchDefaultValue(new param_value_t(val));
- }
- }
- }
-
- explicit Batch(const char* name = "")
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, defaultValue<T>(), NULL, 0, 1),
- mLastParseGeneration(-1)
- {
- BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
- if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
- {
- ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this);
-
- if (param_descriptorp)
- {
- param_descriptorp->mDeserializeFunc = &deserializeParam;
- }
- }
- }
-
- Batch& operator=(value_assignment_t val)
- {
- set(val);
- return *this;
- }
-
- DERIVED_BLOCK& operator()(value_assignment_t val)
- {
- super_t::set(val);
- return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;
}
-
- using super_t::operator();
-
- private:
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
- {
- self_t& typed_param = static_cast<self_t&>(param);
-
- if (generation != typed_param.mLastParseGeneration)
- {
- ParamDescriptorPtr descriptor = typed_param.enclosingBlock().findParamDescriptor(param);
- if (descriptor && static_cast<BatchDefaultValue*>(descriptor->mUserData))
- {
- static_cast<param_value_t&>(typed_param) = (static_cast<BatchDefaultValue*>(descriptor->mUserData))->mValue;
- }
- else
- {
- static_cast<param_value_t&>(typed_param) = param_value_t(value_t());
- }
- typed_param.mLastParseGeneration = generation;
- }
- return super_t::deserializeParam(param, parser, name_stack, generation);
- }
-
- S32 mLastParseGeneration;
};
class Deprecated : public Param
@@ -1699,9 +1602,9 @@ namespace LLInitParam
}
}
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
{
- if (name_stack.first == name_stack.second)
+ if (name_stack_range.first == name_stack_range.second)
{
//std::string message = llformat("Deprecated value %s ignored", getName().c_str());
//parser.parserWarning(message);
@@ -1712,6 +1615,7 @@ namespace LLInitParam
}
};
+ // different semantics for documentation purposes, but functionally identical
typedef Deprecated Ignored;
protected:
@@ -1720,8 +1624,173 @@ namespace LLInitParam
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
}
+
+ template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool 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)
+ {
+ if (!param.isProvided())
+ {
+ param.set(value, false);
+ }
+ }
+
};
+ template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+ class BatchBlock
+ : public Block<DERIVED_BLOCK, BASE_BLOCK>
+ {
+ public:
+ typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
+ typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
+
+ BatchBlock()
+ {}
+
+ 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();
+ }
+ return super_t::deserializeBlock(p, name_stack_range, new_name);
+ }
+
+ bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+ {
+ if (overwrite)
+ {
+ *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
+ // merge individual parameters into destination
+ return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
+ }
+ return false;
+ }
+ protected:
+ static const DERIVED_BLOCK& defaultBatchValue()
+ {
+ static DERIVED_BLOCK default_value;
+ return default_value;
+ }
+ };
+
+ // 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>
+ {
+ public:
+ typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
+ typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& value_assignment_t;
+
+ ParamValue()
+ : block_t(),
+ mKeyVersion(0),
+ mValidatedVersion(-1),
+ mValidated(false)
+ {}
+
+ ParamValue(value_assignment_t other)
+ : block_t(other),
+ mKeyVersion(0),
+ mValidatedVersion(-1),
+ mValidated(false)
+ {
+ }
+
+ void setValue(value_assignment_t val)
+ {
+ *this = val;
+ }
+
+ value_assignment_t getValue() const
+ {
+ return *this;
+ }
+
+ BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue()
+ {
+ return *this;
+ }
+
+ operator value_assignment_t() const
+ {
+ return *this;
+ }
+
+ value_assignment_t operator()() const
+ {
+ return *this;
+ }
+
+ S32 mKeyVersion;
+
+ protected:
+ mutable S32 mValidatedVersion;
+ mutable bool mValidated; // lazy validation flag
+ };
+
+ template <>
+ class ParamValue <LLSD,
+ TypeValues<LLSD>,
+ false>
+ : public TypeValues<LLSD>,
+ public BaseBlock
+ {
+ public:
+ typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t;
+ typedef const LLSD& value_assignment_t;
+
+ ParamValue()
+ : mKeyVersion(0),
+ mValidatedVersion(-1),
+ mValidated(false)
+ {}
+
+ ParamValue(value_assignment_t other)
+ : mValue(other),
+ mKeyVersion(0),
+ mValidatedVersion(-1),
+ mValidated(false)
+ {}
+
+ void setValue(value_assignment_t val) { mValue = val; }
+
+ value_assignment_t getValue() const { return mValue; }
+ LLSD& getValue() { return mValue; }
+
+ 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);
+ 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
+ {
+ //TODO: implement LLSD params as schema type Any
+ return true;
+ }
+
+ protected:
+ mutable S32 mValidatedVersion;
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack);
+
+ LLSD mValue;
+ };
+
template<typename T>
class CustomParamValue
: public Block<ParamValue<T, TypeValues<T> > >,
@@ -1744,39 +1813,35 @@ namespace LLInitParam
: mValue(value),
mValueAge(VALUE_AUTHORITATIVE),
mKeyVersion(0),
- mValidatedVersion(-1)
+ mValidatedVersion(-1),
+ mValidated(false)
{}
- bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack, S32 generation)
+ bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)
{
derived_t& typed_param = static_cast<derived_t&>(*this);
- // type to apply parse direct value T
- if (name_stack.first == name_stack.second)
+ // try to parse direct value T
+ if (name_stack_range.first == name_stack_range.second)
{
if(parser.readValue(typed_param.mValue))
{
- typed_param.clearValueName();
typed_param.mValueAge = VALUE_AUTHORITATIVE;
- typed_param.updateBlockFromValue();
+ typed_param.updateBlockFromValue(false);
+
+ typed_param.clearValueName();
return true;
}
}
// fall back on parsing block components for T
- // if we deserialized at least one component...
- if (typed_param.BaseBlock::deserializeBlock(parser, name_stack, generation))
- {
- return true;
- }
-
- return false;
+ return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);
}
- void serializeBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const
+ void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
{
- const self_t& typed_param = static_cast<const self_t&>(*this);
- const self_t* diff_param = static_cast<const self_t*>(diff_block);
+ 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();
@@ -1801,7 +1866,20 @@ namespace LLInitParam
// be exported as <color green="1"/>, since it was probably the intent of the user to
// be specific about the RGB color values. This also fixes an issue where we distinguish
// between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
- block_t::serializeBlock(parser, name_stack, NULL);
+
+ if (typed_param.mValueAge == VALUE_AUTHORITATIVE)
+ {
+ // if the value is authoritative but the parser doesn't accept the value type
+ // go ahead and make a copy, and splat the value out to its component params
+ // and serialize those params
+ derived_t copy(typed_param);
+ copy.updateBlockFromValue(true);
+ copy.block_t::serializeBlock(parser, name_stack, NULL);
+ }
+ else
+ {
+ block_t::serializeBlock(parser, name_stack, NULL);
+ }
}
}
}
@@ -1850,7 +1928,7 @@ namespace LLInitParam
{
BaseBlock::paramChanged(changed_param, user_provided);
if (user_provided)
- {
+ {
// a parameter changed, so our value is out of date
mValueAge = VALUE_NEEDS_UPDATE;
}
@@ -1863,7 +1941,7 @@ namespace LLInitParam
mValueAge = VALUE_AUTHORITATIVE;
mValue = val;
typed_param.clearValueName();
- static_cast<derived_t*>(const_cast<self_t*>(this))->updateBlockFromValue();
+ static_cast<derived_t*>(this)->updateBlockFromValue(false);
}
value_assignment_t getValue() const
@@ -1878,6 +1956,16 @@ namespace LLInitParam
return mValue;
}
+ operator value_assignment_t() const
+ {
+ return getValue();
+ }
+
+ value_assignment_t operator()() const
+ {
+ return getValue();
+ }
+
S32 mKeyVersion;
protected:
@@ -1888,37 +1976,35 @@ namespace LLInitParam
mValue = value;
}
- bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
{
- if (param_provided)
- {
- return mergeBlock(block_data, other, overwrite);
- }
- return false;
- }
+ bool source_override = source_provided && (overwrite || !dst_provided);
- bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
- {
- const derived_t& src_typed_param = static_cast<const derived_t&>(other);
+ const derived_t& src_typed_param = static_cast<const derived_t&>(source);
- if (src_typed_param.mValueAge == VALUE_AUTHORITATIVE)
+ if (source_override && src_typed_param.mValueAge == VALUE_AUTHORITATIVE)
{
// copy value over
setValue(src_typed_param.getValue());
return true;
}
- else
+ // merge individual parameters into destination
+ if (mValueAge == VALUE_AUTHORITATIVE)
{
- // merge individual parameters into destination
- return block_t::mergeBlock(block_t::selfBlockDescriptor(), src_typed_param, overwrite);
+ static_cast<derived_t*>(this)->updateBlockFromValue(dst_provided);
}
+ return mergeBlock(block_data, source, overwrite);
+ }
+
+ bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
+ {
+ return block_t::mergeBlock(block_data, source, overwrite);
}
mutable S32 mValidatedVersion;
mutable bool mValidated; // lazy validation flag
private:
-
mutable T mValue;
mutable EValueAge mValueAge;
};