Sfoglia il codice sorgente

Postpone instancing named decorators until other decorators are instanced

Previously, they were instanced the moment they were encountered in the style sheet parser. With this change, the render manager is always available at the time of instancing.
Michael Ragazzon 2 anni fa
parent
commit
a076be2494

+ 1 - 1
Include/RmlUi/Core/StyleSheet.h

@@ -103,7 +103,7 @@ private:
 	KeyframesMap keyframes;
 
 	// Name of every @decorator mapped to their specification
-	NamedDecoratorMap decorator_map;
+	NamedDecoratorMap named_decorator_map;
 
 	// Name of every @spritesheet and underlying sprites mapped to their values
 	SpritesheetList spritesheet_list;

+ 1 - 1
Include/RmlUi/Core/StyleSheetTypes.h

@@ -54,8 +54,8 @@ using KeyframesMap = UnorderedMap<String, Keyframes>;
 
 struct NamedDecorator {
 	String type;
+	DecoratorInstancer* instancer;
 	PropertyDictionary properties;
-	SharedPtr<Decorator> decorator;
 };
 using NamedDecoratorMap = UnorderedMap<String, NamedDecorator>;
 

+ 1 - 1
Source/Core/ElementAnimation.cpp

@@ -100,7 +100,7 @@ struct EffectDeclarationView {
 		instancer(declaration.instancer), type(&declaration.type), properties(&declaration.properties), paint_area(declaration.paint_area)
 	{}
 	EffectDeclarationView(const NamedDecorator* named_decorator) :
-		instancer(Factory::GetDecoratorInstancer(named_decorator->type)), type(&named_decorator->type), properties(&named_decorator->properties)
+		instancer(named_decorator->instancer), type(&named_decorator->type), properties(&named_decorator->properties)
 	{}
 	EffectDeclarationView(const FilterDeclaration& declaration) :
 		instancer(declaration.instancer), type(&declaration.type), properties(&declaration.properties)

+ 10 - 9
Source/Core/StyleSheet.cpp

@@ -56,7 +56,7 @@ UniquePtr<StyleSheet> StyleSheet::CombineStyleSheet(const StyleSheet& other_shee
 	new_sheet->root = root->DeepCopy();
 	new_sheet->specificity_offset = specificity_offset;
 	new_sheet->keyframes = keyframes;
-	new_sheet->decorator_map = decorator_map;
+	new_sheet->named_decorator_map = named_decorator_map;
 	new_sheet->spritesheet_list = spritesheet_list;
 
 	new_sheet->MergeStyleSheet(other_sheet);
@@ -79,10 +79,10 @@ void StyleSheet::MergeStyleSheet(const StyleSheet& other_sheet)
 	}
 
 	// Copy over the decorators, and replace any matching decorator names from other_sheet
-	decorator_map.reserve(decorator_map.size() + other_sheet.decorator_map.size());
-	for (auto& other_decorator : other_sheet.decorator_map)
+	named_decorator_map.reserve(named_decorator_map.size() + other_sheet.named_decorator_map.size());
+	for (auto& other_decorator : other_sheet.named_decorator_map)
 	{
-		decorator_map[other_decorator.first] = other_decorator.second;
+		named_decorator_map[other_decorator.first] = other_decorator.second;
 	}
 
 	spritesheet_list.Reserve(spritesheet_list.NumSpriteSheets() + other_sheet.spritesheet_list.NumSpriteSheets(),
@@ -99,8 +99,8 @@ void StyleSheet::BuildNodeIndex()
 
 const NamedDecorator* StyleSheet::GetNamedDecorator(const String& name) const
 {
-	auto it = decorator_map.find(name);
-	if (it != decorator_map.end())
+	auto it = named_decorator_map.find(name);
+	if (it != named_decorator_map.end())
 		return &(it->second);
 	return nullptr;
 }
@@ -162,9 +162,10 @@ const DecoratorPtrList& StyleSheet::InstanceDecorators(const DecoratorDeclaratio
 		else
 		{
 			// If we have no instancer, this means the type is the name of an @decorator rule.
-			auto it_map = decorator_map.find(declaration.type);
-			if (it_map != decorator_map.end())
-				decorator = it_map->second.decorator;
+			auto it_map = named_decorator_map.find(declaration.type);
+			if (it_map != named_decorator_map.end())
+				decorator = it_map->second.instancer->InstanceDecorator(it_map->second.type, it_map->second.properties,
+					DecoratorInstancerInterface(*this, source));
 
 			if (!decorator)
 				Log::Message(Log::LT_WARNING, "Decorator name '%s' could not be found in any @decorator rule, declared at %s:%d",

+ 7 - 16
Source/Core/StyleSheetParser.cpp

@@ -325,7 +325,7 @@ bool StyleSheetParser::ParseKeyframeBlock(KeyframesMap& keyframes_map, const Str
 	return true;
 }
 
-bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, NamedDecoratorMap& decorator_map, const StyleSheet& style_sheet,
+bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, NamedDecoratorMap& named_decorator_map,
 	const SharedPtr<const PropertySource>& source)
 {
 	StringList name_type;
@@ -341,8 +341,8 @@ bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, NamedDecorator
 	const String& name = name_type[0];
 	String decorator_type = name_type[1];
 
-	auto it_find = decorator_map.find(name);
-	if (it_find != decorator_map.end())
+	auto it_find = named_decorator_map.find(name);
+	if (it_find != named_decorator_map.end())
 	{
 		Log::Message(Log::LT_WARNING, "Decorator with name '%s' already declared, ignoring decorator at %s:%d.", name.c_str(),
 			stream_file_name.c_str(), line_number);
@@ -356,8 +356,8 @@ bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, NamedDecorator
 	if (!decorator_instancer)
 	{
 		// Type is not a declared decorator type, instead, see if it is another decorator name, then we inherit its properties.
-		auto it = decorator_map.find(decorator_type);
-		if (it != decorator_map.end())
+		auto it = named_decorator_map.find(decorator_type);
+		if (it != named_decorator_map.end())
 		{
 			// Yes, try to retrieve the instancer from the parent type, and add its property values.
 			decorator_instancer = Factory::GetDecoratorInstancer(it->second.type);
@@ -384,16 +384,7 @@ bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, NamedDecorator
 	property_specification.SetPropertyDefaults(properties);
 	properties.SetSourceOfAllProperties(source);
 
-	SharedPtr<Decorator> decorator =
-		decorator_instancer->InstanceDecorator(decorator_type, properties, DecoratorInstancerInterface(style_sheet, source.get()));
-	if (!decorator)
-	{
-		Log::Message(Log::LT_WARNING, "Could not instance decorator of type '%s' declared at %s:%d.", decorator_type.c_str(),
-			stream_file_name.c_str(), line_number);
-		return false;
-	}
-
-	decorator_map.emplace(name, NamedDecorator{std::move(decorator_type), std::move(properties), std::move(decorator)});
+	named_decorator_map.emplace(name, NamedDecorator{std::move(decorator_type), decorator_instancer, std::move(properties)});
 
 	return true;
 }
@@ -599,7 +590,7 @@ bool StyleSheetParser::Parse(MediaBlockList& style_sheets, Stream* _stream, int
 					else if (at_rule_identifier == "decorator")
 					{
 						auto source = MakeShared<PropertySource>(stream_file_name, (int)line_number, pre_token_str);
-						ParseDecoratorBlock(at_rule_name, current_block.stylesheet->decorator_map, *current_block.stylesheet, source);
+						ParseDecoratorBlock(at_rule_name, current_block.stylesheet->named_decorator_map, source);
 
 						at_rule_name.clear();
 						state = State::Global;

+ 1 - 2
Source/Core/StyleSheetParser.h

@@ -105,8 +105,7 @@ private:
 	bool ParseKeyframeBlock(KeyframesMap& keyframes_map, const String& identifier, const String& rules, const PropertyDictionary& properties);
 
 	// Attempts to parse a @decorator block
-	bool ParseDecoratorBlock(const String& at_name, NamedDecoratorMap& decorator_map, const StyleSheet& style_sheet,
-		const SharedPtr<const PropertySource>& source);
+	bool ParseDecoratorBlock(const String& at_name, NamedDecoratorMap& named_decorator_map, const SharedPtr<const PropertySource>& source);
 
 	// Attempts to parse the properties of a @media query
 	bool ParseMediaFeatureMap(PropertyDictionary& properties, const String& rules);