Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
clonable links
Browse files Browse the repository at this point in the history
  • Loading branch information
iopapamanoglou committed Nov 12, 2024
1 parent 4d3055d commit a281ca5
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 32 deletions.
6 changes: 6 additions & 0 deletions src/faebryk/core/cpp/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class GraphInterface:
def connect(self, others: Sequence[GraphInterface]) -> None: ...
@overload
def connect(self, other: GraphInterface, link: Link) -> None: ...
@overload
def connect(self, others: Sequence[GraphInterface], link: Link) -> None: ...

class GraphInterfaceHierarchical(GraphInterface):
def __init__(self, is_parent: bool) -> None: ...
Expand Down Expand Up @@ -129,6 +131,10 @@ class LinkDirectConditionalFilterResult(enum.Enum):
class LinkDirectDerived(LinkDirectConditional):
def __init__(self, arg: Path, /) -> None: ...

class LinkExists:
def existing_link(self) -> Link: ...
def new_link(self) -> Link: ...

class LinkFilteredException(Exception):
pass

Expand Down
14 changes: 14 additions & 0 deletions src/faebryk/core/cpp/include/graph/graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ using GI_refs_weak = std::vector<GI_ref_weak>;
using HierarchicalNodeRef = std::pair<Node_ref, std::string>;
using Link_weak_ref = Link *;

class LinkExists : public std::runtime_error {
private:
Link_ref existing_link;
Link_ref new_link;

public:
LinkExists(Link_ref existing_link, Link_ref new_link, const std::string &msg);
Link_ref get_existing_link();
Link_ref get_new_link();
};

class Node {
public:
struct NodeException : public std::runtime_error {
Expand Down Expand Up @@ -138,6 +149,7 @@ class GraphInterface {
void connect(GI_ref_weak other);
void connect(GI_refs_weak others);
void connect(GI_ref_weak other, Link_ref link);
void connect(GI_refs_weak others, Link_ref link);
// TODO replace with set_node(Node_ref node, std::string name)
void set_node(Node_ref node);
Node_ref get_node();
Expand All @@ -160,11 +172,13 @@ class Link {
protected:
Link();
Link(GI_ref_weak from, GI_ref_weak to);
Link(const Link &other);

public:
std::pair<GI_ref_weak, GI_ref_weak> get_connections();
virtual void set_connections(GI_ref_weak from, GI_ref_weak to);
bool is_setup();
virtual Link_ref clone() const = 0;
};

struct Edge {
Expand Down
20 changes: 18 additions & 2 deletions src/faebryk/core/cpp/include/graph/links.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class LinkDirect : public Link {
public:
LinkDirect();
LinkDirect(GI_ref_weak from, GI_ref_weak to);
LinkDirect(const LinkDirect &other);
Link_ref clone() const override;
};

class LinkParent : public Link {
Expand All @@ -20,10 +22,11 @@ class LinkParent : public Link {
public:
LinkParent();
LinkParent(GraphInterfaceHierarchical *from, GraphInterfaceHierarchical *to);

LinkParent(const LinkParent &other);
void set_connections(GI_ref_weak from, GI_ref_weak to) override;
GraphInterfaceHierarchical *get_parent();
GraphInterfaceHierarchical *get_child();
Link_ref clone() const override;
};

class LinkNamedParent : public LinkParent {
Expand All @@ -33,8 +36,9 @@ class LinkNamedParent : public LinkParent {
LinkNamedParent(std::string name);
LinkNamedParent(std::string name, GraphInterfaceHierarchical *from,
GraphInterfaceHierarchical *to);

LinkNamedParent(const LinkNamedParent &other);
std::string get_name();
Link_ref clone() const override;
};

class LinkPointer : public Link {
Expand All @@ -44,15 +48,19 @@ class LinkPointer : public Link {
public:
LinkPointer();
LinkPointer(GI_ref_weak from, GraphInterfaceSelf *to);
LinkPointer(const LinkPointer &other);
void set_connections(GI_ref_weak from, GI_ref_weak to) override;
GraphInterface *get_pointer();
GraphInterfaceSelf *get_pointee();
Link_ref clone() const override;
};

class LinkSibling : public LinkPointer {
public:
LinkSibling();
LinkSibling(GI_ref_weak from, GraphInterfaceSelf *to);
LinkSibling(const LinkSibling &other);
Link_ref clone() const override;
};

class LinkDirectConditional : public LinkDirect {
Expand Down Expand Up @@ -81,27 +89,35 @@ class LinkDirectConditional : public LinkDirect {
LinkDirectConditional(FilterF filter, bool needs_only_first_in_path);
LinkDirectConditional(FilterF filter, bool needs_only_first_in_path,
GI_ref_weak from, GI_ref_weak to);
LinkDirectConditional(const LinkDirectConditional &other);
void set_connections(GI_ref_weak from, GI_ref_weak to) override;
FilterResult run_filter(Path path);

bool needs_to_check_only_first_in_path();
Link_ref clone() const override;
};

class LinkDirectShallow : public LinkDirectConditional {
// TODO
public:
LinkDirectShallow();
LinkDirectShallow(const LinkDirectShallow &other);
Link_ref clone() const override;
};

class LinkDirectDerived : public LinkDirectConditional {
private:
static std::pair<LinkDirectConditional::FilterF, bool>
make_filter_from_path(Path path);

Path path;

public:
LinkDirectDerived(Path path);
LinkDirectDerived(Path path, std::pair<FilterF, bool> filter);
LinkDirectDerived(Path path, GI_ref_weak from, GI_ref_weak to);
LinkDirectDerived(Path path, std::pair<FilterF, bool> filter, GI_ref_weak from,
GI_ref_weak to);
LinkDirectDerived(const LinkDirectDerived &other);
Link_ref clone() const override;
};
21 changes: 17 additions & 4 deletions src/faebryk/core/cpp/src/graph/graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ void Graph::add_edge(Link_ref link) {

auto G = Graph::merge_graphs(from->G, to->G);

// remove existing link
// existing link
if (G->e_cache_simple[from].contains(to)) {
// this->remove_edge(this->e_cache[from][to]);
// TODO: reconsider this
throw std::runtime_error("link already exists");
// handle policy in the caller
throw LinkExists(G->e_cache[from][to], link, "link already exists");
}

G->e_cache_simple[from].insert(to);
Expand Down Expand Up @@ -208,3 +207,17 @@ Set<GI_ref> Graph::get_gifs() {
std::vector<std::tuple<GI_ref_weak, GI_ref_weak, Link_ref>> Graph::all_edges() {
return this->e;
}

LinkExists::LinkExists(Link_ref existing_link, Link_ref new_link, const std::string &msg)
: std::runtime_error(msg)
, existing_link(existing_link)
, new_link(new_link) {
}

Link_ref LinkExists::get_existing_link() {
return this->existing_link;
}

Link_ref LinkExists::get_new_link() {
return this->new_link;
}
6 changes: 6 additions & 0 deletions src/faebryk/core/cpp/src/graph/graphinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ void GraphInterface::connect(GI_ref_weak other, Link_ref link) {
Graph::add_edge(link);
}

void GraphInterface::connect(GI_refs_weak others, Link_ref link) {
for (auto other : others) {
this->connect(other, link->clone());
}
}

void GraphInterface::register_graph(std::shared_ptr<GraphInterface> gi) {
this->G->hold(gi);
}
Expand Down
6 changes: 6 additions & 0 deletions src/faebryk/core/cpp/src/graph/link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Link::Link(GI_ref_weak from, GI_ref_weak to)
, setup(true) {
}

Link::Link(const Link &other)
: from(nullptr)
, to(nullptr)
, setup(false) {
}

std::pair<GI_ref_weak, GI_ref_weak> Link::get_connections() {
if (!this->setup) {
throw std::runtime_error("link not setup");
Expand Down
83 changes: 81 additions & 2 deletions src/faebryk/core/cpp/src/graph/links.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ LinkDirect::LinkDirect(GI_ref_weak from, GI_ref_weak to)
: Link(from, to) {
}

LinkDirect::LinkDirect(const LinkDirect &other)
: Link(other) {
}

Link_ref LinkDirect::clone() const {
return std::make_shared<LinkDirect>(*this);
}

// LinkParent --------------------------------------------------------------------------
LinkParent::LinkParent()
: Link()
Expand All @@ -27,6 +35,12 @@ LinkParent::LinkParent(GraphInterfaceHierarchical *from, GraphInterfaceHierarchi
this->set_connections(from, to);
}

LinkParent::LinkParent(const LinkParent &other)
: Link(other)
, parent(nullptr)
, child(nullptr) {
}

void LinkParent::set_connections(GI_ref_weak from, GI_ref_weak to) {
auto from_h = dynamic_cast<GraphInterfaceHierarchical *>(from);
auto to_h = dynamic_cast<GraphInterfaceHierarchical *>(to);
Expand Down Expand Up @@ -61,6 +75,10 @@ GraphInterfaceHierarchical *LinkParent::get_child() {
return this->child;
}

Link_ref LinkParent::clone() const {
return std::make_shared<LinkParent>(*this);
}

// LinkNamedParent ---------------------------------------------------------------------
LinkNamedParent::LinkNamedParent(std::string name)
: LinkParent()
Expand All @@ -73,10 +91,19 @@ LinkNamedParent::LinkNamedParent(std::string name, GraphInterfaceHierarchical *f
, name(name) {
}

LinkNamedParent::LinkNamedParent(const LinkNamedParent &other)
: LinkParent(other)
, name(other.name) {
}

std::string LinkNamedParent::get_name() {
return this->name;
}

Link_ref LinkNamedParent::clone() const {
return std::make_shared<LinkNamedParent>(*this);
}

// LinkPointer -------------------------------------------------------------------------
LinkPointer::LinkPointer()
: Link()
Expand All @@ -91,6 +118,12 @@ LinkPointer::LinkPointer(GI_ref_weak from, GraphInterfaceSelf *to)
this->set_connections(from, to);
}

LinkPointer::LinkPointer(const LinkPointer &other)
: Link(other)
, pointee(nullptr)
, pointer(nullptr) {
}

void LinkPointer::set_connections(GI_ref_weak from, GI_ref_weak to) {
auto from_s = dynamic_cast<GraphInterfaceSelf *>(from);
auto to_s = dynamic_cast<GraphInterfaceSelf *>(to);
Expand Down Expand Up @@ -122,6 +155,10 @@ GraphInterface *LinkPointer::get_pointer() {
return this->pointer;
}

Link_ref LinkPointer::clone() const {
return std::make_shared<LinkPointer>(*this);
}

// LinkSibling ------------------------------------------------------------------------
LinkSibling::LinkSibling()
: LinkPointer() {
Expand All @@ -131,6 +168,14 @@ LinkSibling::LinkSibling(GI_ref_weak from, GraphInterfaceSelf *to)
: LinkPointer(from, to) {
}

LinkSibling::LinkSibling(const LinkSibling &other)
: LinkPointer(other) {
}

Link_ref LinkSibling::clone() const {
return std::make_shared<LinkSibling>(*this);
}

// LinkDirectConditional ----------------------------------------------------------------
LinkDirectConditional::LinkDirectConditional(FilterF filter,
bool needs_only_first_in_path)
Expand All @@ -148,6 +193,12 @@ LinkDirectConditional::LinkDirectConditional(FilterF filter,
this->set_connections(from, to);
}

LinkDirectConditional::LinkDirectConditional(const LinkDirectConditional &other)
: LinkDirect(other)
, filter(other.filter)
, needs_only_first_in_path(other.needs_only_first_in_path) {
}

void LinkDirectConditional::set_connections(GI_ref_weak from, GI_ref_weak to) {
if (this->filter(Path({from, to})) != FilterResult::FILTER_PASS) {
throw LinkFilteredException("LinkDirectConditional filtered");
Expand All @@ -163,6 +214,10 @@ bool LinkDirectConditional::needs_to_check_only_first_in_path() {
return this->needs_only_first_in_path;
}

Link_ref LinkDirectConditional::clone() const {
return std::make_shared<LinkDirectConditional>(*this);
}

// LinkDirectDerived -------------------------------------------------------------------
LinkDirectDerived::LinkDirectDerived(Path path)
: LinkDirectDerived(path, make_filter_from_path(path)) {
Expand All @@ -173,12 +228,23 @@ LinkDirectDerived::LinkDirectDerived(Path path, GI_ref_weak from, GI_ref_weak to
}

LinkDirectDerived::LinkDirectDerived(Path path, std::pair<FilterF, bool> filter)
: LinkDirectConditional(filter.first, filter.second) {
: LinkDirectConditional(filter.first, filter.second)
, path(path) {
}

LinkDirectDerived::LinkDirectDerived(Path path, std::pair<FilterF, bool> filter,
GI_ref_weak from, GI_ref_weak to)
: LinkDirectConditional(filter.first, filter.second, from, to) {
: LinkDirectConditional(filter.first, filter.second, from, to)
, path(path) {
}

LinkDirectDerived::LinkDirectDerived(const LinkDirectDerived &other)
: LinkDirectConditional(other)
, path(other.path) {
}

Link_ref LinkDirectDerived::clone() const {
return std::make_shared<LinkDirectDerived>(*this);
}

std::pair<LinkDirectConditional::FilterF, bool>
Expand Down Expand Up @@ -217,3 +283,16 @@ LinkDirectDerived::make_filter_from_path(Path path) {

return {filterf, needs_only_first_in_path};
}

// LinkDirectShallow -------------------------------------------------------------------
// LinkDirectShallow::LinkDirectShallow()
// : LinkDirectConditional() {
//}
//
// LinkDirectShallow::LinkDirectShallow(const LinkDirectShallow &other)
// : LinkDirectConditional(other) {
//}
//
// Link_ref LinkDirectShallow::clone() const {
// return std::make_shared<LinkDirectShallow>(*this);
//}
9 changes: 8 additions & 1 deletion src/faebryk/core/cpp/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ PYMOD(m) {
.def("connect", nb::overload_cast<GI_ref_weak>(&GI::connect), "other"_a)
.def("connect", nb::overload_cast<GI_refs_weak>(&GI::connect), "others"_a)
.def("connect", nb::overload_cast<GI_ref_weak, Link_ref>(&GI::connect),
"other"_a, "link"_a),
"other"_a, "link"_a)
.def("connect", nb::overload_cast<GI_refs_weak, Link_ref>(&GI::connect),
"others"_a, "link"_a),
&GraphInterface::factory<GraphInterface>);

nb::class_<Graph>(m, "Graph")
Expand All @@ -105,6 +107,11 @@ PYMOD(m) {
nb::rv_policy::reference)
.def("__repr__", &Graph::repr);

nb::exception<LinkExists>(m, "LinkExists");
nb::class_<LinkExists>(m, "LinkExists")
.def("existing_link", &LinkExists::get_existing_link, nb::rv_policy::reference)
.def("new_link", &LinkExists::get_new_link, nb::rv_policy::reference);

// Graph interfaces
FACTORY((nb::class_<GraphInterfaceSelf, GI>(m, "GraphInterfaceSelf")),
&GraphInterfaceSelf::factory<GraphInterfaceSelf>);
Expand Down
Loading

0 comments on commit a281ca5

Please sign in to comment.