56 lines
1.4 KiB
Python
56 lines
1.4 KiB
Python
from typing import Callable, List
|
|
|
|
from jinja2 import Template
|
|
|
|
from .singleton import Singleton
|
|
|
|
|
|
class IdGenerator(metaclass=Singleton):
|
|
exec_id = -1
|
|
node_id = -1
|
|
|
|
@classmethod
|
|
def generate_node_id(cls) -> int:
|
|
cls.node_id +=1
|
|
return cls.node_id
|
|
|
|
@classmethod
|
|
def generate_exec_id(cls) -> int:
|
|
cls.exec_id += 1
|
|
return cls.exec_id
|
|
|
|
def generate_dot_wrap(func) -> Callable:
|
|
def wrapper(self, *args, **kwargs) -> str:
|
|
nodes = []
|
|
edges = []
|
|
self.reset_visited()
|
|
func(self, nodes, edges, *args, **kwargs)
|
|
return f"digraph G {{\n\t{"\n\t".join(nodes)}\n\t{"\n\t".join(edges)}\n}}"
|
|
|
|
return wrapper
|
|
|
|
|
|
def not_visited(func) -> Callable:
|
|
def wrapper(
|
|
self, nodes: List[str], edges: List[str], visited: set[int], *args, **kwargs
|
|
) -> None:
|
|
if self in visited:
|
|
return
|
|
visited.add(self)
|
|
func(self, nodes, edges, visited, *args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
def generate_dot_node(self, nodes: List[str], template: Template, **kwargs) -> None:
|
|
nodes.append(template.module.__getattribute__("Node")(**{**kwargs, "id": self.id}))
|
|
|
|
|
|
def generate_dot_edge(
|
|
self, target, edges: List[str], template: Template, kwargs
|
|
) -> None:
|
|
edges.append(
|
|
template.module.__getattribute__("Edge")(
|
|
**{**kwargs, "from_id": self.id, "to_id": target.id}
|
|
)
|
|
)
|