HierarchyObjectInterface Manual
maxon::HierarchyObjectInterface is a base interface used to create elements that can be organized in a tree like structure. A parent element can have one or many child elements. A child element can have only one parent but none, one or many siblings.
A parent object can organize its child elements in multiple sub-branches.
The hierarchy interface provides functions to insert an element into a given tree structure:
// create "root" element const TreeElementRef root = TreeElementFactory().Create( "root" _s) iferr_return ; // create child elements const TreeElementRef elementA = TreeElementFactory().Create( "Element A" _s) iferr_return ; const TreeElementRef elementB = TreeElementFactory().Create( "Element B" _s) iferr_return ; const TreeElementRef elementC = TreeElementFactory().Create( "Element C" _s) iferr_return ;
// insert first element under the root element elementC.InsertAsLastChildOf(root) iferr_return ;
// insert second element as a sibling under the root element elementB.InsertBefore(elementC) iferr_return ;
// insert third element under the root element root.InsertChildAsFirst(elementA) iferr_return ;
// check element order
Child elements can be replaced or removed:
// create "root" element const TreeElementRef root = TreeElementFactory().Create( "root" _s) iferr_return ;
// create child elements const TreeElementRef elementA = TreeElementFactory().Create( "Element A" _s) iferr_return ; const TreeElementRef elementB = TreeElementFactory().Create( "Element B" _s) iferr_return ; const TreeElementRef elementC = TreeElementFactory().Create( "Element C" _s) iferr_return ;
// insert child elements root.InsertChildAsFirst(elementA) iferr_return ; root.InsertChildAsFirst(elementB) iferr_return ;
// replace element elementB.Replace(elementC) iferr_return ;
// remove element elementA.Remove();
// check remaining element const maxon::HierarchyObjectRef<> firstChild = root.GetFirstChild(); const TreeElementRef firstElement = maxon::Cast<TreeElementRef>(firstChild); DiagnosticOutput ( "First Child: @" , firstElement.GetName());
Within a given hierarchy level one can navigate with:
// get first child element maxon::HierarchyObjectRef<> child = root.GetFirstChild(); while (child) { // check type of child if (child.IsInstanceOf<TreeElementRef>()) { const TreeElementRef treeElement = maxon::Cast<TreeElementRef>(child); DiagnosticOutput ( "Tree Element: @" , treeElement.GetName()); }
// get next child child = child.GetNext(); }
The parent of an element is accessed with:
The child elements of a parent object are accessed with:
// define branch IDs const maxon::ConstDataPtr branchA = maxon::ConstDataPtr ( "a" ); const maxon::ConstDataPtr branchB = maxon::ConstDataPtr ( "b" );
// insert child elements into branches root.InsertChildAsFirst(elementA, branchA) iferr_return ; root.InsertChildAsFirst(elementB, branchB) iferr_return ;
// get child elements from branches const maxon::HierarchyObjectRef<> childA = root.GetFirstChild(branchA); const maxon::HierarchyObjectRef<> childB = root.GetFirstChild(branchB);
These observables are called on certain events:
ObservableHierarchyInsert:
Is called when an element was inserted in the hierarchy.
ObservableHierarchyRemove:
Is called when an element was removed from the hierarchy.
To navigate through a given hierarchy one can use these utility functions:
// This example traverses over all child elements of the given root element but not the root element itself. maxon::TraverseChildren<TreeElementRef>(root, []( const TreeElementRef& child, const TreeElementRef& parent, const maxon::ConstDataPtr & branch, maxon::Int depth) -> maxon::Result<maxon::Bool> { DiagnosticOutput ( "Tree Element: @" , child.GetName()); return true ; }) iferr_return ;
It is also possible to iterate over all elements of a hierarchy using maxon::HierarchyObjectIterator :
// This example uses the HierarchyObjectIterator template to iterate over // all child elements of the given root element and the root element itself. for ( const TreeElementRef& element : maxon::HierarchyObjectIterator<TreeElementRef> (root)) { DiagnosticOutput ( "Tree Element: @" , element.GetName()); }
A custom interface can be based on
maxon::HierarchyObjectInterface
. The resulting reference object can be organized in a tree. The default implementation of
maxon::HierarchyObjectInterface
is
maxon::HierarchyObjectClass
.
An interface based on maxon::HierarchyObjectInterface can implement maxon::HierarchyObjectInterface::ParentChanged() to be informed when the parent of the element has changed. This function must not be called by user code.
// This example shows an implementation of an interface based on HierarchyObjectInterface. // It implements ParentChanged() and accesses the hierarchy in GetParentName().// implementation of TreeElementInterface class TreeElementImplementation : public maxon::Component <TreeElementImplementation, TreeElementInterface> { // use the default implementation "HierarchyObjectClass" MAXON_COMPONENT ( NORMAL , maxon::HierarchyObjectClass); public : MAXON_METHOD void SetName( maxon::String name) { _name = name; } MAXON_METHOD maxon::String GetName() const { return _name; }
// function that returns the name of the parent element MAXON_METHOD maxon::Result<maxon::String> GetParentName() const { // access parent element const auto parentObject = super.GetParent(); if (!parentObject) return maxon::String ();
// check type of parent element if (!parentObject.IsInstanceOf<TreeElementRef>()) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION , "Parent object is no TreeElementRef." _s);
// get name of parent element const TreeElementRef treeElement = maxon::Cast<TreeElementRef>(parentObject); return treeElement.GetName(); } MAXON_METHOD void ParentChanged( maxon::Bool removed) { if (removed) return ;
// if a new parent is assigned, print the parent's name const auto parentObject = super.GetParent(); if (parentObject.IsInstanceOf<TreeElementRef>()) { const TreeElementRef treeElement = maxon::Cast<TreeElementRef>(parentObject); DiagnosticOutput ( "New Parent is @" , treeElement.GetName()); } }
// Factory method maxon::Result<void> FactoryInit(maxon::FactoryInterface::ConstPtr, maxon::String name) { self .SetName(name); return maxon::OK ; } private : maxon::String _name; };