Преглед на файлове

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 години
родител
ревизия
a076be2494

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

@@ -103,7 +103,7 @@ private:
 	KeyframesMap keyframes;
 	KeyframesMap keyframes;
 
 
 	// Name of every @decorator mapped to their specification
 	// 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
 	// Name of every @spritesheet and underlying sprites mapped to their values
 	SpritesheetList spritesheet_list;
 	SpritesheetList spritesheet_list;

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

@@ -54,8 +54,8 @@ using KeyframesMap = UnorderedMap<String, Keyframes>;
 
 
 struct NamedDecorator {
 struct NamedDecorator {
 	String type;
 	String type;
+	DecoratorInstancer* instancer;
 	PropertyDictionary properties;
 	PropertyDictionary properties;
-	SharedPtr<Decorator> decorator;
 };
 };
 using NamedDecoratorMap = UnorderedMap<String, NamedDecorator>;
 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)
 		instancer(declaration.instancer), type(&declaration.type), properties(&declaration.properties), paint_area(declaration.paint_area)
 	{}
 	{}
 	EffectDeclarationView(const NamedDecorator* named_decorator) :
 	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) :
 	EffectDeclarationView(const FilterDeclaration& declaration) :
 		instancer(declaration.instancer), type(&declaration.type), properties(&declaration.properties)
 		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->root = root->DeepCopy();
 	new_sheet->specificity_offset = specificity_offset;
 	new_sheet->specificity_offset = specificity_offset;
 	new_sheet->keyframes = keyframes;
 	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->spritesheet_list = spritesheet_list;
 
 
 	new_sheet->MergeStyleSheet(other_sheet);
 	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
 	// 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(),
 	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
 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 &(it->second);
 	return nullptr;
 	return nullptr;
 }
 }
@@ -162,9 +162,10 @@ const DecoratorPtrList& StyleSheet::InstanceDecorators(const DecoratorDeclaratio
 		else
 		else
 		{
 		{
 			// If we have no instancer, this means the type is the name of an @decorator rule.
 			// 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)
 			if (!decorator)
 				Log::Message(Log::LT_WARNING, "Decorator name '%s' could not be found in any @decorator rule, declared at %s:%d",
 				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;
 	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)
 	const SharedPtr<const PropertySource>& source)
 {
 {
 	StringList name_type;
 	StringList name_type;
@@ -341,8 +341,8 @@ bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, NamedDecorator
 	const String& name = name_type[0];
 	const String& name = name_type[0];
 	String decorator_type = name_type[1];
 	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(),
 		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);
 			stream_file_name.c_str(), line_number);
@@ -356,8 +356,8 @@ bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, NamedDecorator
 	if (!decorator_instancer)
 	if (!decorator_instancer)
 	{
 	{
 		// Type is not a declared decorator type, instead, see if it is another decorator name, then we inherit its properties.
 		// 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.
 			// Yes, try to retrieve the instancer from the parent type, and add its property values.
 			decorator_instancer = Factory::GetDecoratorInstancer(it->second.type);
 			decorator_instancer = Factory::GetDecoratorInstancer(it->second.type);
@@ -384,16 +384,7 @@ bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, NamedDecorator
 	property_specification.SetPropertyDefaults(properties);
 	property_specification.SetPropertyDefaults(properties);
 	properties.SetSourceOfAllProperties(source);
 	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;
 	return true;
 }
 }
@@ -599,7 +590,7 @@ bool StyleSheetParser::Parse(MediaBlockList& style_sheets, Stream* _stream, int
 					else if (at_rule_identifier == "decorator")
 					else if (at_rule_identifier == "decorator")
 					{
 					{
 						auto source = MakeShared<PropertySource>(stream_file_name, (int)line_number, pre_token_str);
 						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();
 						at_rule_name.clear();
 						state = State::Global;
 						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);
 	bool ParseKeyframeBlock(KeyframesMap& keyframes_map, const String& identifier, const String& rules, const PropertyDictionary& properties);
 
 
 	// Attempts to parse a @decorator block
 	// 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
 	// Attempts to parse the properties of a @media query
 	bool ParseMediaFeatureMap(PropertyDictionary& properties, const String& rules);
 	bool ParseMediaFeatureMap(PropertyDictionary& properties, const String& rules);