GraphModel
This commit is contained in:
parent
58b62eb3a8
commit
8eed3f7065
9
src/GraphModel/Attribute.cpp
Normal file
9
src/GraphModel/Attribute.cpp
Normal 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
9
src/GraphModel/Edge.cpp
Normal 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
47
src/GraphModel/Graph.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
90
src/GraphModel/GraphModel.hpp
Normal file
90
src/GraphModel/GraphModel.hpp
Normal 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);
|
||||
};
|
||||
|
||||
}
|
||||
9
src/GraphModel/IdGenerator.cpp
Normal file
9
src/GraphModel/IdGenerator.cpp
Normal 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
9
src/GraphModel/Node.cpp
Normal 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
41
src/RBTree.hpp
Normal 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){
|
||||
|
||||
}
|
||||
};
|
||||
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string format(const std::string format_str, size_t args_count, ...);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -1,50 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../dependencies/imnodes/imnodes.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "../GraphModel/GraphModel.hpp"
|
||||
#include <memory>
|
||||
|
||||
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 {
|
||||
std::string title=nullptr;
|
||||
bool editor_open=false;
|
||||
ImNodesContext* editor_context=nullptr;
|
||||
id_t next_id=1;
|
||||
std::vector<Node> nodes;
|
||||
std::vector<NodeAttributeLink> links;
|
||||
std::shared_ptr<GraphModel::Graph> graph;
|
||||
|
||||
public:
|
||||
NodeEditor(std::string _title);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user