Browse Source

Remove the old IterateProperties, replace with new iterators

Michael Ragazzon 6 years ago
parent
commit
85a633693c

+ 7 - 7
Include/Rocket/Core/Element.h

@@ -57,6 +57,7 @@ class ElementDefinition;
 class ElementDocument;
 class ElementScroll;
 class ElementStyle;
+class ElementStyleIterator;
 class FontFaceHandle;
 class PropertyDictionary;
 class RenderInterface;
@@ -260,13 +261,12 @@ public:
 	/// @return True if a new animation key was added.
 	bool AddAnimationKey(const String& property_name, const Property& target_value, float duration, Tween tween = Tween{});
 	
-	/// Iterates over the properties defined on this element.
-	/// @param[inout] index Index of the property to fetch. This is incremented to the next valid index after the fetch. Indices are not necessarily incremental.
-	/// @param[out] pseudo_classes The pseudo-classes the property is defined by.
-	/// @param[out] name The name of the property at the specified index.
-	/// @param[out] property The property at the specified index.
-	/// @return True if a property was successfully fetched.
-	bool IterateProperties(int& index, String& name, const Property*& property, const PseudoClassList** pseudo_classes = nullptr) const;
+	/// Iterators for the properties defined on this element.
+	/// @warning Modifying the element's properties or classes invalidates the iterators.
+	/// @return Iterator to the first property defined on this element.
+	ElementStyleIterator IteratePropertiesBegin() const;
+	/// @return Iterator to the one-past-the-last property defined on this element.
+	ElementStyleIterator IteratePropertiesEnd() const;
 	///@}
 
 	/** @name Pseudo-classes

+ 6 - 3
Source/Core/Element.cpp

@@ -866,11 +866,14 @@ const Vector2f Element::Project(const Vector2f& point) noexcept
 	}
 }
 
+ElementStyleIterator Element::IteratePropertiesBegin() const
+{
+	return style->begin();
+}
 
-// Iterates over the properties defined on this element.
-bool Element::IterateProperties(int& index, String& name, const Property*& property, const PseudoClassList** pseudo_classes) const
+ElementStyleIterator Element::IteratePropertiesEnd() const
 {
-	return style->IterateProperties(index, name, property, pseudo_classes);
+	return style->end();
 }
 
 // Sets or removes a pseudo-class on the element.

+ 0 - 54
Source/Core/ElementDefinition.cpp

@@ -227,60 +227,6 @@ void ElementDefinition::GetDefinedProperties(PropertyNameList& property_names, c
 	}
 }
 
-// Iterates over the properties in the definition.
-bool ElementDefinition::IterateProperties(int& index, const PseudoClassList& pseudo_classes, String& property_name, const Property*& property, const PseudoClassList** property_pseudo_classes) const
-{
-	if (index < properties.GetNumProperties())
-	{
-		PropertyMap::const_iterator i = properties.GetProperties().begin();
-		for (int count = 0; count < index; ++count)
-			++i;
-
-		if (property_pseudo_classes)
-			* property_pseudo_classes = nullptr;
-		property_name = (*i).first;
-		property = &((*i).second);
-		++index;
-
-		return true;
-	}
-
-	// Not in the base properties; check for pseudo-class overrides.
-	int property_count = properties.GetNumProperties();
-	for (PseudoClassPropertyDictionary::const_iterator i = pseudo_class_properties.begin(); i != pseudo_class_properties.end(); ++i)
-	{
-		// Iterate over each pseudo-class set that has a definition for this property; if we find one that matches our
-		// pseudo-class, increment our index counter and either return that property (if we hit the requested index) or
-		// continue looking if we're still below it.
-		for (size_t j = 0; j < (*i).second.size(); ++j)
-		{
-			// @Performance: We are re-iterating this for every call to this function, can certainly optimize this! See also ++i over.
-			if (IsPseudoClassRuleApplicable((*i).second[j].first, pseudo_classes))
-			{
-				property_count++;
-				if (property_count > index)
-				{
-					// Copy the list of pseudo-classes.
-					if(property_pseudo_classes)
-						*property_pseudo_classes = &(*i).second[j].first;
-
-					property_name = (*i).first;
-					property = &((*i).second[j].second);
-					++index;
-
-					return true;
-				}
-				else
-				{
-					break;
-				}
-			}
-		}
-	}
-
-	return false;
-}
-
 // Returns the list of the element definition's instanced decorators in the default state.
 const DecoratorMap& ElementDefinition::GetDecorators() const
 {

+ 0 - 9
Source/Core/ElementDefinition.h

@@ -82,15 +82,6 @@ public:
 	/// @param[in] pseudo_class The pseudo-class that was just activated or deactivated.
 	void GetDefinedProperties(PropertyNameList& property_names, const PseudoClassList& pseudo_classes, const String& pseudo_class) const;
 
-	/// Iterates over the properties in the definition.
-	/// @param[inout] index Index of the property to fetch. This is incremented to the next valid index after the fetch.
-	/// @param[in] pseudo_classes The pseudo-classes defined on the querying element.
-	/// @param[out] property_pseudo_classes The pseudo-classes the property is defined by.
-	/// @param[out] property_name The name of the property at the specified index.
-	/// @param[out] property The property at the specified index.
-	/// @return True if a property was successfully fetched.
-	bool IterateProperties(int& index, const PseudoClassList& pseudo_classes, String& property_name, const Property*& property, const PseudoClassList** property_pseudo_classes = nullptr) const;
-
 	/// Returns the list of the element definition's instanced decorators in the default state.
 	/// @return The list of instanced decorators.
 	const DecoratorMap& GetDecorators() const;

+ 0 - 48
Source/Core/ElementStyle.cpp

@@ -480,54 +480,6 @@ float ElementStyle::ResolveLengthPercentage(const Property* property, float base
 	return result;
 }
 
-
-// Iterates over the properties defined on the element.
-bool ElementStyle::IterateProperties(int& index, String& name, const Property*& property, const PseudoClassList** property_pseudo_classes) const
-{
-	// First check for locally defined properties.
-	if (local_properties != NULL)
-	{
-		if (index < local_properties->GetNumProperties())
-		{
-			PropertyMap::const_iterator i = local_properties->GetProperties().begin();
-			for (int count = 0; count < index; ++count)
-				++i;
-
-			name = (*i).first;
-			property = &((*i).second);
-			if (property_pseudo_classes)
-				* property_pseudo_classes = nullptr;
-			++index;
-
-			return true;
-		}
-	}
-
-	if (definition != NULL)
-	{
-		int index_offset = 0;
-		if (local_properties != NULL)
-			index_offset = local_properties->GetNumProperties();
-
-		// Offset the index to be relative to the definition before we start indexing. When we do get a property back,
-		// check that it hasn't been overridden by the element's local properties; if so, continue on to the next one.
-		index -= index_offset;
-		while (definition->IterateProperties(index, pseudo_classes, name, property, property_pseudo_classes))
-		{
-			if (local_properties == NULL ||
-				local_properties->GetProperty(name) == NULL)
-			{
-				index += index_offset;
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	return false;
-}
-
 // Returns the active style sheet for this element. This may be NULL.
 StyleSheet* ElementStyle::GetStyleSheet() const
 {

+ 0 - 8
Source/Core/ElementStyle.h

@@ -161,14 +161,6 @@ public:
 	/// Number and percentages are resolved by scaling the size of the specified target.
 	float ResolveNumberLengthPercentage(const Property* property, RelativeTarget relative_target);
 
-	/// Iterates over the properties defined on the element.
-	/// @param[inout] index Index of the property to fetch. This is incremented to the next valid index after the fetch. Indices are not necessarily incremental.
-	/// @param[out] pseudo_classes The pseudo-classes the property is defined by.
-	/// @param[out] name The name of the property at the specified index.
-	/// @param[out] property The property at the specified index.
-	/// @return True if a property was successfully fetched.
-	bool IterateProperties(int& index, String& name, const Property*& property, const PseudoClassList** pseudo_classes = nullptr) const;
-
 	/// Returns the active style sheet for this element. This may be NULL.
 	StyleSheet* GetStyleSheet() const;
 

+ 15 - 5
Source/Core/Lua/ElementStyleProxy.cpp

@@ -106,12 +106,22 @@ int ElementStyleProxy__pairs(lua_State* L)
     int* pindex = (int*)lua_touserdata(L,3);
     if((*pindex) == -1)
         *pindex = 0;
-    //iterate variables
-    String key,val;
-    const Property* prop;
-    if(obj->owner->IterateProperties((*pindex),key,prop))
+
+	int i = 0;
+	auto it = obj->owner->IteratePropertiesBegin();
+	auto it_end = obj->owner->IteratePropertiesEnd();
+	while (i < (*pindex) && it != it_end)
+	{
+		++it;
+		++i;
+	}
+
+    if(it != it_end)
     {
-        prop->definition->GetValue(val,*prop);
+		const String& key = (*it).first;
+		const Property& property = (*it).second;
+		String val;
+        property.definition->GetValue(val, (*it).second);
         lua_pushstring(L,key.c_str());
         lua_pushstring(L,val.c_str());
     }

+ 7 - 5
Source/Debugger/ElementInfo.cpp

@@ -27,6 +27,7 @@
 
 #include "ElementInfo.h"
 #include "../../Include/Rocket/Core/Property.h"
+#include "../../Include/Rocket/Core/PropertyIterators.h"
 #include "../../Include/Rocket/Core/Factory.h"
 #include "../../Include/Rocket/Core/StyleSheet.h"
 #include "Geometry.h"
@@ -441,14 +442,15 @@ void ElementInfo::BuildElementPropertiesRML(Core::String& property_rml, Core::El
 {
 	NamedPropertyMap property_map;
 
-	int property_index = 0;
-	Core::String property_name;
 	const Core::PseudoClassList empty_property_pseudo_classes;
-	const Core::PseudoClassList* property_pseudo_classes_ptr = nullptr;
-	const Core::Property* property;
 
-	while (element->IterateProperties(property_index, property_name, property, &property_pseudo_classes_ptr))
+	auto it_end = element->IteratePropertiesEnd();
+	for(auto it = element->IteratePropertiesBegin(); it != it_end; ++it)
 	{
+		const Core::String& property_name = (*it).first;
+		const Core::Property* property = &(*it).second;
+		const Core::PseudoClassList* property_pseudo_classes_ptr = it.pseudo_class_list();
+
 		// Check that this property isn't overridden or just not inherited.
 		if (primary_element->GetProperty(property_name) != property)
 			continue;