GraphModel

This commit is contained in:
Timerix22 2024-04-08 07:39:41 +05:00
parent 58b62eb3a8
commit 8eed3f7065
10 changed files with 252 additions and 80 deletions

View File

@ -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)
{}
}

9
src/GraphModel/Edge.cpp Normal file
View File

@ -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)
{}
}

47
src/GraphModel/Graph.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "GraphModel.hpp"
namespace GraphC::GraphModel {
Graph::Graph()
{}
Graph::Graph(RBTree<id_t, Node>& _nodes, RBTree<id_t, Edge>& _edges)
: nodes(_nodes), edges(_edges)
{}
RBTree<id_t, Node>& Graph::getNodes(){
return nodes;
}
RBTree<id_t, Edge>& 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;
}
}

View File

@ -0,0 +1,90 @@
#pragma once
#include "../../dependencies/kerep/src/base/base.h"
#include <string>
#include <memory>
#include <vector>
#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<std::shared_ptr<Edge>> incoming_edges;
std::vector<std::shared_ptr<Edge>> 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<id_t, Attribute> attributes;
public:
const id_t id;
std::string title;
Node(id_t _id, std::string _title);
RBTree<id_t, Attribute>& 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<id_t, Node> nodes;
RBTree<id_t, Edge> edges;
public:
IdGenerator id_gen;
Graph();
Graph(RBTree<id_t, Node>& _nodes, RBTree<id_t, Edge>& _edges);
RBTree<id_t, Node>& getNodes();
bool tryCreateNode(std::string _title, Node*& result);
bool tryGetNode(id_t node_id, Node*& result);
bool tryDeleteNode(id_t node_id);
RBTree<id_t, Edge>& 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);
};
}

View File

@ -0,0 +1,9 @@
#include "GraphModel.hpp"
namespace GraphC::GraphModel {
id_t IdGenerator::getNext(){
return next_id++;
}
}

9
src/GraphModel/Node.cpp Normal file
View File

@ -0,0 +1,9 @@
#include "GraphModel.hpp"
namespace GraphC::GraphModel {
Node::Node(id_t _id, std::string _title)
: id(_id), title(_title)
{}
}

41
src/RBTree.hpp Normal file
View File

@ -0,0 +1,41 @@
#pragma once
#include "../../dependencies/kerep/src/base/base.h"
#include <map>
#include <memory>
template<typename TKey, typename TVal>
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){
}
};

View File

@ -1,3 +1,5 @@
#pragma once
#include <string> #include <string>
std::string format(const std::string format_str, size_t args_count, ...); std::string format(const std::string format_str, size_t args_count, ...);

View File

@ -4,37 +4,28 @@
namespace GraphC::gui { namespace GraphC::gui {
NodeAttribute::NodeAttribute(id_t _id, NodeAttributeType _type, std::string _title) void drawNode(GraphModel::Node& node){
: id(_id), type(_type), title(_title) {} ImNodes::BeginNode(node.id);
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);
ImNodes::BeginNodeTitleBar(); ImNodes::BeginNodeTitleBar();
ImGui::TextUnformatted(title.c_str()); ImGui::TextUnformatted(node.title.c_str());
ImNodes::EndNodeTitleBar(); ImNodes::EndNodeTitleBar();
for(NodeAttribute& a : attributes) for(GraphModel::Attribute& a : node.attributes)
{ {
switch (a.type) switch (a.type)
{ {
case NodeAttributeType::Input: case GraphModel::Attribute::Type::Input:
ImNodes::BeginInputAttribute(a.id); ImNodes::BeginInputAttribute(a.id);
ImGui::Text("%s", a.title.c_str()); ImGui::Text("%s", a.title.c_str());
ImNodes::EndInputAttribute(); ImNodes::EndInputAttribute();
break; break;
case NodeAttributeType::Output: case GraphModel::Attribute::Type::Output:
ImNodes::BeginOutputAttribute(a.id); ImNodes::BeginOutputAttribute(a.id);
ImGui::Text("%s", a.title.c_str()); ImGui::Text("%s", a.title.c_str());
ImGui::Indent(40); ImGui::Indent(40);
ImNodes::EndOutputAttribute(); ImNodes::EndOutputAttribute();
break; break;
case NodeAttributeType::Static: case GraphModel::Attribute::Type::Static:
ImNodes::BeginStaticAttribute(a.id); ImNodes::BeginStaticAttribute(a.id);
ImGui::Text("%s", a.title.c_str()); ImGui::Text("%s", a.title.c_str());
ImNodes::EndStaticAttribute(); ImNodes::EndStaticAttribute();
@ -48,17 +39,15 @@ void Node::draw(){
} }
Node CreateExampleNode(id_t* next_id, std::string title){ GraphModel::Node CreateExampleNode(GraphModel::id_t* next_id, std::string title){
Node a = Node((*next_id)++, title); GraphModel::Node a = GraphModel::Node((*next_id)++, title);
a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Input, "In")); a.attributes.push_back(GraphModel::Attribute((*next_id)++, &a, GraphModel::Attribute::Type::Input, "In"));
a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Output, "Out")); a.attributes.push_back(GraphModel::Attribute((*next_id)++, &a, GraphModel::Attribute::Type::Output, "Out"));
a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Static, "Static")); a.attributes.push_back(GraphModel::Attribute((*next_id)++, &a, GraphModel::Attribute::Type::Static, "Static"));
return a; return a;
} }
NodeEditor::NodeEditor(std::string _title) : title(_title) { 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(){ void NodeEditor::show(){
@ -78,34 +67,35 @@ void NodeEditor::draw(){
ImGui::SetWindowSizeMin(300,300); ImGui::SetWindowSizeMin(300,300);
ImNodes::BeginNodeEditor(); ImNodes::BeginNodeEditor();
// draw nodes // draw nodes
for(Node& n : nodes){ for(auto&& p : graph->getNodes()){
n.draw(); drawNode(p.second);
} }
// draw links // draw edges
for(const NodeAttributeLink& l : links){ const auto& edges = graph->getEdges();
ImNodes::Link(l.id, l.in_attr_id, l.out_attr_id); 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(); ImNodes::EndNodeEditor();
// handle link creation // handle edge creation
id_t in_attr_id; GraphModel::id_t to_attr_id;
id_t out_attr_id; GraphModel::id_t from_attr_id;
if (ImNodes::IsLinkCreated(&in_attr_id, &out_attr_id)) if (ImNodes::IsLinkCreated(&from_attr_id, &to_attr_id))
{ {
NodeAttributeLink link(next_id++, in_attr_id, out_attr_id); graph->createEdge(graph->getEdge(from_attr_id), graph->getEdge(to_attr_id));
links.push_back(link);
} }
// handle link destruction // handle edge destruction
id_t link_id; GraphModel::id_t edge_id;
if (ImNodes::IsLinkDestroyed(&link_id)) if (ImNodes::IsLinkDestroyed(&edge_id))
{ {
auto iter = std::find_if(links.begin(), links.end(), auto iter = std::find_if(edges.begin(), edges.end(),
[link_id](const NodeAttributeLink& link) -> bool { [edge_id](const GraphModel::Edge& edge) -> bool {
return link.id == link_id; return edge.id == edge_id;
}); });
assert(iter != links.end()); assert(iter != edges.end());
links.erase(iter); edges.erase(iter);
} }
ImGui::End(); ImGui::End();

View File

@ -1,51 +1,17 @@
#pragma once #pragma once
#include "../../dependencies/imnodes/imnodes.h" #include "../../dependencies/imnodes/imnodes.h"
#include <vector> #include "../GraphModel/GraphModel.hpp"
#include <string> #include <memory>
namespace GraphC::gui { 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<NodeAttribute> 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 { class NodeEditor {
std::string title=nullptr; std::string title=nullptr;
bool editor_open=false; bool editor_open=false;
ImNodesContext* editor_context=nullptr; ImNodesContext* editor_context=nullptr;
id_t next_id=1; std::shared_ptr<GraphModel::Graph> graph;
std::vector<Node> nodes;
std::vector<NodeAttributeLink> links;
public: public:
NodeEditor(std::string _title); NodeEditor(std::string _title);