Commits

Merov Linden  committed 42a5a5d Merge

merge leslie changes

  • Participants
  • Parent commits 02c473b, 52017e5

Comments (0)

Files changed (19)

File indra/llui/llloadingindicator.cpp

 //static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");
 
 ///////////////////////////////////////////////////////////////////////////////
-// LLLoadingIndicator::Data class
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Pre-loaded images shared by all instances of the widget
- */
-class LLLoadingIndicator::Data: public LLSingleton<LLLoadingIndicator::Data>
-{
-public:
-	/*virtual*/ void		initSingleton(); // from LLSingleton
-
-	LLPointer<LLUIImage>	getNextImage(S8& idx) const;
-	U8						getImagesCount() const	{ return NIMAGES; }
-private:
-
-	static const U8			NIMAGES = 12;
-	LLPointer<LLUIImage>	mImages[NIMAGES];
-};
-
-// virtual
-// Called right after the instance gets constructed.
-void LLLoadingIndicator::Data::initSingleton()
-{
-	// Load images.
-	for (U8 i = 0; i < NIMAGES; ++i)
-	{
-		std::string img_name = llformat("Progress_%d", i+1);
-		mImages[i] = LLUI::getUIImage(img_name, 0);
-		llassert(mImages[i]);
-	}
-}
-
-LLPointer<LLUIImage> LLLoadingIndicator::Data::getNextImage(S8& idx) const
-{
-	// Calculate next index, performing array bounds checking.
-	idx = (idx >= NIMAGES || idx < 0) ? 0 : (idx + 1) % NIMAGES; 
-	return mImages[idx];
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // LLLoadingIndicator class
 ///////////////////////////////////////////////////////////////////////////////
 
 LLLoadingIndicator::LLLoadingIndicator(const Params& p)
-:	LLUICtrl(p)
-	, mRotationsPerSec(p.rotations_per_sec > 0 ? p.rotations_per_sec : 1.0f)
-	, mCurImageIdx(-1)
+:	LLUICtrl(p), 
+	mImagesPerSec(p.images_per_sec > 0 ? p.images_per_sec : 1.0f), 
+	mCurImageIdx(0)
 {
-	// Select initial image.
-	mCurImagep = Data::instance().getNextImage(mCurImageIdx);
+}
+
+void LLLoadingIndicator::initFromParams(const Params& p)
+{
+	for (LLInitParam::ParamIterator<LLUIImage*>::const_iterator it = p.images().image.begin(), end_it = p.images().image.end();
+		it != end_it;
+		++it)
+	{
+		mImages.push_back(it->getValue());
+	}
 
 	// Start timer for switching images.
 	start();
 	if (mImageSwitchTimer.getStarted() && mImageSwitchTimer.hasExpired())
 	{
 		// Switch to the next image.
-		mCurImagep = Data::instance().getNextImage(mCurImageIdx);
+		if (!mImages.empty())
+		{
+			mCurImageIdx = (mCurImageIdx + 1) % mImages.size();
+		}
 
 		// Restart timer.
 		start();
 	}
 
+	LLUIImagePtr cur_image = mImages.empty() ? LLUIImagePtr(NULL) : mImages[mCurImageIdx];
+
 	// Draw current image.
-	if( mCurImagep.notNull() )
+	if( cur_image.notNull() )
 	{
-		mCurImagep->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha);
+		cur_image->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha);
 	}
 
 	LLUICtrl::draw();
 void LLLoadingIndicator::start()
 {
 	mImageSwitchTimer.start();
-	F32 period = 1.0f / (Data::instance().getImagesCount() * mRotationsPerSec);
+	F32 period = 1.0f / (mImages.size() * mImagesPerSec);
 	mImageSwitchTimer.setTimerExpirySec(period);
 }

File indra/llui/llloadingindicator.h

 /**
  * Perpetual loading indicator (a la MacOSX or YouTube)
  * 
- * Number of rotations per second can be overriden
- * with the "roations_per_sec" parameter.
+ * Number of rotations per second can be overridden
+ * with the "images_per_sec" parameter.
  * 
  * Can start/stop spinning.
  * 
 {
 	LOG_CLASS(LLLoadingIndicator);
 public:
+
+	struct Images : public LLInitParam::Block<Images>
+	{
+		Multiple<LLUIImage*>	image;
+
+		Images()
+		:	image("image")
+		{}
+	};
+
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
-		Optional<F32>	rotations_per_sec;
+		Optional<F32>			images_per_sec;
+		Batch<Images>			images;
+
 		Params()
-		:	rotations_per_sec("rotations_per_sec", 1.0f)
+		:	images_per_sec("images_per_sec", 1.0f),
+			images("images")
 		{}
 	};
 
 
 private:
 	LLLoadingIndicator(const Params&);
+	void initFromParams(const Params&);
+
 	friend class LLUICtrlFactory;
 
-	class Data;
+	F32						mImagesPerSec;
+	S8						mCurImageIdx;
+	LLFrameTimer			mImageSwitchTimer;
 
-	F32						mRotationsPerSec;
-	S8						mCurImageIdx;
-	LLPointer<LLUIImage>	mCurImagep;
-	LLFrameTimer			mImageSwitchTimer;
+	std::vector<LLUIImagePtr> mImages;
 };
 
 #endif // LL_LLLOADINGINDICATOR_H

File indra/llui/llui.cpp

 {
 	if(sImageProvider)
 	{
-		sImageProvider->cleanUp();
-	}
+	sImageProvider->cleanUp();
+}
 }
 
 void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups)
 
 namespace LLInitParam
 {
-	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-	:	super_t(descriptor, name, value, func, min_count, max_count),
+	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	:	super_t(color),
 		red("red"),
 		green("green"),
 		blue("blue"),
 		alpha("alpha"),
 		control("")
 	{
-		setBlockFromValue();
+		updateBlockFromValue();
 	}
 
-	void TypedParam<LLUIColor>::setValueFromBlock() const
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
 	{
 		if (control.isProvided())
 		{
-			mData.mValue = LLUIColorTable::instance().getColor(control);
+			updateValue(LLUIColorTable::instance().getColor(control));
 		}
 		else
 		{
-			mData.mValue = LLColor4(red, green, blue, alpha);
+			updateValue(LLColor4(red, green, blue, alpha));
 		}
 	}
 	
-	void TypedParam<LLUIColor>::setBlockFromValue()
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
 	{
-		LLColor4 color = mData.mValue.get();
+		LLColor4 color = getValue();
 		red.set(color.mV[VRED], false);
 		green.set(color.mV[VGREEN], false);
 		blue.set(color.mV[VBLUE], false);
 		control.set("", false);
 	}
 
-	void TypeValues<LLUIColor>::declareValues()
-	{
-		declare("white", LLColor4::white);
-		declare("black", LLColor4::black);
-		declare("red", LLColor4::red);
-		declare("green", LLColor4::green);
-		declare("blue", LLColor4::blue);
-	}
-
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
 	{
 		return !(a->getFontDesc() < b->getFontDesc())
 			&& !(b->getFontDesc() < a->getFontDesc());
 	}
 
-	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-	:	super_t(descriptor, _name, value, func, min_count, max_count),
+	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	:	super_t(fontp),
 		name("name"),
 		size("size"),
 		style("style")
 	{
-		setBlockFromValue();
+		if (!fontp)
+		{
+			updateValue(LLFontGL::getFontDefault());
+		}
 		addSynonym(name, "");
-		setBlockFromValue();
+		updateBlockFromValue();
 	}
 
-	void TypedParam<const LLFontGL*>::setValueFromBlock() const
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
 	{
 		const LLFontGL* res_fontp = LLFontGL::getFontByName(name);
 		if (res_fontp)
 		{
-			mData.mValue = res_fontp;
+			updateValue(res_fontp);
 			return;
 		}
 
 		const LLFontGL* fontp = LLFontGL::getFont(desc);
 		if (fontp)
 		{
-			mData.mValue = fontp;
-		}		
+			updateValue(fontp);
+		}
+		else
+		{
+			updateValue(LLFontGL::getFontDefault());
+		}
 	}
 	
-	void TypedParam<const LLFontGL*>::setBlockFromValue()
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
 	{
-		if (mData.mValue)
+		if (getValue())
 		{
-			name.set(LLFontGL::nameFromFont(mData.mValue), false);
-			size.set(LLFontGL::sizeFromFont(mData.mValue), false);
-			style.set(LLFontGL::getStringFromStyle(mData.mValue->getFontDesc().getStyle()), false);
+			name.set(LLFontGL::nameFromFont(getValue()), false);
+			size.set(LLFontGL::sizeFromFont(getValue()), false);
+			style.set(LLFontGL::getStringFromStyle(getValue()->getFontDesc().getStyle()), false);
 		}
 	}
 
-	TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-	:	super_t(descriptor, name, value, func, min_count, max_count),
+	ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect)
+	:	super_t(rect),
 		left("left"),
 		top("top"),
 		right("right"),
 		width("width"),
 		height("height")
 	{
-		setBlockFromValue();
+		updateBlockFromValue();
 	}
 
-	void TypedParam<LLRect>::setValueFromBlock() const
+	void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()
 	{
 		LLRect rect;
 
 			rect.mBottom = bottom;
 			rect.mTop = top;
 		}
-		mData.mValue = rect;
+		updateValue(rect);
 	}
 	
-	void TypedParam<LLRect>::setBlockFromValue()
+	void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue()
 	{
 		// because of the ambiguity in specifying a rect by position and/or dimensions
 		// we clear the "provided" flag so that values from xui/etc have priority
 		// over those calculated from the rect object
 
-		left.set(mData.mValue.mLeft, false);
-		right.set(mData.mValue.mRight, false);
-		bottom.set(mData.mValue.mBottom, false);
-		top.set(mData.mValue.mTop, false);
-		width.set(mData.mValue.getWidth(), false);
-		height.set(mData.mValue.getHeight(), false);
+		LLRect& value = getValue();
+		left.set(value.mLeft, false);
+		right.set(value.mRight, false);
+		bottom.set(value.mBottom, false);
+		top.set(value.mTop, false);
+		width.set(value.getWidth(), false);
+		height.set(value.getHeight(), false);
 	}
 
-	TypedParam<LLCoordGL>::TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-	:	super_t(descriptor, name, value, func, min_count, max_count),
+	ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord)
+	:	super_t(coord),
 		x("x"),
 		y("y")
 	{
-		setBlockFromValue();
+		updateBlockFromValue();
 	}
 
-	void TypedParam<LLCoordGL>::setValueFromBlock() const
+	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()
 	{
-		mData.mValue.set(x, y);
+		updateValue(LLCoordGL(x, y));
 	}
 	
-	void TypedParam<LLCoordGL>::setBlockFromValue()
+	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue()
 	{
-		x.set(mData.mValue.mX, false);
-		y.set(mData.mValue.mY, false);
+		x.set(getValue().mX, false);
+		y.set(getValue().mY, false);
 	}
 
 

File indra/llui/llui.h

 namespace LLInitParam
 {
 	template<>
-	class TypedParam<LLRect> 
-	:	public BlockValue<LLRect>
+	class ParamValue<LLRect, TypeValues<LLRect> > 
+	:	public CustomParamValue<LLRect>
 	{
-        typedef BlockValue<LLRect> super_t;
+        typedef CustomParamValue<LLRect> super_t;
 	public:
 		Optional<S32>	left,
 						top,
 						width,
 						height;
 
-		TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
+		ParamValue(const LLRect& value);
 
-		void setValueFromBlock() const;
-		void setBlockFromValue();
+		void updateValueFromBlock();
+		void updateBlockFromValue();
 	};
 
 	template<>
-	struct TypeValues<LLUIColor> : public TypeValuesHelper<LLUIColor>
+	class ParamValue<LLUIColor, TypeValues<LLUIColor> > 
+	:	public CustomParamValue<LLUIColor>
 	{
-		static void declareValues();
+        typedef CustomParamValue<LLUIColor> super_t;
+
+	public:
+		Optional<F32>			red,
+								green,
+								blue,
+								alpha;
+		Optional<std::string>	control;
+
+		ParamValue(const LLUIColor& color);
+		void updateValueFromBlock();
+		void updateBlockFromValue();
 	};
 
 	template<>
-	class TypedParam<LLUIColor> 
-	:	public BlockValue<LLUIColor>
+	class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> > 
+	:	public CustomParamValue<const LLFontGL* >
 	{
-        typedef BlockValue<LLUIColor> super_t;
-	public:
-		Optional<F32>	red,
-						green,
-						blue,
-						alpha;
-		Optional<std::string> control;
-
-		TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
-		void setValueFromBlock() const;
-		void setBlockFromValue();
-	};
-
-	// provide a better default for Optional<const LLFontGL*> than NULL
-	template <>
-	struct DefaultInitializer<const LLFontGL*>
-	{
-		// return reference to a single default instance of T
-		// built-in types will be initialized to zero, default constructor otherwise
-		static const LLFontGL* get() 
-		{ 
-			static const LLFontGL* sDefaultFont = LLFontGL::getFontDefault();  
-			return sDefaultFont;
-		} 
-	};
-
-
-	template<>
-	class TypedParam<const LLFontGL*> 
-	:	public BlockValue<const LLFontGL*>
-	{
-        typedef BlockValue<const LLFontGL*> super_t;
+        typedef CustomParamValue<const LLFontGL*> super_t;
 	public:
 		Optional<std::string>	name,
 								size,
 								style;
 
-		TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
-		void setValueFromBlock() const;
-		void setBlockFromValue();
+		ParamValue(const LLFontGL* value);
+		void updateValueFromBlock();
+		void updateBlockFromValue();
 	};
 
 	template<>
 
 
 	template<>
-	class TypedParam<LLCoordGL>
-	:	public BlockValue<LLCoordGL>
+	class ParamValue<LLCoordGL, TypeValues<LLCoordGL> >
+	:	public CustomParamValue<LLCoordGL>
 	{
-		typedef BlockValue<LLCoordGL> super_t;
+		typedef CustomParamValue<LLCoordGL> super_t;
 	public:
 		Optional<S32>	x,
 						y;
 
-		TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
-		void setValueFromBlock() const;
-		void setBlockFromValue();
+		ParamValue(const LLCoordGL& val);
+		void updateValueFromBlock();
+		void updateBlockFromValue();
 	};
 }
 

File indra/llui/lluiimage.cpp

 
 namespace LLInitParam
 {
-	void TypedParam<LLUIImage*>::setValueFromBlock() const
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
 	{
 		// The keyword "none" is specifically requesting a null image
 		// do not default to current value. Used to overwrite template images. 
 		if (name() == "none")
 		{
-			mData.mValue = NULL;
+			updateValue(NULL);
 			return;
 		}
 
 		LLUIImage* imagep =  LLUI::getUIImage(name());
 		if (imagep)
 		{
-			mData.mValue = imagep;
+			updateValue(imagep);
 		}
 	}
 	
-	void TypedParam<LLUIImage*>::setBlockFromValue()
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
 	{
-		if (mData.mValue == NULL)
+		if (getValue() == NULL)
 		{
 			name.set("none", false);
 		}
 		else
 		{
-			name.set(mData.mValue->getName(), false);
+			name.set(getValue()->getName(), false);
 		}
 	}
 

File indra/llui/lluiimage.h

 namespace LLInitParam
 {
 	template<>
-	class TypedParam<LLUIImage*, TypeValues<LLUIImage*>, false> 
-	:	public BlockValue<LLUIImage*>
+	class ParamValue<LLUIImage*, TypeValues<LLUIImage*> > 
+	:	public CustomParamValue<LLUIImage*>
 	{
 		typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type	T_const_ref;
-		typedef BlockValue<LLUIImage*> super_t;
+		typedef CustomParamValue<LLUIImage*> super_t;
 	public:
 		Optional<std::string> name;
 
-		TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-		:	super_t(descriptor, name, value, func, min_count, max_count)
+		ParamValue(LLUIImage* const& image)
+		:	super_t(image)
 		{
-			setBlockFromValue();
+			updateBlockFromValue();
+			addSynonym(name, "name");
 		}
 
-		void setValueFromBlock() const;
-		void setBlockFromValue();
+		void updateValueFromBlock();
+		void updateBlockFromValue();
 	};
 
 	// Need custom comparison function for our test app, which only loads

File indra/llui/tests/llurlentry_stub.cpp

 		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
 		mEnclosingBlockOffset = (U16)(my_addr - block_addr);
 	}
-	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {}
+	void BaseBlock::paramChanged(const Param& last_param, bool user_provided) {}
 
-	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){}
+	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
+	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
 	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
 	
 	void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
 	{
 		descriptor.mCurrentBlockPtr = this;
 	}
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; }
-	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; }
-	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; }
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; }
+	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {}
+	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; }
 	bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
 	bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
 
-	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-	:	super_t(descriptor, name, value, func, min_count, max_count)
+	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	:	super_t(color)
 	{}
 
-	void TypedParam<LLUIColor>::setValueFromBlock() const
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock() 
 	{}
 	
-	void TypedParam<LLUIColor>::setBlockFromValue()
-	{}
-
-	void TypeValues<LLUIColor>::declareValues()
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
 	{}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
 		return false;
 	}
 
-	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-	:	super_t(descriptor, _name, value, func, min_count, max_count)
+	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	:	super_t(fontp)
 	{}
 
-	void TypedParam<const LLFontGL*>::setValueFromBlock() const
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
 	{}
 	
-	void TypedParam<const LLFontGL*>::setBlockFromValue()
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
 	{}
 
 	void TypeValues<LLFontGL::HAlign>::declareValues()
 	void TypeValues<LLFontGL::ShadowType>::declareValues()
 	{}
 
-	void TypedParam<LLUIImage*>::setValueFromBlock() const
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
 	{}
 	
-	void TypedParam<LLUIImage*>::setBlockFromValue()
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
 	{}
 
 	

File indra/llui/tests/llurlentry_test.cpp

 	return 0;
 }
 
+namespace LLInitParam
+{
+	S32 Parser::sNextParseGeneration = 0;
+	BlockDescriptor::BlockDescriptor() {}
+	ParamDescriptor::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){}
+	ParamDescriptor::~ParamDescriptor() {}
+
+}
+
 namespace tut
 {
 	struct LLUrlEntryData

File indra/llui/tests/llurlmatch_test.cpp

 	BaseBlock::BaseBlock() {}
 	BaseBlock::~BaseBlock() {}
 
-	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {}
+	S32 Parser::sNextParseGeneration = 0;
 
-	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){}
+	BlockDescriptor::BlockDescriptor() {}
+	ParamDescriptor::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){}
+	ParamDescriptor::~ParamDescriptor() {}
+
+	void BaseBlock::paramChanged(const Param& last_param, bool user_provided) {}
+
+	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
 	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
-	
+	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
+
 	void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
 	{
 		descriptor.mCurrentBlockPtr = this;
 		mEnclosingBlockOffset = (U16)(my_addr - block_addr);
 	}
 
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; }
-	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; }
-	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; }
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; }
+	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {}
+	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; }
 	bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
 	bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
 
-	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-	:	super_t(descriptor, name, value, func, min_count, max_count)
+	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	:	super_t(color)
 	{}
 
-	void TypedParam<LLUIColor>::setValueFromBlock() const
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
 	{}
 	
-	void TypedParam<LLUIColor>::setBlockFromValue()
-	{}
-
-	void TypeValues<LLUIColor>::declareValues()
+	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
 	{}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
 		return false;
 	}
 
-	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
-	:	super_t(descriptor, _name, value, func, min_count, max_count)
+
+	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	:	super_t(fontp)
 	{}
 
-	void TypedParam<const LLFontGL*>::setValueFromBlock() const
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
 	{}
 	
-	void TypedParam<const LLFontGL*>::setBlockFromValue()
+	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
 	{}
 
 	void TypeValues<LLFontGL::HAlign>::declareValues()
 	void TypeValues<LLFontGL::ShadowType>::declareValues()
 	{}
 
-	void TypedParam<LLUIImage*>::setValueFromBlock() const
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
 	{}
 	
-	void TypedParam<LLUIImage*>::setBlockFromValue()
+	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
 	{}
 	
 	bool ParamCompare<LLUIImage*, false>::equals(

File indra/llxuixml/llinitparam.cpp

 	}
 
 	//
+	// ParamDescriptor
+	//
+	ParamDescriptor::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)
+	:	mParamHandle(p),
+		mMergeFunc(merge_func),
+		mDeserializeFunc(deserialize_func),
+		mSerializeFunc(serialize_func),
+		mValidationFunc(validation_func),
+		mInspectFunc(inspect_func),
+		mMinCount(min_count),
+		mMaxCount(max_count),
+		mGeneration(0),
+		mUserData(NULL)
+	{}
+
+	ParamDescriptor::ParamDescriptor()
+	:	mParamHandle(0),
+		mMergeFunc(NULL),
+		mDeserializeFunc(NULL),
+		mSerializeFunc(NULL),
+		mValidationFunc(NULL),
+		mInspectFunc(NULL),
+		mMinCount(0),
+		mMaxCount(0),
+		mGeneration(0),
+		mUserData(NULL)
+	{}
+
+	ParamDescriptor::~ParamDescriptor()
+	{
+		delete mUserData;
+	}
+
+	//
 	// Parser
 	//
+	S32 Parser::sNextParseGeneration = 0;
+
 	Parser::~Parser()
 	{}
 
 		std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
 	}
 
+	BlockDescriptor::BlockDescriptor()
+	:	mMaxParamOffset(0),
+		mInitializationState(UNINITIALIZED),
+		mCurrentBlockPtr(NULL)
+	{}
+
 	//
 	// BaseBlock
 	//
 
 	bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent)
 	{
-		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end())))
+		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), -1))
 		{
 			if (!silent)
 			{
 		return true;
 	}
 
-	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const
+	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const
 	{
 		// named param is one like LLView::Params::follows
 		// unnamed param is like LLView::Params::rect - implicit
 				name_stack.pop_back();
 			}
 		}
-
-		return true;
 	}
 
-	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const
+	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const
 	{
 		// named param is one like LLView::Params::follows
 		// unnamed param is like LLView::Params::rect - implicit
 		return true;
 	}
 
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack)
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 parent_generation)
 	{
 		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
 		bool names_left = name_stack.first != name_stack.second;
 
+		S32 parse_generation = name_stack.first == name_stack.second ? -1 : name_stack.first->second;
+
 		if (names_left)
 		{
 			const std::string& top_name = name_stack.first->first;
 					
 				Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);
 				++new_name_stack.first;
-				return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second);
+				return deserialize_func(*paramp, p, new_name_stack, parse_generation);
 			}
 		}
 
 			Param* paramp = getParamFromHandle((*it)->mParamHandle);
 			ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;
 
-			if (deserialize_func && deserialize_func(*paramp, p, name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second))
+			if (deserialize_func && deserialize_func(*paramp, p, name_stack, parse_generation))
 			{
 				return true;
 			}
 	}
 
 	//static 
-	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name)
+	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
 	{
 		// create a copy of the paramdescriptor in allparams
 		// so other data structures can store a pointer to it
 		block_data.mAllParams.push_back(in_param);
-		ParamDescriptor& param(block_data.mAllParams.back());
+		ParamDescriptorPtr param(block_data.mAllParams.back());
 
 		std::string name(char_name);
-		if ((size_t)param.mParamHandle > block_data.mMaxParamOffset)
+		if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
 		{
 			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
 		}
 
 		if (name.empty())
 		{
-			block_data.mUnnamedParams.push_back(&param);
+			block_data.mUnnamedParams.push_back(param);
 		}
 		else
 		{
 			// don't use insert, since we want to overwrite existing entries
-			block_data.mNamedParams[name] = &param;
+			block_data.mNamedParams[name] = param;
 		}
 
-		if (param.mValidationFunc)
+		if (param->mValidationFunc)
 		{
-			block_data.mValidationList.push_back(std::make_pair(param.mParamHandle, param.mValidationFunc));
+			block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
 		}
 	}
 
 				llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
 			}
 
-			ParamDescriptor* param_descriptor = findParamDescriptor(handle);
+			ParamDescriptorPtr param_descriptor = findParamDescriptor(param);
 			if (param_descriptor)
 			{
 				if (synonym.empty())
 		}
 	}
 
-	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided)
+	void BaseBlock::paramChanged(const Param& changed_param, bool user_provided)
 	{ 
 		if (user_provided)
 		{
 		return LLStringUtil::null;
 	}
 
-	ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle)
+	ParamDescriptorPtr BaseBlock::findParamDescriptor(const Param& param)
 	{
+		param_handle_t handle = getHandleFromParam(&param);
 		BlockDescriptor& descriptor = mostDerivedBlockDescriptor();
 		BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
 		for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
 			it != end_it;
 			++it)
 		{
-			if (it->mParamHandle == handle) return &(*it);
+			if ((*it)->mParamHandle == handle) return *it;
 		}
-		return NULL;
+		return ParamDescriptorPtr();
 	}
 
 	// take all provided params from other and apply to self
 			it != end_it;
 			++it)
 		{
-			const Param* other_paramp = other.getParamFromHandle(it->mParamHandle);
-			ParamDescriptor::merge_func_t merge_func = it->mMergeFunc;
+			const Param* other_paramp = other.getParamFromHandle((*it)->mParamHandle);
+			ParamDescriptor::merge_func_t merge_func = (*it)->mMergeFunc;
 			if (merge_func)
 			{
-				Param* paramp = getParamFromHandle(it->mParamHandle);
+				Param* paramp = getParamFromHandle((*it)->mParamHandle);
 				some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
 			}
 		}
 		return some_param_changed;
 	}
-
-	bool ParamCompare<LLSD, false>::equals(const LLSD &a, const LLSD &b)
-	{
-		return false;
-	}
 }

File indra/llxuixml/llinitparam.h

 /** 
-f * @file llinitparam.h
+ * @file llinitparam.h
  * @brief parameter block abstraction for creating complex objects and 
  * parsing construction parameters from xml and LLSD
  *
 #define LL_LLPARAM_H
 
 #include <vector>
-
-#include <stddef.h>
 #include <boost/function.hpp>
-#include <boost/bind.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 #include <boost/unordered_map.hpp>
-#include "llregistry.h"
-#include "llmemory.h"
-
+#include <boost/shared_ptr.hpp>
 
 namespace LLInitParam
 {
+	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 >
     struct ParamCompare 
 		}
 	};
 
-	// default constructor adaptor for InitParam Values
-	// constructs default instances of the given type, returned by const reference
-	template <typename T>
-	struct DefaultInitializer
+	template<> 
+	struct ParamCompare<LLSD, false>
 	{
-		typedef const T&			T_const_ref;
-		// return reference to a single default instance of T
-		// built-in types will be initialized to zero, default constructor otherwise
-		static T_const_ref get() { static T t = T(); return t; } 
+		static bool equals(const LLSD &a, const LLSD &b) { return false; }
 	};
 
 	// helper functions and classes
 	typedef ptrdiff_t param_handle_t;
 
+	// empty default implementation of key cache
+	// leverages empty base class optimization
 	template <typename T>
 	class TypeValues
 	{
 	public:
-		// empty default implemenation of key cache
-		class KeyCache
-		{
-		public:
-			void setKey(const std::string& key) {}
-			std::string getKey() const { return ""; }
-			void clearKey(){}
-		};
+		typedef std::map<std::string, T> value_name_map_t;
 
-		static bool get(const std::string& name, T& value)
+		void setValueName(const std::string& key) {}
+		std::string getValueName() const { return ""; }
+		void clearValueName() const {}
+
+		static bool getValueFromName(const std::string& name, T& value)
 		{
 			return false;
 		}
 
-		static bool empty()
+		static bool valueNamesExist()
 		{
-			return true;
+			return false;
 		}
 
-		static std::vector<std::string>* getPossibleValues() { return NULL; }
+		static std::vector<std::string>* getPossibleValues()
+		{
+			return NULL;
+		}
+
+		static value_name_map_t* getValueNames() {return NULL;}
 	};
 
 	template <typename T, typename DERIVED_TYPE = TypeValues<T> >
 	class TypeValuesHelper
-	:	public LLRegistrySingleton<std::string, T, DERIVED_TYPE >
 	{
-		typedef LLRegistrySingleton<std::string, T, DERIVED_TYPE>	super_t;
-		typedef LLSingleton<DERIVED_TYPE>							singleton_t;
 	public:
+		typedef typename std::map<std::string, T> value_name_map_t;
 
 		//TODO: cache key by index to save on param block size
-		class KeyCache
+		void setValueName(const std::string& value_name) 
 		{
-		public:
-			void setKey(const std::string& key) 
-			{
-				mKey = key; 
-			}
+			mValueName = value_name; 
+		}
 
-			void clearKey()
-			{
-				mKey = "";
-			}
+		std::string getValueName() const
+		{ 
+			return mValueName; 
+		}
 
-			std::string getKey() const
-			{ 
-				return mKey; 
-			}
+		void clearValueName() const
+		{
+			mValueName.clear();
+		}
 
-		private:
-			std::string mKey;
-		};
+		static bool getValueFromName(const std::string& name, T& value)
+		{
+			value_name_map_t* map = getValueNames();
+			typename value_name_map_t::iterator found_it = map->find(name);
+			if (found_it == map->end()) return false;
 
-		static bool get(const std::string& name, T& value)
-		{
-			if (!singleton_t::instance().exists(name)) return false;
-
-			value = *singleton_t::instance().getValue(name);
+			value = found_it->second;
 			return true;
 		}
 
-		static bool empty()
+		static bool valueNamesExist()
 		{
-			return singleton_t::instance().LLRegistry<std::string, T>::empty();
+			return !getValueNames()->empty();
 		}
 	
-		//override this to add name value pairs
-		static void declareValues() {}
-	
-		void initSingleton()
+		static value_name_map_t* getValueNames()
 		{
-			DERIVED_TYPE::declareValues();
+			static value_name_map_t sMap;
+			static bool sInitialized = false;
+
+			if (!sInitialized)
+			{
+				sInitialized = true;
+				DERIVED_TYPE::declareValues();
+			}
+			return &sMap;
 		}
 
-		static const std::vector<std::string>* getPossibleValues() 
-		{ 
-			// in order to return a pointer to a member, we lazily
-			// evaluate the result and store it in mValues here
-			if (singleton_t::instance().mValues.empty())
+		static std::vector<std::string>* getPossibleValues()
+		{
+			static std::vector<std::string> sValues;
+
+			value_name_map_t* map = getValueNames();
+			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
+				 it != end_it;
+				 ++it)
 			{
-				typename super_t::Registrar::registry_map_t::const_iterator it;
-				for (it = super_t::defaultRegistrar().beginItems(); it != super_t::defaultRegistrar().endItems(); ++it)
-				{
-					singleton_t::instance().mValues.push_back(it->first);
-				}
+				sValues.push_back(it->first);
 			}
-			return &singleton_t::instance().mValues; 
+			return &sValues;
 		}
 
+		static void declare(const std::string& name, const T& value)
+		{
+			(*getValueNames())[name] = value;
+		}
 
 	protected:
-		static void declare(const std::string& name, const T& value)
-		{
-			super_t::defaultRegistrar().add(name, value);
-		}
+		static void getName(const std::string& name, const T& value)
+		{}
 
-	private:
-		std::vector<std::string> mValues;
+		mutable std::string	mValueName;
 	};
 
 	class Parser
 			}
 		};
 
-		typedef std::vector<std::pair<std::string, S32> >			name_stack_t;
+		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::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&);
 
 		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(0),
+			mParseGeneration(sNextParseGeneration),
 			mParserReadFuncs(&read_map),
 			mParserWriteFuncs(&write_map),
 			mParserInspectFuncs(&inspect_map)
 		void setParseSilently(bool silent) { mParseSilently = silent; }
 
 		S32 getParseGeneration() { return mParseGeneration; }
-		S32 newParseGeneration() { return ++mParseGeneration; }
+		S32 newParseGeneration() { return mParseGeneration = ++sNextParseGeneration; }
 
 
 	protected:
 		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
 		Param(class BaseBlock* enclosing_block);
 
 		// store pointer to enclosing block as offset to reduce space and allow for quick copying
-		BaseBlock& enclosingBlock() const
+		class 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));
+			return *const_cast<class BaseBlock*>
+				(reinterpret_cast<const class BaseBlock*>
+					(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
 		}
 
 	private:
 	// various callbacks and constraints associated with an individual param
 	struct ParamDescriptor
 	{
-	public:
+		struct UserData
+		{
+			virtual ~UserData() {}
+		};
+
 		typedef bool(*merge_func_t)(Param&, const Param&, bool);
 		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, S32);
 		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
 		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)
-		:	mParamHandle(p),
-			mMergeFunc(merge_func),
-			mDeserializeFunc(deserialize_func),
-			mSerializeFunc(serialize_func),
-			mValidationFunc(validation_func),
-			mInspectFunc(inspect_func),
-			mMinCount(min_count),
-			mMaxCount(max_count),
-			mGeneration(0),
-			mNumRefs(0)
-		{}
+						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);
 
-		ParamDescriptor()
-		:	mParamHandle(0),
-			mMergeFunc(NULL),
-			mDeserializeFunc(NULL),
-			mSerializeFunc(NULL),
-			mValidationFunc(NULL),
-			mInspectFunc(NULL),
-			mMinCount(0),
-			mMaxCount(0),
-			mGeneration(0),
-			mNumRefs(0)
-		{}
+		ParamDescriptor();
+		~ParamDescriptor();
 
 		param_handle_t		mParamHandle;
-	
 		merge_func_t		mMergeFunc;
 		deserialize_func_t	mDeserializeFunc;
 		serialize_func_t	mSerializeFunc;
 		S32					mMaxCount;
 		S32					mGeneration;
 		S32					mNumRefs;
+		UserData*			mUserData;
 	};
 
+	typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
+
 	// each derived Block class keeps a static data structure maintaining offsets to various params
 	class BlockDescriptor
 	{
 	public:
-		BlockDescriptor()
-		:	mMaxParamOffset(0),
-			mInitializationState(UNINITIALIZED),
-			mCurrentBlockPtr(NULL)
-		{}
+		BlockDescriptor();
 
 		typedef enum e_initialization_state
 		{
 
 		void aggregateBlockData(BlockDescriptor& src_block_data);
 
-	public:
-		typedef boost::unordered_map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
-		typedef std::vector<ParamDescriptor*> param_list_t; 
-
-		typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams
-		typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
+		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::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* getParamFromHandle(const param_handle_t param_handle)
 		{
 			if (param_handle == 0) return NULL;
+
 			U8* baseblock_address = reinterpret_cast<U8*>(this);
 			return reinterpret_cast<Param*>(baseblock_address + param_handle);
 		}
 		void addSynonym(Param& param, const std::string& synonym);
 
 		// Blocks can override this to do custom tracking of changes
-		virtual void setLastChangedParam(const Param& last_param, bool user_provided);
+		virtual void paramChanged(const Param& changed_param, bool user_provided);
 
 		S32 getLastChangeVersion() const { return mChangeVersion; }
-		bool isDefault() const { return mChangeVersion == 0; }
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack);
-		bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
-		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
+		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 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(); }
 		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
 			return false;
 		}
 
-		static void addParam(BlockDescriptor& block_data, const ParamDescriptor& param, const char* name);
+		static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name);
+
+		ParamDescriptorPtr findParamDescriptor(const Param& param);
+
 	protected:
 		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
 
 
 	private:
 		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
-		ParamDescriptor* findParamDescriptor(param_handle_t handle);
-	};
-
-
-	template<typename T>
-	struct ParamIterator
-	{
-		typedef typename std::vector<T>::const_iterator		const_iterator;
-		typedef typename std::vector<T>::iterator			iterator;
 	};
 
 	// these templates allow us to distinguish between template parameters
 	// that derive from BaseBlock and those that don't
-	// this is supposedly faster than boost::is_convertible and its ilk
 	template<typename T, typename Void = void>
-	struct IsBaseBlock
+	struct IsBlock
 	{
 		static const bool value = false;
 	};
 
 	template<typename T>
-	struct IsBaseBlock<T, typename T::baseblock_base_class_t>
+	struct IsBlock<T, typename T::baseblock_base_class_t>
 	{
 		static const bool value = true;
 	};
 
+	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
+	class ParamValue : public NAME_VALUE_LOOKUP
+	{
+	public:
+		typedef const T&							value_assignment_t;
+
+		ParamValue(): mValue() {}
+		ParamValue(const T& other) : mValue(other) {}
+
+		void setValue(value_assignment_t val)
+		{
+			mValue = val;
+		}
+
+		value_assignment_t getValue() const
+		{
+			return mValue;
+		}
+
+		T& getValue()
+		{
+			return mValue;
+		}
+
+	private:
+		T mValue;
+	};
+
+	template<typename T, typename NAME_VALUE_LOOKUP>
+	class ParamValue<T, NAME_VALUE_LOOKUP, true> 
+	:	public T,
+		public NAME_VALUE_LOOKUP
+	{
+	public:
+		typedef const T&							value_assignment_t;
+
+		S32 			mKeyVersion;
+		mutable S32 	mValidatedVersion;
+		mutable bool 	mValidated; // lazy validation flag
+
+		ParamValue() 
+		:	T(),
+			mKeyVersion(0),
+			mValidatedVersion(-1),
+			mValidated(false)
+		{}
+
+		ParamValue(const T& other)
+		:	T(other),
+			mKeyVersion(0),
+			mValidatedVersion(-1),
+			mValidated(false)
+		{
+		}
+
+		void setValue(value_assignment_t val)
+		{
+			*this = val;
+		}
+
+		value_assignment_t getValue() const
+		{
+			return *this;
+		}
+
+		T& getValue()
+		{
+			return *this;
+		}
+	};
+
+	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+	struct ParamIterator
+	{
+		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator;
+		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator;
+	};
+
 	// specialize for custom parsing/decomposition of specific classes
 	// e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
-			bool		VALUE_IS_BLOCK = IsBaseBlock<T>::value>
+			bool		VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>
 	class TypedParam 
-	:	public Param
+	:	public Param, 
+		public ParamValue<T, NAME_VALUE_LOOKUP>
 	{
 	public:
-		typedef const T&																	value_const_ref_t;
-		typedef value_const_ref_t															value_assignment_t;
-		typedef typename NAME_VALUE_LOOKUP::KeyCache										key_cache_t;
+		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;
 
 		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)
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ 				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 												&mergeWith,
 												&deserializeParam,
 												&serializeParam,
 												validate_func,
 												&inspectParam,
-												min_count, max_count);
+												min_count, max_count));
 				BaseBlock::addParam(block_descriptor, param_descriptor, name);
 			}
 
-			mData.mValue = value;
+			setValue(value);
 		} 
 
 		bool isProvided() const { return Param::anyProvided(); }
 			// no further names in stack, attempt to parse value now
 			if (name_stack.first == name_stack.second)
 			{
-				if (parser.readValue(typed_param.mData.mValue))
+				if (parser.readValue(typed_param.getValue()))
 				{
-					typed_param.mData.clearKey();
+					typed_param.clearValueName();
 					typed_param.setProvided(true);
-					typed_param.enclosingBlock().setLastChangedParam(param, true);
+					typed_param.enclosingBlock().paramChanged(param, true);
 					return true;
 				}
 				
 				// try to parse a known named value
-				if(!NAME_VALUE_LOOKUP::empty())
+				if(name_value_lookup_t::valueNamesExist())
 				{
 					// try to parse a known named value
 					std::string name;
 					if (parser.readValue(name))
 					{
 						// try to parse a per type named value
-						if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue))
+						if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
 						{
-							typed_param.mData.setKey(name);
+							typed_param.setValueName(name);
 							typed_param.setProvided(true);
-							typed_param.enclosingBlock().setLastChangedParam(param, true);
+							typed_param.enclosingBlock().paramChanged(param, true);
 							return true;
 						}
 
 				name_stack.back().second = parser.newParseGeneration();
 			}
 
-			std::string key = typed_param.mData.getKey();
+			std::string key = typed_param.getValueName();
 
 			// first try to write out name of name/value pair
 
 			if (!key.empty())
 			{
-				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
+				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
 				{
 					if (!parser.writeValue(key, name_stack))
 					{
 				}
 			}
 			// then try to serialize value directly
-			else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get()))					{
-				if (!parser.writeValue(typed_param.mData.mValue, name_stack)) 
+			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue()))
+			{
+				if (!parser.writeValue(typed_param.getValue(), name_stack)) 
 				{
 					return;
 				}
 			// tell parser about our actual type
 			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
 			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
-			if (NAME_VALUE_LOOKUP::getPossibleValues())
+			if (name_value_lookup_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
 			}
 		}
 
 		void set(value_assignment_t val, bool flag_as_provided = true)
 		{
-			mData.mValue = val;
-			mData.clearKey();
+			setValue(val);
+			param_value_t::clearValueName();
 			setProvided(flag_as_provided);
-			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+			Param::enclosingBlock().paramChanged(*this, flag_as_provided);
 		}
 
 		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
 		}
 
 		// implicit conversion
-		operator value_assignment_t() const { return get(); } 
+		operator value_assignment_t() const { return param_value_t::getValue(); } 
 		// explicit conversion
-		value_assignment_t operator()() const { return get(); } 
+		value_assignment_t operator()() const { return param_value_t::getValue(); } 
 
 	protected:
-		value_assignment_t get() const
-		{
-			return mData.mValue;
-		}
 
 		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_typed_param.mData.clearKey();
-				dst_typed_param.set(src_typed_param.get());
+				dst_typed_param.clearValueName();
+				dst_typed_param.set(src_typed_param.getValue());
 				return true;
 			}
 			return false;
 		}
-
-		struct Data : public key_cache_t
-		{
-			T mValue;
-		};
-
-		Data		mData;
 	};
 
 	// parameter that is a block
 	template <typename T, typename NAME_VALUE_LOOKUP>
 	class TypedParam<T, NAME_VALUE_LOOKUP, false, true> 
-	:	public T,
-		public Param
+	:	public Param,
+		public ParamValue<T, NAME_VALUE_LOOKUP>
 	{
 	public:
 		typedef const T											value_const_t;
 		typedef T												value_t;
-		typedef value_const_t&									value_const_ref_t;
-		typedef value_const_ref_t								value_assignment_t;
-		typedef typename NAME_VALUE_LOOKUP::KeyCache			key_cache_t;
+		typedef value_const_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;
 
 		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),
-			T(value)
+			param_value_t(value)
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 												&mergeWith,
 												&deserializeParam,
 												&serializeParam,
 												validate_func, 
 												&inspectParam,
-												min_count, max_count);
+												min_count, max_count));
 				BaseBlock::addParam(block_descriptor, param_descriptor, name);
 			}
 		}
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 			// attempt to parse block...
-			if(typed_param.deserializeBlock(parser, name_stack))
+			if(typed_param.deserializeBlock(parser, name_stack, generation))
 			{
-				typed_param.mData.clearKey();
-				typed_param.enclosingBlock().setLastChangedParam(param, true);
+				typed_param.clearValueName();
+				typed_param.enclosingBlock().paramChanged(param, true);
+				typed_param.setProvided(true);
 				return true;
 			}
 
-			if(!NAME_VALUE_LOOKUP::empty())
+			if(name_value_lookup_t::valueNamesExist())
 			{
 				// try to parse a known named value
 				std::string name;
 				if (parser.readValue(name))
 				{
 					// try to parse a per type named value
-					if (NAME_VALUE_LOOKUP::get(name, typed_param))
+					if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
 					{
-						typed_param.enclosingBlock().setLastChangedParam(param, true);
-						typed_param.mData.setKey(name);
-						typed_param.mData.mKeyVersion = typed_param.getLastChangeVersion();
+						typed_param.enclosingBlock().paramChanged(param, true);
+						typed_param.setValueName(name);
+						typed_param.setProvided(true);
+						typed_param.mKeyVersion = typed_param.getLastChangeVersion();
 						return true;
 					}
 
 		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);
+			if (!typed_param.isProvided()) return;
+
 			if (!name_stack.empty())
 			{
 				name_stack.back().second = parser.newParseGeneration();
 			}
 
-			std::string key = typed_param.mData.getKey();
-			if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion())
+			std::string key = typed_param.getValueName();
+			if (!key.empty() && typed_param.mKeyVersion == typed_param.getLastChangeVersion())
 			{
 				if (!parser.writeValue(key, name_stack))
 				{
 		{
 			// I am a param that is also a block, so just recurse into my contents
 			const self_t& typed_param = static_cast<const self_t&>(param);
-			typed_param.inspectBlock(parser, name_stack);
+			typed_param.inspectBlock(parser, name_stack, min_count, max_count);
 		}
 
 		// a param-that-is-a-block is provided when the user has set one of its child params
 		// *and* the block as a whole validates
 		bool isProvided() const 
 		{ 
-			// only validate block when it hasn't already passed validation and user has supplied *some* value
-			if (Param::anyProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
+			// only validate block when it hasn't already passed validation with current data
+			if (Param::anyProvided() && param_value_t::mValidatedVersion < param_value_t::getLastChangeVersion())
 			{
 				// a sub-block is "provided" when it has been filled in enough to be valid
-				mData.mValidated = T::validateBlock(false);
-				mData.mValidatedVersion = T::getLastChangeVersion();
+				param_value_t::mValidated = param_value_t::validateBlock(false);
+				param_value_t::mValidatedVersion = param_value_t::getLastChangeVersion();
 			}
-			return Param::anyProvided() && mData.mValidated;
+			return Param::anyProvided() && param_value_t::mValidated;
 		}
 
 		// assign block contents to this param-that-is-a-block
 		void set(value_assignment_t val, bool flag_as_provided = true)
 		{
-			value_t::operator=(val);
-			mData.clearKey();
+			setValue(val);
+			param_value_t::clearValueName();
 			// force revalidation of block by clearing known provided version
 			// next call to isProvided() will update provision status based on validity
-			mData.mValidatedVersion = 0;
+			param_value_t::mValidatedVersion = -1;
 			setProvided(flag_as_provided);
-			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+			Param::enclosingBlock().paramChanged(*this, flag_as_provided);
 		}
 
 		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
 		}
 
 		// propagate changed status up to enclosing block
-		/*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
+		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
 		{ 
-			T::setLastChangedParam(last_param, user_provided);
-			Param::enclosingBlock().setLastChangedParam(*this, user_provided);
+			ParamValue<T, NAME_VALUE_LOOKUP>::paramChanged(changed_param, user_provided);
+			Param::enclosingBlock().paramChanged(*this, user_provided);
 			if (user_provided)
 			{
 				// a child param has been explicitly changed
 		}
 
 		// implicit conversion
-		operator value_assignment_t() const { return get(); } 
+		operator value_assignment_t() const { return param_value_t::getValue(); } 
 		// explicit conversion
-		value_assignment_t operator()() const { return get(); } 
+		value_assignment_t operator()() const { return param_value_t::getValue(); } 
 
 	protected:
-		value_assignment_t get() const
-		{
-			return *this;
-		}
 
 		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 (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite))
+
+			if (src_typed_param.isProvided()
+				&& (overwrite || !dst_typed_param.isProvided()))
 			{
-				dst_typed_param.mData.clearKey();
-				return true;
+				if (dst_typed_param.merge(param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+				{
+					dst_typed_param.clearValueName();
+					return true;
+				}
 			}
 			return false;
 		}
-
-		struct Data : public key_cache_t
-		{
-			S32 			mKeyVersion;
-			mutable S32 	mValidatedVersion;
-			mutable bool 	mValidated; // lazy validation flag
-
-			Data() 
-			:	mKeyVersion(0),
-				mValidatedVersion(0),
-				mValidated(false)
-			{}
-		};
-		Data	mData;
 	};
 
 	// container of non-block parameters
 	{
 	public:
 		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t;
-		typedef typename std::vector<VALUE_TYPE>							container_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;
 
 		typedef VALUE_TYPE													value_t;
-		typedef value_t&													value_ref_t;
-		typedef const value_t&												value_const_ref_t;
+		typedef NAME_VALUE_LOOKUP											name_value_lookup_t;
 		
-		typedef typename NAME_VALUE_LOOKUP::KeyCache						key_cache_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)
+		{
+			std::copy(value.begin(), value.end(), std::back_inserter(mValues));
 
-		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),
-			mValues(value)
-		{
-			mCachedKeys.resize(mValues.size());
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 												&mergeWith,
 												&deserializeParam,
 												&serializeParam,
 												validate_func,
 												&inspectParam,
-												min_count, max_count);
+												min_count, max_count));
 				BaseBlock::addParam(block_descriptor, param_descriptor, name);
 			}
 		} 
 				// attempt to read value directly
 				if (parser.readValue(value))
 				{
-					typed_param.mValues.push_back(value);
-					// save an empty name/value key as a placeholder
-					typed_param.mCachedKeys.push_back(key_cache_t());
-					typed_param.enclosingBlock().setLastChangedParam(param, true);
-					typed_param.setProvided(true);
+					typed_param.add(value);
 					return true;
 				}
 				
 				// try to parse a known named value
-				if(!NAME_VALUE_LOOKUP::empty())
+				if(name_value_lookup_t::valueNamesExist())
 				{
 					// try to parse a known named value
 					std::string name;
 					if (parser.readValue(name))
 					{
 						// try to parse a per type named value
-						if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues))
+						if (name_value_lookup_t::getValueFromName(name, typed_param.mValues))
 						{
-							typed_param.mValues.push_back(value);
-							typed_param.mCachedKeys.push_back(key_cache_t());
-							typed_param.mCachedKeys.back().setKey(name);
-							typed_param.enclosingBlock().setLastChangedParam(param, true);
-							typed_param.setProvided(true);
+							typed_param.add(value);
+							typed_param.mValues.back().setValueName(name);
 							return true;
 						}
 
 			const self_t& typed_param = static_cast<const self_t&>(param);
 			if (!typed_param.isProvided() || name_stack.empty()) return;
 
-			const_iterator it = typed_param.mValues.begin();
-			for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin();
-				it != typed_param.mValues.end();
-				++key_it, ++it)
+			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
+				it != end_it;
+				++it)
 			{
-				std::string key = key_it->get();
+				std::string key = it->getValue();
 				name_stack.back().second = parser.newParseGeneration();
 
-				if(!key.empty())
+				if(key.empty())
+				// not parsed via name values, write out value directly
+				{
+					if (!parser.writeValue(*it, name_stack))
+					{
+						break;
+					}
+				}
+				else 
 				{
 					if(!parser.writeValue(key, name_stack))
 					{
-						return;
+						break;
 					}
 				}
-				// not parse via name values, write out value directly
-				else if (!parser.writeValue(*it, name_stack))
-				{
-					return;
-				}
 			}
 		}
 
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
 			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
-			if (NAME_VALUE_LOOKUP::getPossibleValues())
+			if (name_value_lookup_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
 			}
 		}
 
 		void set(value_assignment_t val, bool flag_as_provided = true)
<