void BaseBlock::addSynonym(Param& param, const std::string& synonym)
	{
		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
		if (block_data.mInitializationState == BlockDescriptor::INITIALIZING)
		{
			param_handle_t handle = getHandleFromParam(&param);
			
			// check for invalid derivation from a paramblock (i.e. without using
			// Block<T, Base_Class>
			if ((size_t)handle > 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;
			}

			ParamDescriptor* param_descriptor = findParamDescriptor(handle);
			if (param_descriptor)
			{
				if (synonym.empty())
				{
					block_data.mUnnamedParams.push_back(param_descriptor);
				}
				else
				{
					block_data.mNamedParams[synonym] = param_descriptor;
				}
			}
		}
	}
	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const
	{
		// named param is one like LLView::Params::follows
		// unnamed param is like LLView::Params::rect - implicit
		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();

		for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin(); 
			it != block_data.mUnnamedParams.end(); 
			++it)
		{
			param_handle_t param_handle = (*it)->mParamHandle;
			const Param* param = getParamFromHandle(param_handle);
			ParamDescriptor::inspect_func_t inspect_func = (*it)->mInspectFunc;
			if (inspect_func)
			{
				(*it)->mGeneration = parser.newParseGeneration();
				name_stack.push_back(std::make_pair("", (*it)->mGeneration));
				inspect_func(*param, parser, name_stack, (*it)->mMinCount, (*it)->mMaxCount);
				name_stack.pop_back();
			}
		}

		for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
			it != block_data.mNamedParams.end();
			++it)
		{
			param_handle_t param_handle = it->second->mParamHandle;
			const Param* param = getParamFromHandle(param_handle);
			ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
			if (inspect_func)
			{
				// Ensure this param has not already been inspected
				bool duplicate = false;
				for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin(); 
					it2 != block_data.mUnnamedParams.end(); 
					++it2)
				{
					if (param_handle == (*it2)->mParamHandle)
					{
						duplicate = true;
						break;
					}
				}

				if (!duplicate)
				{
					it->second->mGeneration = parser.newParseGeneration();
				}
				name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
				inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
				name_stack.pop_back();
			}
		}

		return true;
	}
Exemple #3
0
	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack)
	{
		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
		bool names_left = name_stack.first != name_stack.second;

		if (names_left)
		{
			const std::string& top_name = name_stack.first->first;

			ParamDescriptor::deserialize_func_t deserialize_func = NULL;
			Param* paramp = NULL;

			BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
			if (found_it != block_data.mNamedParams.end())
			{
				// find pointer to member parameter from offset table
				paramp = getParamFromHandle(found_it->second->mParamHandle);
				deserialize_func = found_it->second->mDeserializeFunc;
			}
			else
			{
				BlockDescriptor::param_map_t::iterator found_it = block_data.mSynonyms.find(top_name);
				if (found_it != block_data.mSynonyms.end())
				{
					// find pointer to member parameter from offset table
					paramp = getParamFromHandle(found_it->second->mParamHandle);
					deserialize_func = found_it->second->mDeserializeFunc;
				}
			}
					
			Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);
			++new_name_stack.first;
			if (deserialize_func)
			{
				return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second);
			}
		}

		// try to parse unnamed parameters, in declaration order
		for ( BlockDescriptor::param_list_t::iterator it = block_data.mUnnamedParams.begin(); 
			it != block_data.mUnnamedParams.end(); 
			++it)
		{
			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))
			{
				return true;
			}
		}

		return false;
	}
	ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle)
	{
		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);
		}
		return NULL;
	}
	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;
		}
		return ParamDescriptorPtr();
	}
	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;

			ParamDescriptor::deserialize_func_t deserialize_func = NULL;
			Param* paramp = NULL;

			BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
			if (found_it != block_data.mNamedParams.end())
			{
				// find pointer to member parameter from offset table
				paramp = getParamFromHandle(found_it->second->mParamHandle);
				deserialize_func = found_it->second->mDeserializeFunc;
					
				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, parse_generation);
			}
		}

		// try to parse unnamed parameters, in declaration order
		for ( BlockDescriptor::param_list_t::iterator it = block_data.mUnnamedParams.begin(); 
			it != block_data.mUnnamedParams.end(); 
			++it)
		{
			Param* paramp = getParamFromHandle((*it)->mParamHandle);
			ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;

			if (deserialize_func && deserialize_func(*paramp, p, name_stack, parse_generation))
			{
				return true;
			}
		}

		// if no match, and no names left on stack, this is just an existence assertion of this block
		// verify by calling readValue with NoParamValue type, an inherently unparseable type
		if (!names_left)
		{
			NoParamValue no_value;
			return p.readValue(no_value);
		}

		return false;
	}
	bool BaseBlock::validateBlock(bool emit_errors) const
	{
		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
		for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
		{
			const Param* param = getParamFromHandle(it->first);
			if (!it->second(param))
			{
				if (emit_errors)
				{
					llwarns << "Invalid param \"" << getParamName(block_data, param) << "\"" << llendl;
				}
				return false;
			}
		}
		return true;
	}
	bool 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
		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();

		for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin(); 
			it != block_data.mUnnamedParams.end(); 
			++it)
		{
			param_handle_t param_handle = (*it)->mParamHandle;
			const Param* param = getParamFromHandle(param_handle);
			ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
			if (serialize_func)
			{
				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
				// each param descriptor remembers its serial number
				// so we can inspect the same param under different names
				// and see that it has the same number
				(*it)->mGeneration = parser.newParseGeneration();
				name_stack.push_back(std::make_pair("", (*it)->mGeneration));
				serialize_func(*param, parser, name_stack, diff_param);
				name_stack.pop_back();
			}
		}

		for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
			it != block_data.mNamedParams.end();
			++it)
		{
			param_handle_t param_handle = it->second->mParamHandle;
			const Param* param = getParamFromHandle(param_handle);
			ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
			if (serialize_func && param->anyProvided())
			{
				// Ensure this param has not already been serialized
				// Prevents <rect> from being serialized as its own tag.
				bool duplicate = false;
				for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin(); 
					it2 != block_data.mUnnamedParams.end(); 
					++it2)
				{
					if (param_handle == (*it2)->mParamHandle)
					{
						duplicate = true;
						break;
					}
				}

				//FIXME: for now, don't attempt to serialize values under synonyms, as current parsers
				// don't know how to detect them
				if (duplicate) 
				{
					continue;
				}

				if (!duplicate)
				{
					it->second->mGeneration = parser.newParseGeneration();
				}

				name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
				serialize_func(*param, parser, name_stack, diff_param);
				name_stack.pop_back();
			}
		}

		return true;
	}