2
0
Эх сурвалжийг харах

Specify data view update order for some update views, eg. data-value may require other attributes set on the element first.

Michael Ragazzon 4 жил өмнө
parent
commit
fb2351d50a

+ 7 - 5
Source/Core/DataView.cpp

@@ -43,19 +43,21 @@ Element* DataView::GetElement() const
 	return result;
 	return result;
 }
 }
 
 
-int DataView::GetElementDepth() const {
-	return element_depth;
+int DataView::GetSortOrder() const {
+	return sort_order;
 }
 }
 
 
 bool DataView::IsValid() const {
 bool DataView::IsValid() const {
 	return static_cast<bool>(attached_element);
 	return static_cast<bool>(attached_element);
 }
 }
 
 
-DataView::DataView(Element* element) : attached_element(element->GetObserverPtr()), element_depth(0) {
+DataView::DataView(Element* element, int bias) : attached_element(element->GetObserverPtr()), sort_order(bias + 1000) {
+	RMLUI_ASSERT(bias >= -1000 && bias <= 999);
+
 	if (element)
 	if (element)
 	{
 	{
 		for (Element* parent = element->GetParentNode(); parent; parent = parent->GetParentNode())
 		for (Element* parent = element->GetParentNode(); parent; parent = parent->GetParentNode())
-			element_depth += 1;
+			sort_order += 2000;
 	}
 	}
 }
 }
 
 
@@ -127,7 +129,7 @@ bool DataViews::Update(DataModel& model, const DirtyVariables& dirty_variables)
 
 
 		// Sort by the element's depth in the document tree so that any structural changes due to a changed variable are reflected in the element's children.
 		// Sort by the element's depth in the document tree so that any structural changes due to a changed variable are reflected in the element's children.
 		// Eg. the 'data-for' view will remove children if any of its data variable array size is reduced.
 		// Eg. the 'data-for' view will remove children if any of its data variable array size is reduced.
-		std::sort(dirty_views.begin(), dirty_views.end(), [](auto&& left, auto&& right) { return left->GetElementDepth() < right->GetElementDepth(); });
+		std::sort(dirty_views.begin(), dirty_views.end(), [](auto&& left, auto&& right) { return left->GetSortOrder() < right->GetSortOrder(); });
 
 
 		for (DataView* view : dirty_views)
 		for (DataView* view : dirty_views)
 		{
 		{

+ 8 - 4
Source/Core/DataView.h

@@ -88,18 +88,22 @@ public:
 	// Returns the attached element if it still exists.
 	// Returns the attached element if it still exists.
 	Element* GetElement() const;
 	Element* GetElement() const;
 
 
-	// Returns the depth of the attached element in the document tree.
-	int GetElementDepth() const;
+	// Data views are first sorted by the depth of the attached element in the
+	// document tree, then optionally by an offset specified for each data view.
+	int GetSortOrder() const;
 	
 	
 	// Returns true if the element still exists.
 	// Returns true if the element still exists.
 	bool IsValid() const;
 	bool IsValid() const;
 	
 	
 protected:
 protected:
-	DataView(Element* element);
+	// @param[in] element The element this data view is attached to.
+	// @param[in] sort_offset A number [-1000, 999] specifying the update order of this
+	//            data view at the same tree depth, negative numbers are updated first.
+	DataView(Element* element, int sort_offset);
 
 
 private:
 private:
 	ObserverPtr<Element> attached_element;
 	ObserverPtr<Element> attached_element;
-	int element_depth;
+	int sort_order;
 };
 };
 
 
 
 

+ 13 - 6
Source/Core/DataViewDefault.cpp

@@ -39,7 +39,14 @@
 
 
 namespace Rml {
 namespace Rml {
 
 
-DataViewCommon::DataViewCommon(Element* element, String override_modifier) : DataView(element), modifier(std::move(override_modifier))
+// Some data views need to offset the update order for proper behavior.
+//  'data-value' may need other attributes applied first, eg. min/max attributes.
+static constexpr int SortOffset_DataValue = 100;
+//  'data-checked' may need a value attribute already set.
+static constexpr int SortOffset_DataChecked = 110;
+
+
+DataViewCommon::DataViewCommon(Element* element, String override_modifier, int sort_offset) : DataView(element, sort_offset), modifier(std::move(override_modifier))
 {}
 {}
 
 
 bool DataViewCommon::Initialize(DataModel& model, Element* element, const String& expression_str, const String& in_modifier)
 bool DataViewCommon::Initialize(DataModel& model, Element* element, const String& expression_str, const String& in_modifier)
@@ -78,7 +85,7 @@ void DataViewCommon::Release()
 DataViewAttribute::DataViewAttribute(Element* element) : DataViewCommon(element)
 DataViewAttribute::DataViewAttribute(Element* element) : DataViewCommon(element)
 {}
 {}
 
 
-DataViewAttribute::DataViewAttribute(Element * element, String override_attribute) : DataViewCommon(element, std::move(override_attribute))
+DataViewAttribute::DataViewAttribute(Element * element, String override_attribute, int sort_offset) : DataViewCommon(element, std::move(override_attribute), sort_offset)
 {}
 {}
 
 
 bool DataViewAttribute::Update(DataModel& model)
 bool DataViewAttribute::Update(DataModel& model)
@@ -132,10 +139,10 @@ bool DataViewAttributeIf::Update(DataModel& model)
 }
 }
 
 
 
 
-DataViewValue::DataViewValue(Element* element) : DataViewAttribute(element, "value")
+DataViewValue::DataViewValue(Element* element) : DataViewAttribute(element, "value", SortOffset_DataValue)
 {}
 {}
 
 
-DataViewChecked::DataViewChecked(Element* element) : DataViewCommon(element)
+DataViewChecked::DataViewChecked(Element* element) : DataViewCommon(element, String(), SortOffset_DataChecked)
 {}
 {}
 
 
 bool DataViewChecked::Update(DataModel & model)
 bool DataViewChecked::Update(DataModel & model)
@@ -303,7 +310,7 @@ bool DataViewVisible::Update(DataModel& model)
 }
 }
 
 
 
 
-DataViewText::DataViewText(Element* element) : DataView(element)
+DataViewText::DataViewText(Element* element) : DataView(element, 0)
 {}
 {}
 
 
 bool DataViewText::Initialize(DataModel& model, Element* element, const String& RMLUI_UNUSED_PARAMETER(expression), const String& RMLUI_UNUSED_PARAMETER(modifier))
 bool DataViewText::Initialize(DataModel& model, Element* element, const String& RMLUI_UNUSED_PARAMETER(expression), const String& RMLUI_UNUSED_PARAMETER(modifier))
@@ -449,7 +456,7 @@ String DataViewText::BuildText() const
 
 
 
 
 
 
-DataViewFor::DataViewFor(Element* element) : DataView(element)
+DataViewFor::DataViewFor(Element* element) : DataView(element, 0)
 {}
 {}
 
 
 bool DataViewFor::Initialize(DataModel& model, Element* element, const String& in_expression, const String& in_rml_content)
 bool DataViewFor::Initialize(DataModel& model, Element* element, const String& in_expression, const String& in_rml_content)

+ 2 - 2
Source/Core/DataViewDefault.h

@@ -43,7 +43,7 @@ using DataExpressionPtr = UniquePtr<DataExpression>;
 
 
 class DataViewCommon : public DataView {
 class DataViewCommon : public DataView {
 public:
 public:
-	DataViewCommon(Element* element, String override_modifier = String());
+	DataViewCommon(Element* element, String override_modifier = String(), int sort_offset = 0);
 
 
 	bool Initialize(DataModel& model, Element* element, const String& expression, const String& modifier) override;
 	bool Initialize(DataModel& model, Element* element, const String& expression, const String& modifier) override;
 
 
@@ -65,7 +65,7 @@ private:
 class DataViewAttribute : public DataViewCommon {
 class DataViewAttribute : public DataViewCommon {
 public:
 public:
 	DataViewAttribute(Element* element);
 	DataViewAttribute(Element* element);
-	DataViewAttribute(Element* element, String override_attribute);
+	DataViewAttribute(Element* element, String override_attribute, int sort_offset);
 
 
 	bool Update(DataModel& model) override;
 	bool Update(DataModel& model) override;
 };
 };