Skip to content

Commit

Permalink
feat: Render nested components
Browse files Browse the repository at this point in the history
  • Loading branch information
huyenngn committed Apr 29, 2024
1 parent c9226d3 commit f4e44d0
Showing 1 changed file with 61 additions and 27 deletions.
88 changes: 61 additions & 27 deletions capellambse_context_diagrams/collectors/exchanges.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import typing as t

from capellambse.model import common
from capellambse.model.crosslayer import cs
from capellambse.model.modeltypes import DiagramType as DT

from .. import _elkjs, context
Expand Down Expand Up @@ -90,6 +91,28 @@ def get_functions_and_exchanges(

return functions, incomings, outgoings

def collect_context(
self, comp: common.GenericElement, interface: common.GenericElement
) -> dict[str, t.Any]:
functions, outgoings, incomings = self.get_functions_and_exchanges(
comp, interface
)
components = []
for cmp in comp.components:
fncs, incs, outs = self.get_functions_and_exchanges(cmp, interface)
functions.extend(fncs)
outgoings.extend(outs)
incomings.extend(incs)
if fncs:
components.append(self.collect_context(cmp, interface))
return {
"element": comp,
"functions": functions,
"outgoings": outgoings,
"incomings": incomings,
"components": components,
}

def make_ports_and_update_children_size(
self,
data: _elkjs.ELKInputChild,
Expand All @@ -100,6 +123,9 @@ def make_ports_and_update_children_size(
for child in data["children"]:
inputs, outputs = [], []
obj = self.obj._model.by_uuid(child["id"])
if isinstance(obj, cs.Component):
self.make_ports_and_update_children_size(child, exchanges)
return
port_ids = {p.uuid for p in obj.inputs + obj.outputs}
for ex in exchanges:
source, target = ex["sources"][0], ex["targets"][0]
Expand Down Expand Up @@ -178,15 +204,19 @@ def get_capella_order(
alloc_functions = self.get_alloc_functions(comp)
return [fnc for fnc in alloc_functions if fnc in functions]

def make_boxes(
comp: common.GenericElement, functions: list[common.GenericElement]
) -> None:
def make_boxes(cntxt: dict[str, t.Any]) -> _elkjs.ELKInputChild | None:
comp = cntxt["element"]
functions = cntxt["functions"]
components = cntxt["components"]
if comp.uuid not in made_children:
children = [
makers.make_box(c)
for c in functions
if c in self.get_alloc_functions(comp)
]
for c in components:
if child := make_boxes(c):
children.append(child)
if children:
layout_options = makers.DEFAULT_LABEL_LAYOUT_OPTIONS
else:
Expand All @@ -196,45 +226,49 @@ def make_boxes(
comp, no_symbol=True, layout_options=layout_options
)
box["children"] = children
self.data["children"].append(box)
made_children.add(comp.uuid)
return box
return None

try:
comp = self.get_source(self.obj)
functions, incs, outs = self.get_functions_and_exchanges(
comp, self.obj
left_context = self.collect_context(comp, self.obj)
functions = left_context["functions"]
inc_port_ids = set(
ex.target.uuid for ex in left_context["incomings"]
)
out_port_ids = set(
ex.source.uuid for ex in left_context["outgoings"]
)
inc_port_ids = set(ex.target.uuid for ex in incs)
out_port_ids = set(ex.source.uuid for ex in outs)
port_spread = len(out_port_ids) - len(inc_port_ids)

_comp = self.get_target(self.obj)
_functions, _, _ = self.get_functions_and_exchanges(
_comp, self.obj
right_context = self.collect_context(_comp, self.obj)
_functions = right_context["functions"]
_inc_port_ids = set(
ex.target.uuid for ex in left_context["outgoings"]
)
_out_port_ids = set(
ex.source.uuid for ex in left_context["incomings"]
)
_inc_port_ids = set(ex.target.uuid for ex in outs)
_out_port_ids = set(ex.source.uuid for ex in incs)
_port_spread = len(_out_port_ids) - len(_inc_port_ids)

functions = get_capella_order(comp, functions)
_functions = get_capella_order(_comp, _functions)
if port_spread >= _port_spread:
self.left = comp
self.right = _comp
self.outgoing_edges = outs
self.incoming_edges = incs
left_functions = functions
right_functions = _functions
self.outgoing_edges = left_context["outgoings"]
self.incoming_edges = left_context["incomings"]
else:
self.left = _comp
self.right = comp
self.outgoing_edges = incs
self.incoming_edges = outs
left_functions = _functions
right_functions = functions

make_boxes(self.left, left_functions)
make_boxes(self.right, right_functions)
temp = left_context
left_context = right_context
right_context = temp
self.outgoing_edges = left_context["incomings"]
self.incoming_edges = left_context["outgoings"]

if left_child := make_boxes(left_context):
self.data["children"].append(left_child)
if right_child := make_boxes(right_context):
self.data["children"].append(right_child)
except AttributeError:
pass

Expand Down

0 comments on commit f4e44d0

Please sign in to comment.