Skip to content

Commit

Permalink
Merge pull request #377 from Volue-Public/emmaluciano/bottom-top-trav…
Browse files Browse the repository at this point in the history
…ersal

Add bottom top traversal support
  • Loading branch information
emmaluciano authored Nov 20, 2023
2 parents 2aaecd8 + d04031d commit 44dedf9
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
12 changes: 12 additions & 0 deletions src/volue/mesh/_attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ def __init__(
self.id: uuid.UUID = _from_proto_guid(proto_attribute.id)
self.path: str = proto_attribute.path
self.name: str = proto_attribute.name
# owner_id field is always set starting from Mesh 2.11
# TODO: Remove the check if the owner_id field exists when we move to support Mesh >= 2.11
self.owner_id = (
_from_proto_guid(proto_attribute.owner_id.id)
if proto_attribute.HasField("owner_id")
else None
)
self.owner_path = (
proto_attribute.owner_id.path
if proto_attribute.HasField("owner_id")
else None
)

self.definition = None

Expand Down
45 changes: 35 additions & 10 deletions src/volue/mesh/examples/traverse_model.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
from volue.mesh import Connection, OwnershipRelationAttribute
from volue.mesh.examples import _get_connection_info

leaves = []

def traverse_model(session: Connection.Session, target, depth=0):

def traverse_model_top_down(session: Connection.Session, target, depth=0):
"""Traverses the Mesh model recursively."""
object = session.get_object(target)
print(f"{'..' * depth}{object.name}")
leaf = True

for attr in object.attributes.values():
if isinstance(attr, OwnershipRelationAttribute):
for child_id in attr.target_object_ids:
traverse_model(session, child_id, depth + 1)
leaf = False
traverse_model_top_down(session, child_id, depth + 1)
if leaf:
leaves.append(object)


def traverse_model_bottom_up(session: Connection.Session, target, model):
object = session.get_object(target)
depth = object.path.count("/") - 1
print(f"{'..' * depth}{object.name}")
if object.owner_id == model.id:
print(model.name)
return
attribute = session.get_attribute(object.owner_id)
traverse_model_bottom_up(session, attribute.owner_id, model)


def main(address, port, root_pem_certificate):
Expand All @@ -20,14 +37,22 @@ def main(address, port, root_pem_certificate):
with connection.create_session() as session:
models = session.list_models()
for model in models:
traverse_model(session, model.id)

# Excepted output:
# Model
# ..ChildObject1
# ....SubChildObject1
# ....SubChildObject2
# ..ChildObject2
leaves.clear()
print(f"\nModel: '{model.name}'")
print("Top-bottom traversal:")
traverse_model_top_down(session, model.id)
# Excepted output:
# Model
# ..ChildObject1
# ....SubChildObject1
# ....SubChildObject2
# ..ChildObject2
print("\nBottom-top traversal:")
traverse_model_bottom_up(session, leaves[0].id, model)
# Excepted output:
# ....SubChildObject1
# ..ChildObject1
# Model


if __name__ == "__main__":
Expand Down
2 changes: 2 additions & 0 deletions src/volue/mesh/proto/core/v1alpha/core.proto
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,8 @@ message Attribute {
AttributeValueType value_type = 6;
// If the `value_type` is a collection then this flag is set to `True`.
bool value_type_collection = 7;

MeshId owner_id = 8;
}

enum AttributeValueType {
Expand Down
5 changes: 5 additions & 0 deletions src/volue/mesh/tests/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ def verify_plant_base_attribute(
assert attribute.path == path
assert attribute.name == name
assert attribute.id == id
assert attribute.owner_id == uuid.UUID("0000000a-0001-0000-0000-000000000000")
assert (
attribute.owner_path
== "Model/SimpleThermalTestModel/ThermalComponent.ThermalPowerToPlantRef/SomePowerPlant1"
)

if is_definition:
assert (
Expand Down

0 comments on commit 44dedf9

Please sign in to comment.