mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Advance Logical identifier condition
This commit is contained in:
		| @@ -1123,10 +1123,20 @@ void CGTownInstance::battleFinished(const CGHeroInstance *hero, const BattleResu | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CGTownInstance::serializeJsonOptions(JsonSerializeFormat& handler) | ||||
| void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler) | ||||
| { | ||||
| 	CGObjectInstance::serializeJsonOwner(handler); | ||||
| 	CCreatureSet::serializeJson(handler, "army"); | ||||
| 	handler.serializeBool<ui8>("tightFormation", 1, 0, formation); | ||||
| 	handler.serializeString("name", name); | ||||
|  | ||||
|  | ||||
|  | ||||
| 	if(!handler.saving) | ||||
| 	{ | ||||
| 		builtBuildings.insert(BuildingID::DEFAULT);//just in case | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	//todo: CGTownInstance::serializeJsonOptions | ||||
| } | ||||
|   | ||||
| @@ -235,7 +235,7 @@ void CMapFormatJson::serializePlayerInfo(JsonSerializeFormat & handler) | ||||
|  | ||||
| 		serializeAllowedFactions(handler, info.allowedFactions); | ||||
|  | ||||
| 		handler.serializeBoolEnum("canPlay", "PlayerOrAI", "AIOnly", info.canHumanPlay); | ||||
| 		handler.serializeEnum("canPlay", "PlayerOrAI", "AIOnly", info.canHumanPlay); | ||||
|  | ||||
| 		//mainTown | ||||
| 		if(handler.saving) | ||||
|   | ||||
| @@ -25,7 +25,7 @@ void JsonDeserializer::serializeBool(const std::string & fieldName, bool & value | ||||
| 	value = current->operator[](fieldName).Bool(); | ||||
| } | ||||
|  | ||||
| void JsonDeserializer::serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) | ||||
| void JsonDeserializer::serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) | ||||
| { | ||||
| 	const JsonNode & tmp = current->operator[](fieldName); | ||||
|  | ||||
| @@ -72,32 +72,11 @@ void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecode | ||||
| 	if(field.isNull()) | ||||
| 		return; | ||||
|  | ||||
| 	auto loadPart = [&](const JsonVector & part, const bool val) | ||||
| 	{ | ||||
| 		for(size_t index = 0; index < part.size(); index++) | ||||
| 		{ | ||||
| 			const std::string & identifier = part[index].String(); | ||||
| 	const JsonNode & anyOf = field["anyOf"]; | ||||
| 	const JsonNode & allOf = field["allOf"]; | ||||
| 	const JsonNode & noneOf = field["noneOf"]; | ||||
|  | ||||
| 			si32 rawId = decoder(identifier); | ||||
| 			if(rawId >= 0) | ||||
| 			{ | ||||
| 				if(rawId < value.size()) | ||||
| 					value[rawId] = val; | ||||
| 				else | ||||
| 					logGlobal->errorStream() << "JsonDeserializer::serializeLIC: " << fieldName <<" id out of bounds " << rawId; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				logGlobal->errorStream() << "JsonDeserializer::serializeLIC: " << fieldName <<" identifier not resolved " << identifier; | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	const JsonVector & anyOf = field["anyOf"].Vector(); | ||||
| 	const JsonVector & allOf = field["allOf"].Vector(); | ||||
| 	const JsonVector & noneOf = field["noneOf"].Vector(); | ||||
|  | ||||
| 	if(anyOf.empty() && allOf.empty()) | ||||
| 	if(anyOf.Vector().empty() && allOf.Vector().empty()) | ||||
| 	{ | ||||
| 		//permissive mode | ||||
| 		value = standard; | ||||
| @@ -108,11 +87,37 @@ void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecode | ||||
| 		value.clear(); | ||||
| 		value.resize(standard.size(), false); | ||||
|  | ||||
| 		loadPart(anyOf, true); | ||||
| 		loadPart(allOf, true); | ||||
| 		readLICPart(anyOf, decoder, true, value); | ||||
| 		readLICPart(allOf, decoder, true, value); | ||||
| 	} | ||||
|  | ||||
| 	loadPart(noneOf, false); | ||||
| 	readLICPart(noneOf, decoder, false, value); | ||||
| } | ||||
|  | ||||
| void JsonDeserializer::serializeLIC(const std::string & fieldName, LIC & value) | ||||
| { | ||||
| 	const JsonNode & field = current->operator[](fieldName); | ||||
|  | ||||
| 	const JsonNode & anyOf = field["anyOf"]; | ||||
| 	const JsonNode & allOf = field["allOf"]; | ||||
| 	const JsonNode & noneOf = field["noneOf"]; | ||||
|  | ||||
| 	if(anyOf.Vector().empty()) | ||||
| 	{ | ||||
| 		//permissive mode | ||||
| 		value.any = value.standard; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		//restrictive mode | ||||
| 		value.any.clear(); | ||||
| 		value.any.resize(value.standard.size(), false); | ||||
|  | ||||
| 		readLICPart(anyOf, value.decoder, true, value.any); | ||||
| 	} | ||||
|  | ||||
| 	readLICPart(allOf, value.decoder, true, value.all); | ||||
| 	readLICPart(noneOf, value.decoder, true, value.none); | ||||
| } | ||||
|  | ||||
| void JsonDeserializer::serializeString(const std::string & fieldName, std::string & value) | ||||
| @@ -120,3 +125,20 @@ void JsonDeserializer::serializeString(const std::string & fieldName, std::strin | ||||
| 	value = current->operator[](fieldName).String(); | ||||
| } | ||||
|  | ||||
| void JsonDeserializer::readLICPart(const JsonNode & part, const TDecoder & decoder, const bool val, std::vector<bool> & value) | ||||
| { | ||||
| 	for(size_t index = 0; index < part.Vector().size(); index++) | ||||
| 	{ | ||||
| 		const std::string & identifier = part.Vector()[index].String(); | ||||
|  | ||||
| 		const si32 rawId = decoder(identifier); | ||||
| 		if(rawId >= 0) | ||||
| 		{ | ||||
| 			if(rawId < value.size()) | ||||
| 				value[rawId] = val; | ||||
| 			else | ||||
| 				logGlobal->errorStream() << "JsonDeserializer::serializeLIC: id out of bounds " << rawId; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -20,12 +20,15 @@ public: | ||||
| 	JsonDeserializer(JsonNode & root_); | ||||
|  | ||||
| 	void serializeBool(const std::string & fieldName, bool & value) override; | ||||
| 	void serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) override; | ||||
| 	void serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) override; | ||||
| 	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override; | ||||
| 	void serializeLIC(const std::string & fieldName, LIC & value) override; | ||||
| 	void serializeString(const std::string & fieldName, std::string & value) override; | ||||
|  | ||||
| protected: | ||||
| 	void serializeFloat(const std::string & fieldName, double & value) override; | ||||
| 	void serializeIntEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const si32 defaultValue, si32 & value) override; | ||||
| 	void serializeIntId(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const si32 defaultValue, si32 & value) override; | ||||
| private: | ||||
| 	void readLICPart(const JsonNode & part, const TDecoder & decoder, const bool val, std::vector<bool> & value); | ||||
| }; | ||||
|   | ||||
| @@ -14,6 +14,7 @@ | ||||
|  | ||||
| #include "../JsonNode.h" | ||||
|  | ||||
|  | ||||
| //JsonStructSerializer | ||||
| JsonStructSerializer::JsonStructSerializer(JsonStructSerializer&& other): | ||||
| 	restoreState(false), | ||||
| @@ -48,7 +49,6 @@ JsonStructSerializer::JsonStructSerializer(JsonStructSerializer & parent, const | ||||
| 	owner.current = thisNode; | ||||
| } | ||||
|  | ||||
|  | ||||
| JsonStructSerializer JsonStructSerializer::enterStruct(const std::string & fieldName) | ||||
| { | ||||
| 	return JsonStructSerializer(*this, fieldName); | ||||
| @@ -64,6 +64,14 @@ JsonSerializeFormat * JsonStructSerializer::operator->() | ||||
| 	return &owner; | ||||
| } | ||||
|  | ||||
| JsonSerializeFormat::LIC::LIC(const std::vector<bool> & Standard, const TDecoder & Decoder, const TEncoder & Encoder): | ||||
| 	standard(Standard), decoder(Decoder), encoder(Encoder) | ||||
| { | ||||
| 	any = standard; | ||||
| 	all.resize(standard.size(), false); | ||||
| 	none.resize(standard.size(), false); | ||||
| } | ||||
|  | ||||
|  | ||||
| //JsonSerializeFormat | ||||
| JsonSerializeFormat::JsonSerializeFormat(JsonNode & root_, const bool saving_): | ||||
|   | ||||
| @@ -47,6 +47,16 @@ public: | ||||
| 	///may assume that object index is valid | ||||
| 	typedef std::function<std::string(si32)> TEncoder; | ||||
|  | ||||
| 	struct LIC | ||||
| 	{ | ||||
| 		LIC(const std::vector<bool> & Standard, const TDecoder & Decoder, const TEncoder & Encoder); | ||||
|  | ||||
| 		const std::vector<bool> & standard; | ||||
| 		const TDecoder & decoder; | ||||
| 		const TEncoder & encoder; | ||||
| 		std::vector<bool> all, any, none; | ||||
| 	}; | ||||
|  | ||||
| 	const bool saving; | ||||
|  | ||||
| 	JsonSerializeFormat() = delete; | ||||
| @@ -64,10 +74,20 @@ public: | ||||
|  | ||||
| 	JsonStructSerializer enterStruct(const std::string & fieldName); | ||||
|  | ||||
| 	virtual void serializeBool(const std::string & fieldName, bool & value) = 0; | ||||
| 	virtual void serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) = 0; | ||||
| 	template <typename T> | ||||
| 	void serializeBool(const std::string & fieldName, const T trueValue, const T falseValue, T & value) | ||||
| 	{ | ||||
| 		bool temp = (value == trueValue); | ||||
| 		serializeBool(fieldName, temp); | ||||
| 		if(!saving) | ||||
| 			value = temp ? trueValue : falseValue; | ||||
| 	} | ||||
|  | ||||
| 	/** @brief Restrictive serialization of Logical identifier condition (only "anyOf" used), full deserialization | ||||
| 	virtual void serializeBool(const std::string & fieldName, bool & value) = 0; | ||||
|  | ||||
| 	virtual void serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) = 0; | ||||
|  | ||||
| 	/** @brief Restrictive ("anyOf") simple serialization of Logical identifier condition, simple deserialization (allOf=anyOf) | ||||
| 	 * | ||||
| 	 * @param fieldName | ||||
| 	 * @param decoder resolve callback, should report errors itself and do not throw | ||||
| @@ -77,6 +97,9 @@ public: | ||||
| 	 */ | ||||
| 	virtual void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) = 0; | ||||
|  | ||||
| 	/** @brief Complete serialization of Logical identifier condition | ||||
| 	 */ | ||||
| 	virtual void serializeLIC(const std::string & fieldName, LIC & value) = 0; | ||||
|  | ||||
| 	template <typename T> | ||||
| 	void serializeNumericEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const T defaultValue, T & value) | ||||
|   | ||||
| @@ -26,7 +26,7 @@ void JsonSerializer::serializeBool(const std::string & fieldName, bool & value) | ||||
| 		current->operator[](fieldName).Bool() = true; | ||||
| } | ||||
|  | ||||
| void JsonSerializer::serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) | ||||
| void JsonSerializer::serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) | ||||
| { | ||||
| 	current->operator[](fieldName).String() = value ? trueValue : falseValue; | ||||
| } | ||||
| @@ -57,16 +57,19 @@ void JsonSerializer::serializeLIC(const std::string & fieldName, const TDecoder | ||||
| 	assert(standard.size() == value.size()); | ||||
| 	if(standard == value) | ||||
| 		return; | ||||
| 	auto & target = current->operator[](fieldName)["anyOf"].Vector(); | ||||
| 	for(si32 idx = 0; idx < value.size(); idx ++) | ||||
|  | ||||
| 	writeLICPart(fieldName, "anyOf", encoder, value); | ||||
| } | ||||
|  | ||||
| void JsonSerializer::serializeLIC(const std::string & fieldName, LIC & value) | ||||
| { | ||||
| 	if(value.any != value.standard) | ||||
| 	{ | ||||
| 		if(value[idx]) | ||||
| 		{ | ||||
| 			JsonNode val(JsonNode::DATA_STRING); | ||||
| 			val.String() = encoder(idx); | ||||
| 			target.push_back(std::move(val)); | ||||
| 		} | ||||
| 		writeLICPart(fieldName, "anyOf", value.encoder, value.any); | ||||
| 	} | ||||
|  | ||||
| 	writeLICPart(fieldName, "allOf", value.encoder, value.all); | ||||
| 	writeLICPart(fieldName, "noneOf", value.encoder, value.none); | ||||
| } | ||||
|  | ||||
| void JsonSerializer::serializeString(const std::string & fieldName, std::string & value) | ||||
| @@ -75,3 +78,17 @@ void JsonSerializer::serializeString(const std::string & fieldName, std::string | ||||
| 		current->operator[](fieldName).String() = value; | ||||
| } | ||||
|  | ||||
| void JsonSerializer::writeLICPart(const std::string& fieldName, const std::string& partName, const TEncoder& encoder, const std::vector<bool> & data) | ||||
| { | ||||
| 	auto & target = current->operator[](fieldName)[partName].Vector(); | ||||
| 	for(si32 idx = 0; idx < data.size(); idx ++) | ||||
| 	{ | ||||
| 		if(data[idx]) | ||||
| 		{ | ||||
| 			JsonNode val(JsonNode::DATA_STRING); | ||||
| 			val.String() = encoder(idx); | ||||
| 			target.push_back(std::move(val)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -20,12 +20,16 @@ public: | ||||
| 	JsonSerializer(JsonNode & root_); | ||||
|  | ||||
| 	void serializeBool(const std::string & fieldName, bool & value) override; | ||||
| 	void serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) override; | ||||
| 	void serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) override; | ||||
| 	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override; | ||||
| 	void serializeLIC(const std::string & fieldName, LIC & value) override; | ||||
| 	void serializeString(const std::string & fieldName, std::string & value) override; | ||||
|  | ||||
| protected: | ||||
| 	void serializeFloat(const std::string & fieldName, double & value) override; | ||||
| 	void serializeIntEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const si32 defaultValue, si32 & value) override; | ||||
| 	void serializeIntId(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const si32 defaultValue, si32 & value) override; | ||||
|  | ||||
| private: | ||||
| 	void writeLICPart(const std::string & fieldName, const std::string & partName, const TEncoder & encoder, const std::vector<bool> & data); | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user