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.h209
1 files changed, 144 insertions, 65 deletions
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index a853999e94..69dcd474f7 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -34,6 +34,8 @@
#include <boost/unordered_map.hpp>
#include <boost/shared_ptr.hpp>
+#include "llerror.h"
+
namespace LLInitParam
{
template<typename T> const T& defaultValue() { static T value; return value; }
@@ -287,23 +289,24 @@ 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));
}
private:
friend class BaseBlock;
- U16 mEnclosingBlockOffset;
- bool mIsProvided;
+ U32 mEnclosingBlockOffset:31;
+ U32 mIsProvided:1;
+
};
// various callbacks and constraints associated with an individual param
@@ -364,18 +367,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
@@ -496,6 +497,92 @@ namespace LLInitParam
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
};
+ class BaseBlockWithFlags : public BaseBlock
+ {
+ public:
+ class FlagBase : public Param
+ {
+ public:
+ typedef FlagBase self_t;
+
+ FlagBase(const char* name, BaseBlock* enclosing_block) : Param(enclosing_block)
+ {
+ if (LL_UNLIKELY(enclosing_block->mostDerivedBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ enclosing_block->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ NULL,
+ &inspectParam,
+ 0, 1));
+ BaseBlock::addParam(enclosing_block->mostDerivedBlockDescriptor(), param_descriptor, name);
+ }
+ }
+
+ bool isProvided() const { return anyProvided(); }
+
+ private:
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (src_typed_param.isProvided()
+ && (overwrite || !dst_typed_param.isProvided()))
+ {
+ dst.setProvided(true);
+ return true;
+ }
+ return false;
+ }
+
+ 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);
+
+ // no further names in stack, parse value now
+ if (name_stack.first == name_stack.second)
+ {
+ typed_param.setProvided(true);
+ typed_param.enclosingBlock().paramChanged(param, true);
+ return true;
+ }
+
+ return false;
+ }
+
+ 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);
+ const self_t* typed_diff_param = static_cast<const self_t*>(diff_param);
+
+ if (!typed_param.isProvided()) return;
+
+ if (!name_stack.empty())
+ {
+ name_stack.back().second = parser.newParseGeneration();
+ }
+
+ // then try to serialize value directly
+ if (!typed_diff_param || !typed_diff_param->isProvided())
+ {
+ if (!parser.writeValue(NoParamValue(), name_stack))
+ {
+ return;
+ }
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ // tell parser about our actual type
+ parser.inspectValue<NoParamValue>(name_stack, min_count, max_count, NULL);
+ }
+ };
+ };
+
// these templates allow us to distinguish between template parameters
// that derive from BaseBlock and those that don't
template<typename T, typename Void = void>
@@ -714,14 +801,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
@@ -737,7 +816,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;
}
@@ -867,18 +945,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)
{
@@ -1031,15 +1101,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()));
@@ -1230,14 +1291,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());
@@ -1455,7 +1508,7 @@ namespace LLInitParam
}
};
- template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+ template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlockWithFlags>
class Block
: public BASE_BLOCK
{
@@ -1551,6 +1604,13 @@ namespace LLInitParam
};
+ class Flag : public BaseBlockWithFlags::FlagBase
+ {
+ public:
+ Flag(const char* name) : FlagBase(name, DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
+ {}
+ };
+
template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
{
@@ -1717,6 +1777,17 @@ 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 T>
@@ -1741,39 +1812,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)
{
derived_t& typed_param = static_cast<derived_t&>(*this);
- // type to apply parse direct value T
+ // try to parse direct value T
if (name_stack.first == name_stack.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, generation);
}
void serializeBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), 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();
@@ -1798,7 +1865,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);
+ }
}
}
}
@@ -1847,7 +1927,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;
}
@@ -1860,7 +1940,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
@@ -1915,7 +1995,6 @@ namespace LLInitParam
mutable bool mValidated; // lazy validation flag
private:
-
mutable T mValue;
mutable EValueAge mValueAge;
};