Skip to content

Commit

Permalink
Postpone instancing named decorators until other decorators are insta…
Browse files Browse the repository at this point in the history
…nced

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.
  • Loading branch information
mikke89 committed Aug 5, 2023
1 parent f4414b8 commit a076be2
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Include/RmlUi/Core/StyleSheet.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class RMLUICORE_API StyleSheet final : public NonCopyMoveable {
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;
Expand Down
2 changes: 1 addition & 1 deletion Include/RmlUi/Core/StyleSheetTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>;

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/ElementAnimation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
19 changes: 10 additions & 9 deletions Source/Core/StyleSheet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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(),
Expand All @@ -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;
}
Expand Down Expand Up @@ -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",
Expand Down
23 changes: 7 additions & 16 deletions Source/Core/StyleSheetParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions Source/Core/StyleSheetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ class StyleSheetParser {
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);
Expand Down

0 comments on commit a076be2

Please sign in to comment.