heavy restructuring with smart pointers, not finished

This commit is contained in:
Sebastian
2024-10-31 01:43:00 +01:00
14 changed files with 3317 additions and 390 deletions
+107 -67
View File
@@ -1,11 +1,16 @@
#pragma once
#include "datatypes.h"
#include "graph-item.h"
#include "node.h"
#include "connection.h"
#include "edge.h"
#include <algorithm>
#include <iterator>
#include <map>
#include <memory>
#include <random>
#include <ranges>
#include <vector>
class GraphManager{
@@ -13,89 +18,72 @@ class GraphManager{
GraphManager() {}
std::map<int, Node> nodes;
std::vector<Connection> connections;
std::vector<std::shared_ptr<Node>> nodes;
std::vector<std::shared_ptr<Edge>> edges;
std::map<std::shared_ptr<Node>, int> counter;
std::shared_ptr<Node> getRandomNode(){
std::vector<std::shared_ptr<GraphItem>> o;
std::ranges::sample(nodes, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return std::dynamic_pointer_cast<Node>(o.front());
}
std::vector<int> keys;
int iterator = 0;
std::map<int, int> counter;
int getRandomNode(){
std::vector<int> o;
std::ranges::sample(keys, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return o.front();
std::shared_ptr<Edge> getRandomEdge(){
std::vector<std::shared_ptr<GraphItem>> o;
std::ranges::sample(edges, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return std::dynamic_pointer_cast<Edge>(o.front());
}
void copyNodes(Vec2D<float> position){
for(auto n: nodes | std::ranges::views::filter([](std::pair<int, Node> n){ return n.second.copied;})){
n.second.position = position + n.second.drag_offset;
n.second.id = iterator;
n.second.copied = false;
n.second.selected = true;
nodes.insert(std::make_pair(iterator, n.second));
keys.push_back(iterator);
iterator++;
void copyNodes(std::vector<std::shared_ptr<Node>> nodes, Vec2D<float> position){
for(auto n: nodes){
auto nc = std::make_shared<Node>(n);
nc->position = position + nc->drag_offset;
nc->selected = true;
nodes.push_back(nc);
}
}
int copyNode(int id, Vec2D<float> position){
Node n = nodes.at(id);
n.position = position;
n.id = iterator;
nodes.insert(std::make_pair(iterator, n));
keys.push_back(iterator);
iterator++;
return iterator - 1;
void copyNode(std::shared_ptr<Node> n, Vec2D<float> position){
auto nc = std::make_shared<Node>(n);
nc->setPosition(position);
nodes.push_back(nc);
}
void setNodeMode(int mode){
for(auto &n : nodes | std::ranges::views::values){
n.mode = mode;
}
}
int addNode(float x, float y){
std::shared_ptr<Node> addNode(float x, float y){
return addNode(Vec2D<float>(x,y));
}
int addNode(Vec2D<float> position){
nodes.emplace(std::make_pair(iterator, Node(iterator, position, 15.0f)));
keys.push_back(iterator);
iterator++;
return iterator - 1;
std::shared_ptr<Node> addNode(Vec2D<float> position){
nodes.emplace_back(std::make_shared<Node>(position));
return nodes.back();
}
void triggerNode(int node){
nodes.at(node).trigger();
void setNodeMode(int mode){
for(auto n: nodes){
n->setMode(mode);
}
}
void reset(){
counter.clear();
}
int next(int current, int last){
std::vector<Connection*> possible_connections;
std::vector<int> next_node_ids;
std::shared_ptr<Node> next(std::shared_ptr<Node> current, std::shared_ptr<Node> last){
std::vector<std::shared_ptr<Edge>> possible_connections = current->connections | std::ranges::views::filter([current](std::shared_ptr<Edge> c){
return (c->start == current && c->pass_forward) || (c->end == current && c->pass_backward);
}) | std::ranges::to<std::vector<std::shared_ptr<Edge>>>();
for(auto& c : connections){
if((c.v1 == current && c.v1_v2) || (c.v2 == current && c.v2_v1)) {
c.active = false;
possible_connections.push_back(&c);
next_node_ids.push_back( c.v1 == current ? c.v2 : c.v1 );
}
}
if(possible_connections.empty()) return -1;
if(possible_connections.empty()) return std::shared_ptr<Node>(nullptr);
int return_path = 0;
float angle = -1;
if(nodes.at(current).distributionMode == Distribution::GEOMETRIC){
Vec2D<float> coming_from = (nodes.at(current).position - nodes.at(last).position).norm();
if(current->distributionMode == Distribution::GEOMETRIC){
Vec2D<float> coming_from = (current->position - last->position).norm();
int i = 0;
for(auto n : possible_connections){
int next_position = n->v1 == current ? n->v2 : n->v1;
float angle_v1_v2 = coming_from.norm().dot((nodes.at(next_position).position - nodes.at(current).position).norm());
std::shared_ptr<Node> next_node = n->getNextNode(current);
float angle_v1_v2 = coming_from.norm().dot((next_node->position - current->position).norm());
if(angle_v1_v2 > angle) {
return_path = i;
angle = angle_v1_v2;
@@ -104,7 +92,7 @@ class GraphManager{
}
}
if(nodes.at(current).distributionMode == Distribution::ROUNDROBIN){
if(current->distributionMode == Distribution::ROUNDROBIN){
if(counter.find(current) == counter.end()) {
counter[current] = 0;
} else {
@@ -113,24 +101,76 @@ class GraphManager{
}
}
if(nodes.at(current).distributionMode == Distribution::RANDOM){
if(current->distributionMode == Distribution::RANDOM){
return_path = rand() % possible_connections.size();
}
possible_connections.at(return_path)->active = true;
return possible_connections.at(return_path)->v1 == current ? possible_connections.at(return_path)->v2 : possible_connections.at(return_path)->v1;
return possible_connections.at(return_path)->getNextNode(current);
}
void addConnection(int from, int to){
connections.emplace_back(&nodes, from, to);
void addConnection(std::shared_ptr<Node> from, std::shared_ptr<Node> to){
edges.emplace_back(std::make_shared<Edge>(from, to));
}
void drawConnections(Vec2D<float> *mouse_pos, Camera2D *cam){
std::erase_if(connections, [](Connection c){ return c.remove == true;});
for(auto& c : connections){
c.draw(mouse_pos, cam);
// std::erase_if(connections, [](Connection c){ return c.remove == true;});
for(auto& c : edges){
Vec2D<float> v1_position = c->start->position - ((c->start->position - c->end->position)).norm() * (c->start->radius + c->connector_offset);
Vec2D<float> v2_position = c->end->position - ((c->end->position - c->start->position)).norm() * (c->end->radius + c->connector_offset);
float v1_v2_distance = v1_position.dist(&v2_position);
float midi_gate_v1 = Clamp((4.f / 1000.f) * c->start->midi_gate, 1.f, 4.f);
float midi_gate_v2 = Clamp((4.f / 1000.f) * c->end->midi_gate, 1.f, 4.f);
// Line with small connector circles
Color col = {229, 181, 103, 255};
if(c.active) col = {108, 153, 187, 255};
DrawLine(v1_position.x, v1_position.y, v2_position.x, v2_position.y, col);
if(midi_gate_v1 == 4.0f) col = VS_COLOR_RED;
DrawCircle(v1_position.x, v1_position.y, midi_gate_v1, col);
col = {229, 181, 103, 255};
if(midi_gate_v2 == 4.0f) col = VS_COLOR_RED;
DrawCircle(v2_position.x, v2_position.y, midi_gate_v2, col);
if(v1_v2_distance < 100) c.switches_offset = v1_v2_distance/2.3f;
Vec2D<float> from_to_handle = c->start->position - ((c->start->position - c->end->position)).norm() * (c->start->radius + c.switches_offset);
Vec2D<float> to_from_handle = c->end->position - ((c->end->position - c->start->position)).norm() * (c->end->radius + c.switches_offset);
Vec2D<float> middle_handle = c->end->position - ((c->end->position - c->start->position))*0.4f;
Vec2D<float> middle_handle_2 = c->end->position - ((c->end->position - c->start->position))*0.6f;
Vec2D<float> flip_handle = middle_handle + (v1_position - v2_position).norm().orth() * (v1_v2_distance < 120.0f ? Clamp((120.0f - v1_v2_distance)*0.2, 0.f, 20.f) : 1.0f);
Vec2D<float> flip_handle_2 = middle_handle_2 + (v1_position - v2_position).norm().orth() * (v1_v2_distance < 120.0f ? Clamp((120.0f - v1_v2_distance)*-0.2, -20.f, 0.f) : 1.0f);
// Dynamic opacity by distance to mouse
unsigned char opacity = 150.0f - Clamp(middle_handle.dist(mouse_pos), 0.0f, 150.0f);
unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f);
unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f);
// On/Off switches on both sides
if(ViButton(mouse_pos, from_to_handle.x, from_to_handle.y, 8.0f, c->start_end ? (Color){120, 210, 115, opacity_from} : (Color){232, 50, 32, opacity_from} )) c->start_end = !c->start_end;
if(ViButton(mouse_pos, to_from_handle.x, to_from_handle.y, 8.0f, c.end_start ? (Color){120, 210, 115, opacity_to} : (Color){232, 50, 32, opacity_to} )) c.end_start = !c.end_start;
if(!c->start_end){
Vec2D<float> block_point1 = (v1_position - v2_position).norm().orth()*4.0f + from_to_handle;
Vec2D<float> block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + from_to_handle;
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_from});
}
if(!c.end_start){
Vec2D<float> block_point1 = (v1_position - v2_position).norm().orth()*4.0f + to_from_handle;
Vec2D<float> block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + to_from_handle;
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_to});
}
if(ViButton(mouse_pos, flip_handle.x, flip_handle.y, 8.0f, (Color){232, 50, 32, opacity} )) c.remove = true;
if(ViButton(mouse_pos, flip_handle_2.x, flip_handle_2.y, 8.0f, (Color){232, 50, 32, opacity} )) c.split = true;
}
}
void drawNodes(Vec2D<float> *mouse_pos, Camera2D *camera){
auto neighbors = nodes | std::ranges::views::values | std::ranges::views::filter([](Node n){ return !n.dragging && !n.selected;}) | std::ranges::to<std::vector<Node>>();
float min_d = 480;