From 8eed3f706599dd20f9aae38f2260f5e1e2dc684a Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Mon, 8 Apr 2024 07:39:41 +0500 Subject: [PATCH] GraphModel --- src/GraphModel/Attribute.cpp | 9 ++++ src/GraphModel/Edge.cpp | 9 ++++ src/GraphModel/Graph.cpp | 47 ++++++++++++++++++ src/GraphModel/GraphModel.hpp | 90 ++++++++++++++++++++++++++++++++++ src/GraphModel/IdGenerator.cpp | 9 ++++ src/GraphModel/Node.cpp | 9 ++++ src/RBTree.hpp | 41 ++++++++++++++++ src/format.hpp | 2 + src/gui/NodeEditor.cpp | 74 ++++++++++++---------------- src/gui/NodeEditor.hpp | 42 ++-------------- 10 files changed, 252 insertions(+), 80 deletions(-) create mode 100644 src/GraphModel/Attribute.cpp create mode 100644 src/GraphModel/Edge.cpp create mode 100644 src/GraphModel/Graph.cpp create mode 100644 src/GraphModel/GraphModel.hpp create mode 100644 src/GraphModel/IdGenerator.cpp create mode 100644 src/GraphModel/Node.cpp create mode 100644 src/RBTree.hpp diff --git a/src/GraphModel/Attribute.cpp b/src/GraphModel/Attribute.cpp new file mode 100644 index 0000000..e707fd1 --- /dev/null +++ b/src/GraphModel/Attribute.cpp @@ -0,0 +1,9 @@ +#include "GraphModel.hpp" + +namespace GraphC::GraphModel { + +Attribute::Attribute(id_t _id, Node* _parent_node, Attribute::Type _type, std::string _title) + : id(_id), parent_node(_parent_node), type(_type), title(_title) +{} + +} diff --git a/src/GraphModel/Edge.cpp b/src/GraphModel/Edge.cpp new file mode 100644 index 0000000..92cbe65 --- /dev/null +++ b/src/GraphModel/Edge.cpp @@ -0,0 +1,9 @@ +#include "GraphModel.hpp" + +namespace GraphC::GraphModel { + +Edge::Edge(id_t _id, id_t _from_attr_id, id_t _to_attr_id) + : id(_id), from_attr_id(_from_attr_id), to_attr_id(_to_attr_id) +{} + +} diff --git a/src/GraphModel/Graph.cpp b/src/GraphModel/Graph.cpp new file mode 100644 index 0000000..a0774f8 --- /dev/null +++ b/src/GraphModel/Graph.cpp @@ -0,0 +1,47 @@ +#include "GraphModel.hpp" + +namespace GraphC::GraphModel { + +Graph::Graph() +{} + +Graph::Graph(RBTree& _nodes, RBTree& _edges) + : nodes(_nodes), edges(_edges) +{} + +RBTree& Graph::getNodes(){ + return nodes; +} + +RBTree& Graph::getEdges(){ + return edges; +} + + +bool tryCreateEdge(Attribute& from, Attribute& to, Edge&& result); +bool tryGetEdge(id_t edge_id, Edge&& result); +bool tryDeleteEdge(id_t edge_id); + +void Graph::deleteNode(id_t node_id){ + if(nodes.erase(node_id) < 1) + throw UsefulException("can't erase node with id"+toString_i64(node_id)); +} + +void Graph::deleteEdge(id_t edge_id){ + +} + + +bool Graph::tryGetAttribute(id_t attr_id, Attribute*& result){ + for(auto&& p_node : nodes){ + auto&& node_attrs = p_node.second.getAttributes(); + auto&& it = node_attrs.find(attr_id); + if(it != node_attrs.end()){ + result = &it->second; + return true; + } + } + return false; +} + +} \ No newline at end of file diff --git a/src/GraphModel/GraphModel.hpp b/src/GraphModel/GraphModel.hpp new file mode 100644 index 0000000..436919f --- /dev/null +++ b/src/GraphModel/GraphModel.hpp @@ -0,0 +1,90 @@ +#pragma once + +#include "../../dependencies/kerep/src/base/base.h" +#include +#include +#include +#include "../RBTree.hpp" + +namespace GraphC::GraphModel { + +typedef i32 id_t; + +class IdGenerator { + id_t next_id=1; + +public: + id_t getNext(); +}; + +typedef struct Node Node; +typedef struct Edge Edge; + +class Attribute { + std::vector> incoming_edges; + std::vector> outgoing_edges; + +public: + enum class Type { + Input, Output, Static + }; + + const Attribute::Type type; + const id_t id; + const Node* parent_node; + std::string title; + + Attribute(id_t _id, Node* _parent_node, Attribute::Type _type, std::string _title); +}; + +class Node { + RBTree attributes; + +public: + const id_t id; + std::string title; + + Node(id_t _id, std::string _title); + + RBTree& getAttributes(); + bool tryCreateAttribute(IdGenerator id_gen, Attribute*& result); + bool tryGetAttribute(id_t attr_id, Attribute*& result); + bool tryDeleteAttribute(id_t attr_id); +}; + +struct Edge { + const id_t id; + const id_t to_attr_id; + const id_t from_attr_id; + + Edge(id_t _id, id_t _from_attr_id, id_t _to_attr_id); +}; + +class Graph { + friend class Attribute; + friend class Node; + friend class Edge; + + RBTree nodes; + RBTree edges; + +public: + IdGenerator id_gen; + + Graph(); + Graph(RBTree& _nodes, RBTree& _edges); + + RBTree& getNodes(); + bool tryCreateNode(std::string _title, Node*& result); + bool tryGetNode(id_t node_id, Node*& result); + bool tryDeleteNode(id_t node_id); + + RBTree& getEdges(); + bool tryCreateEdge(Attribute& from, Attribute& to, Edge*& result); + bool tryGetEdge(id_t edge_id, Edge*& result); + bool tryDeleteEdge(id_t edge_id); + + bool tryGetAttribute(id_t attr_id, Attribute*& result); +}; + +} \ No newline at end of file diff --git a/src/GraphModel/IdGenerator.cpp b/src/GraphModel/IdGenerator.cpp new file mode 100644 index 0000000..743fb5a --- /dev/null +++ b/src/GraphModel/IdGenerator.cpp @@ -0,0 +1,9 @@ +#include "GraphModel.hpp" + +namespace GraphC::GraphModel { + +id_t IdGenerator::getNext(){ + return next_id++; +} + +} diff --git a/src/GraphModel/Node.cpp b/src/GraphModel/Node.cpp new file mode 100644 index 0000000..cc497b9 --- /dev/null +++ b/src/GraphModel/Node.cpp @@ -0,0 +1,9 @@ +#include "GraphModel.hpp" + +namespace GraphC::GraphModel { + +Node::Node(id_t _id, std::string _title) + : id(_id), title(_title) +{} + +} diff --git a/src/RBTree.hpp b/src/RBTree.hpp new file mode 100644 index 0000000..14b668f --- /dev/null +++ b/src/RBTree.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "../../dependencies/kerep/src/base/base.h" +#include +#include + +template +class RBTree { + enum class Color { + Red, Black; + }; + + struct Node { + TKey key; + TVal value; + Color color; + }; + +public: + RBTree() {} + + bool tryAdd(TKey key, TVal& value, TVal*& result){ + + } + + bool trySet(TKey key, TVal& value){ + + } + + void addOrSet(TKey key, TVal& value){ + + } + + bool tryGet(TKey key, TVal*& result){ + + } + + bool tryDelete(TKey key){ + + } +}; diff --git a/src/format.hpp b/src/format.hpp index c6aa1b2..5432382 100644 --- a/src/format.hpp +++ b/src/format.hpp @@ -1,3 +1,5 @@ +#pragma once + #include std::string format(const std::string format_str, size_t args_count, ...); diff --git a/src/gui/NodeEditor.cpp b/src/gui/NodeEditor.cpp index e544f65..fa0bb5c 100644 --- a/src/gui/NodeEditor.cpp +++ b/src/gui/NodeEditor.cpp @@ -4,37 +4,28 @@ namespace GraphC::gui { -NodeAttribute::NodeAttribute(id_t _id, NodeAttributeType _type, std::string _title) - : id(_id), type(_type), title(_title) {} - -NodeAttributeLink::NodeAttributeLink(id_t _id, id_t _in, id_t _out) - : id(_id), in_attr_id(_in), out_attr_id(_out) {} - -Node::Node(id_t _id, std::string _title) - : id(_id), title(_title) {} - -void Node::draw(){ - ImNodes::BeginNode(id); +void drawNode(GraphModel::Node& node){ + ImNodes::BeginNode(node.id); ImNodes::BeginNodeTitleBar(); - ImGui::TextUnformatted(title.c_str()); + ImGui::TextUnformatted(node.title.c_str()); ImNodes::EndNodeTitleBar(); - for(NodeAttribute& a : attributes) + for(GraphModel::Attribute& a : node.attributes) { switch (a.type) { - case NodeAttributeType::Input: + case GraphModel::Attribute::Type::Input: ImNodes::BeginInputAttribute(a.id); ImGui::Text("%s", a.title.c_str()); ImNodes::EndInputAttribute(); break; - case NodeAttributeType::Output: + case GraphModel::Attribute::Type::Output: ImNodes::BeginOutputAttribute(a.id); ImGui::Text("%s", a.title.c_str()); ImGui::Indent(40); ImNodes::EndOutputAttribute(); break; - case NodeAttributeType::Static: + case GraphModel::Attribute::Type::Static: ImNodes::BeginStaticAttribute(a.id); ImGui::Text("%s", a.title.c_str()); ImNodes::EndStaticAttribute(); @@ -48,17 +39,15 @@ void Node::draw(){ } -Node CreateExampleNode(id_t* next_id, std::string title){ - Node a = Node((*next_id)++, title); - a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Input, "In")); - a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Output, "Out")); - a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Static, "Static")); +GraphModel::Node CreateExampleNode(GraphModel::id_t* next_id, std::string title){ + GraphModel::Node a = GraphModel::Node((*next_id)++, title); + a.attributes.push_back(GraphModel::Attribute((*next_id)++, &a, GraphModel::Attribute::Type::Input, "In")); + a.attributes.push_back(GraphModel::Attribute((*next_id)++, &a, GraphModel::Attribute::Type::Output, "Out")); + a.attributes.push_back(GraphModel::Attribute((*next_id)++, &a, GraphModel::Attribute::Type::Static, "Static")); return a; } NodeEditor::NodeEditor(std::string _title) : title(_title) { - nodes.push_back(CreateExampleNode(&next_id, "node A")); - nodes.push_back(CreateExampleNode(&next_id, "node B")); } void NodeEditor::show(){ @@ -78,34 +67,35 @@ void NodeEditor::draw(){ ImGui::SetWindowSizeMin(300,300); ImNodes::BeginNodeEditor(); // draw nodes - for(Node& n : nodes){ - n.draw(); + for(auto&& p : graph->getNodes()){ + drawNode(p.second); } - // draw links - for(const NodeAttributeLink& l : links){ - ImNodes::Link(l.id, l.in_attr_id, l.out_attr_id); + // draw edges + const auto& edges = graph->getEdges(); + edges.empl = GraphModel::Edge(); + for(auto&& p : edges){ + ImNodes::Link(p.second.id, p.second.to_attr_id, p.second.from_attr_id); } ImNodes::EndNodeEditor(); - // handle link creation - id_t in_attr_id; - id_t out_attr_id; - if (ImNodes::IsLinkCreated(&in_attr_id, &out_attr_id)) + // handle edge creation + GraphModel::id_t to_attr_id; + GraphModel::id_t from_attr_id; + if (ImNodes::IsLinkCreated(&from_attr_id, &to_attr_id)) { - NodeAttributeLink link(next_id++, in_attr_id, out_attr_id); - links.push_back(link); + graph->createEdge(graph->getEdge(from_attr_id), graph->getEdge(to_attr_id)); } - // handle link destruction - id_t link_id; - if (ImNodes::IsLinkDestroyed(&link_id)) + // handle edge destruction + GraphModel::id_t edge_id; + if (ImNodes::IsLinkDestroyed(&edge_id)) { - auto iter = std::find_if(links.begin(), links.end(), - [link_id](const NodeAttributeLink& link) -> bool { - return link.id == link_id; + auto iter = std::find_if(edges.begin(), edges.end(), + [edge_id](const GraphModel::Edge& edge) -> bool { + return edge.id == edge_id; }); - assert(iter != links.end()); - links.erase(iter); + assert(iter != edges.end()); + edges.erase(iter); } ImGui::End(); diff --git a/src/gui/NodeEditor.hpp b/src/gui/NodeEditor.hpp index e75ca10..d6842c1 100644 --- a/src/gui/NodeEditor.hpp +++ b/src/gui/NodeEditor.hpp @@ -1,51 +1,17 @@ #pragma once #include "../../dependencies/imnodes/imnodes.h" -#include -#include +#include "../GraphModel/GraphModel.hpp" +#include namespace GraphC::gui { -typedef i32 id_t; - -enum class NodeAttributeType { - Input, Output, Static -}; - -struct NodeAttribute { - id_t id; - NodeAttributeType type; - std::string title; - - NodeAttribute(id_t _id, NodeAttributeType _type, std::string _title); -}; - -struct Node { - id_t id; - std::string title; - std::vector attributes; - - Node(id_t _id, std::string _title); - - void draw(); -}; - -struct NodeAttributeLink { - id_t id; - id_t in_attr_id; - id_t out_attr_id; - - NodeAttributeLink(id_t _id, id_t _in, id_t _out); -}; - class NodeEditor { std::string title=nullptr; bool editor_open=false; ImNodesContext* editor_context=nullptr; - id_t next_id=1; - std::vector nodes; - std::vector links; - + std::shared_ptr graph; + public: NodeEditor(std::string _title);