From c10832bb9ade5efa2a501cb3b39f769aa3024363 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Fri, 16 Sep 2011 11:57:57 -0700 Subject: added Flag as new param type... usage: will set the bar flag on foo LLSD foo; foo["bar"]; will set the bar flag on foo converted notifications unique to use flag --- indra/llxuixml/llinitparam.h | 115 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 12 deletions(-) (limited to 'indra/llxuixml/llinitparam.h') diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 9d0fe781ce..fd4482f592 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -289,20 +289,20 @@ 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(this); // get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class - return *const_cast - (reinterpret_cast + return *const_cast + (reinterpret_cast (my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset)); } private: - friend class BaseBlock; + friend BaseBlock; U32 mEnclosingBlockOffset:31; U32 mIsProvided:1; @@ -367,18 +367,16 @@ namespace LLInitParam typedef boost::unordered_map param_map_t; typedef std::vector param_list_t; - typedef std::list all_params_list_t; + typedef std::list all_params_list_t; typedef std::vector > 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 @@ -499,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(src); + self_t& dst_typed_param = static_cast(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(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(param); + const self_t* typed_diff_param = static_cast(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(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 @@ -1424,7 +1508,7 @@ namespace LLInitParam } }; - template + template class Block : public BASE_BLOCK { @@ -1520,6 +1604,13 @@ namespace LLInitParam }; + class Flag : public FlagBase + { + public: + Flag(const char* name) : FlagBase(name, DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr) + {} + }; + template > class Multiple : public TypedParam { -- cgit v1.2.3