diff options
Diffstat (limited to 'indra/llxuixml/llinitparam.h')
-rw-r--r-- | indra/llxuixml/llinitparam.h | 144 |
1 files changed, 71 insertions, 73 deletions
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 9fb464ca7b..c9c1d4af90 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -1,5 +1,5 @@ /** - * @file llinitparam.h +f * @file llinitparam.h * @brief parameter block abstraction for creating complex objects and * parsing construction parameters from xml and LLSD * @@ -300,14 +300,14 @@ namespace LLInitParam 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)mEnclosingBlockOffset)); + reinterpret_cast<const BaseBlock*>(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset)); } private: friend class BaseBlock; bool mIsProvided; - S16 mEnclosingBlockOffset; + U16 mEnclosingBlockOffset; }; // various callbacks and constraints associated with an individual param @@ -321,13 +321,13 @@ namespace LLInitParam typedef bool(*validation_func_t)(const Param*); ParamDescriptor(param_handle_t p, - merge_func_t merge_func, - deserialize_func_t deserialize_func, - serialize_func_t serialize_func, - validation_func_t validation_func, - inspect_func_t inspect_func, - S32 min_count, - S32 max_count) + merge_func_t merge_func, + deserialize_func_t deserialize_func, + serialize_func_t serialize_func, + validation_func_t validation_func, + inspect_func_t inspect_func, + S32 min_count, + S32 max_count) : mParamHandle(p), mMergeFunc(merge_func), mDeserializeFunc(deserialize_func), @@ -336,6 +336,7 @@ namespace LLInitParam mInspectFunc(inspect_func), mMinCount(min_count), mMaxCount(max_count), + mGeneration(0), mNumRefs(0) {} @@ -371,7 +372,8 @@ namespace LLInitParam public: BlockDescriptor() : mMaxParamOffset(0), - mInitializationState(UNINITIALIZED) + mInitializationState(UNINITIALIZED), + mCurrentBlockPtr(NULL) {} typedef enum e_initialization_state @@ -405,6 +407,41 @@ namespace LLInitParam class BaseBlock { public: + // "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; } + }; + + template<U32 MIN_AMOUNT> + struct AtLeast + { + static U32 minCount() { return MIN_AMOUNT; } + static U32 maxCount() { return U32_MAX; } + }; + + template<U32 MAX_AMOUNT> + struct AtMost + { + static U32 minCount() { return 0; } + static U32 maxCount() { return MAX_AMOUNT; } + }; + + template<U32 MIN_AMOUNT, U32 MAX_AMOUNT> + struct Between + { + static U32 minCount() { return MIN_AMOUNT; } + static U32 maxCount() { return MAX_AMOUNT; } + }; + + template<U32 EXACT_COUNT> + struct Exactly + { + static U32 minCount() { return EXACT_COUNT; } + static U32 maxCount() { return EXACT_COUNT; } + }; + // this typedef identifies derived classes as being blocks typedef void baseblock_base_class_t; LOG_CLASS(BaseBlock); @@ -415,7 +452,7 @@ namespace LLInitParam bool submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent=false); param_handle_t getHandleFromParam(const Param* param) const; - bool validateBlock(bool silent = false) const; + bool validateBlock(bool emit_errors = true) const; Param* getParamFromHandle(const param_handle_t param_handle) { @@ -435,7 +472,6 @@ namespace LLInitParam // Blocks can override this to do custom tracking of changes virtual void setLastChangedParam(const Param& last_param, bool user_provided); - const Param* getLastChangedParam() const { return mLastChangedParam ? getParamFromHandle(mLastChangedParam) : NULL; } S32 getLastChangeVersion() const { return mChangeVersion; } bool isDefault() const { return mChangeVersion == 0; } @@ -464,13 +500,9 @@ namespace LLInitParam // take all provided params from other and apply to self - bool overwriteFromImpl(BlockDescriptor& block_data, const BaseBlock& other); - - // take all provided params that are not already provided, and apply to self - bool fillFromImpl(BlockDescriptor& block_data, const BaseBlock& other); + bool merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite); // can be updated in getters - mutable param_handle_t mLastChangedParam; mutable S32 mChangeVersion; BlockDescriptor* mBlockDescriptor; // most derived block descriptor @@ -770,7 +802,7 @@ namespace LLInitParam if (Param::getProvided() && mData.mValidatedVersion < T::getLastChangeVersion()) { // a sub-block is "provided" when it has been filled in enough to be valid - mData.mValidated = T::validateBlock(true); + mData.mValidated = T::validateBlock(false); mData.mValidatedVersion = T::getLastChangeVersion(); } return Param::getProvided() && mData.mValidated; @@ -1201,7 +1233,7 @@ namespace LLInitParam it != mValues.end(); ++it) { - if(it->validateBlock(true)) count++; + if(it->validateBlock(false)) count++; } return count; } @@ -1251,7 +1283,7 @@ namespace LLInitParam bool overwriteFrom(const self_t& other) { mCurChoice = other.mCurChoice; - return BaseBlock::overwriteFromImpl(blockDescriptor(), other); + return BaseBlock::merge(blockDescriptor(), other, true); } // take all provided params that are not already provided, and apply to self @@ -1365,40 +1397,6 @@ namespace LLInitParam } }; - struct AnyAmount - { - static U32 minCount() { return 0; } - static U32 maxCount() { return U32_MAX; } - }; - - template<U32 MIN_AMOUNT> - struct AtLeast - { - static U32 minCount() { return MIN_AMOUNT; } - static U32 maxCount() { return U32_MAX; } - }; - - template<U32 MAX_AMOUNT> - struct AtMost - { - static U32 minCount() { return 0; } - static U32 maxCount() { return MAX_AMOUNT; } - }; - - template<U32 MIN_AMOUNT, U32 MAX_AMOUNT> - struct Between - { - static U32 minCount() { return MIN_AMOUNT; } - static U32 maxCount() { return MAX_AMOUNT; } - }; - - template<U32 EXACT_COUNT> - struct Exactly - { - static U32 minCount() { return EXACT_COUNT; } - static U32 maxCount() { return EXACT_COUNT; } - }; - template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock> class Block : public BASE_BLOCK @@ -1412,13 +1410,13 @@ namespace LLInitParam // take all provided params from other and apply to self bool overwriteFrom(const self_t& other) { - return BaseBlock::overwriteFromImpl(blockDescriptor(), other); + return BaseBlock::merge(blockDescriptor(), other, true); } // take all provided params that are not already provided, and apply to self bool fillFrom(const self_t& other) { - return BaseBlock::fillFromImpl(blockDescriptor(), other); + return BaseBlock::merge(blockDescriptor(), other, false); } protected: Block() @@ -1491,7 +1489,7 @@ namespace LLInitParam }; - template <typename T, typename RANGE = AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> > + template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> > class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true> { public: @@ -1709,9 +1707,9 @@ namespace LLInitParam // if cached value is stale, regenerate from params if (Param::getProvided() && mData.mLastParamVersion < BaseBlock::getLastChangeVersion()) { - if (block_t::validateBlock(true)) + if (block_t::validateBlock(false)) { - mData.mValue = static_cast<const DERIVED*>(this)->getValueFromBlock(); + static_cast<const DERIVED*>(this)->setValueFromBlock(); // clear stale keyword associated with old value mData.clearKey(); mData.mLastParamVersion = BaseBlock::getLastChangeVersion(); @@ -1731,12 +1729,14 @@ namespace LLInitParam void set(value_assignment_t val, bool flag_as_provided = true) { Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); + // set param version number to be up to date, so we ignore block contents mData.mLastParamVersion = BaseBlock::getLastChangeVersion(); mData.mValue = val; mData.clearKey(); setProvided(flag_as_provided); + static_cast<DERIVED*>(this)->setBlockFromValue(); } void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) @@ -1766,9 +1766,9 @@ namespace LLInitParam if (Param::getProvided() && (mData.mLastParamVersion < BaseBlock::getLastChangeVersion())) { // go ahead and issue warnings at this point if any param is invalid - if(block_t::validateBlock(false)) + if(block_t::validateBlock(true)) { - mData.mValue = static_cast<const DERIVED*>(this)->getValueFromBlock(); + static_cast<const DERIVED*>(this)->setValueFromBlock(); mData.clearKey(); mData.mLastParamVersion = BaseBlock::getLastChangeVersion(); } @@ -1794,25 +1794,23 @@ namespace LLInitParam private: static bool mergeWith(Param& dst, const Param& src, bool overwrite) { - const self_t& src_param = static_cast<const self_t&>(src); + const self_t& src_typed_param = static_cast<const self_t&>(src); self_t& dst_typed_param = static_cast<self_t&>(dst); - if (src_param.isProvided() + if (src_typed_param.isProvided() && (overwrite || !dst_typed_param.isProvided())) { // assign individual parameters - if (overwrite) - { - dst_typed_param.BaseBlock::overwriteFromImpl(block_t::blockDescriptor(), src_param); - } - else - { - dst_typed_param.BaseBlock::fillFromImpl(block_t::blockDescriptor(), src_param); - } + dst_typed_param.BaseBlock::merge(block_t::blockDescriptor(), src_typed_param, overwrite); + // then copy actual value - dst_typed_param.mData.mValue = src_param.get(); + dst_typed_param.mData.mValue = src_typed_param.get(); dst_typed_param.mData.clearKey(); dst_typed_param.setProvided(true); + + // Propagate value back to block params since the value was updated during this merge. + // This will result in mData.mValue and the block params being in sync. + static_cast<DERIVED&>(dst_typed_param).setBlockFromValue(); return true; } return false; |