2024-10-25 16:41:37 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
2024-10-31 01:43:00 +01:00
|
|
|
#include "edge.h"
|
2024-10-25 16:41:37 +02:00
|
|
|
#include "datatypes.h"
|
2024-10-30 14:55:24 +01:00
|
|
|
#include "graph-manager.h"
|
2024-11-01 02:38:47 +01:00
|
|
|
#include "midi-node.h"
|
2024-10-25 16:41:37 +02:00
|
|
|
#include "signal-manager.h"
|
|
|
|
|
#include "ui.h"
|
2024-10-27 00:40:57 +02:00
|
|
|
|
2024-10-26 02:14:41 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
#include <iterator>
|
2024-11-01 02:38:47 +01:00
|
|
|
#include <memory>
|
2024-10-26 02:14:41 +02:00
|
|
|
#include <ranges>
|
|
|
|
|
#include <vector>
|
2024-10-25 16:41:37 +02:00
|
|
|
|
|
|
|
|
class AppState{
|
|
|
|
|
public:
|
|
|
|
|
|
2024-10-30 14:55:24 +01:00
|
|
|
AppState() : sm(&gm, &mutex), ui(&settings, &sm, &gm) {}
|
2024-10-25 16:41:37 +02:00
|
|
|
|
|
|
|
|
enum States {IDLE, CONFIG};
|
|
|
|
|
|
|
|
|
|
AppSettings settings;
|
|
|
|
|
|
|
|
|
|
States state;
|
|
|
|
|
|
|
|
|
|
std::mutex mutex;
|
|
|
|
|
|
2024-10-30 14:55:24 +01:00
|
|
|
GraphManager gm;
|
2024-10-25 16:41:37 +02:00
|
|
|
SignalManager sm;
|
|
|
|
|
|
|
|
|
|
AppUI ui;
|
|
|
|
|
|
|
|
|
|
void updateMidiPorts(){
|
2024-11-01 14:08:27 +01:00
|
|
|
for(auto&n : gm.nodes | RANGE_FILTER([](SPTR_Node n){return n->getNodeType() == NodeType::MIDINODE;})){
|
2024-11-01 02:38:47 +01:00
|
|
|
auto nc = std::dynamic_pointer_cast<MidiNode>(n);
|
2024-10-25 16:41:37 +02:00
|
|
|
for(auto& mo : sm.midi.midi_out_ports){
|
2024-11-01 02:38:47 +01:00
|
|
|
if(!nc->midi_outs.contains(mo.number) && mo.enabled){
|
|
|
|
|
nc->midi_outs[mo.number] = {mo.number, mo.port.port_name, false};
|
2024-10-25 16:41:37 +02:00
|
|
|
}
|
2024-11-01 02:38:47 +01:00
|
|
|
if(nc->midi_outs.contains(mo.number) && !mo.enabled){
|
|
|
|
|
nc->midi_outs.erase(mo.number);
|
2024-10-25 16:41:37 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-01 14:08:27 +01:00
|
|
|
void copyNodesAndConnections(VEC_SPTR_Node nodes, Vec2D<float> position){
|
2024-10-26 16:31:23 +02:00
|
|
|
|
2024-11-01 14:08:27 +01:00
|
|
|
VEC_SPTR_Edge copy_connections;
|
2024-11-01 02:38:47 +01:00
|
|
|
for(auto n : nodes){
|
2024-11-02 02:06:26 +01:00
|
|
|
for(auto c : n->connections){
|
|
|
|
|
if(std::ranges::contains(nodes, c->start) && std::ranges::contains(nodes, c->end)) {
|
|
|
|
|
copy_connections.push_back(std::make_shared<Edge>(*c));
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-11-01 02:38:47 +01:00
|
|
|
}
|
2024-11-02 02:06:26 +01:00
|
|
|
std::cout << copy_connections.size() << std::endl;
|
|
|
|
|
|
|
|
|
|
for(auto old_node : nodes){
|
|
|
|
|
SPTR_Node new_node;
|
|
|
|
|
|
|
|
|
|
if(old_node->getNodeType() == NodeType::MIDINODE) {
|
|
|
|
|
new_node = gm.copyNode(std::dynamic_pointer_cast<MidiNode>(old_node), position + old_node->drag_offset);
|
|
|
|
|
} else {
|
|
|
|
|
new_node = gm.copyNode(old_node, position + old_node->drag_offset);
|
|
|
|
|
}
|
2024-10-26 16:31:23 +02:00
|
|
|
|
2024-11-01 02:38:47 +01:00
|
|
|
new_node->copied = false;
|
2024-11-01 14:46:51 +01:00
|
|
|
new_node->selected = false;
|
2024-10-28 02:07:47 +01:00
|
|
|
|
2024-11-01 14:46:51 +01:00
|
|
|
for(auto c : copy_connections){
|
2024-11-02 02:06:26 +01:00
|
|
|
if(c->start == old_node) {
|
|
|
|
|
c->start = new_node;
|
|
|
|
|
c->start->connections.push_back(c);
|
|
|
|
|
}
|
|
|
|
|
if(c->end == old_node) {
|
|
|
|
|
c->end = new_node;
|
|
|
|
|
c->end->connections.push_back(c);
|
|
|
|
|
}
|
2024-10-26 16:31:23 +02:00
|
|
|
}
|
|
|
|
|
}
|
2024-11-02 02:06:26 +01:00
|
|
|
std::ranges::copy(copy_connections.begin(), copy_connections.end(), std::back_inserter(gm.edges));
|
2024-10-26 16:31:23 +02:00
|
|
|
}
|
|
|
|
|
|
2024-11-01 14:08:27 +01:00
|
|
|
void removeNodes(VEC_SPTR_Node nodes){
|
2024-10-26 02:14:41 +02:00
|
|
|
|
2024-11-01 02:38:47 +01:00
|
|
|
for(auto n : gm.nodes){
|
|
|
|
|
n->highlighted = false;
|
2024-10-26 02:14:41 +02:00
|
|
|
}
|
|
|
|
|
|
2024-11-01 14:08:27 +01:00
|
|
|
auto erase_connections = gm.edges | RANGE_FILTER([nodes](SPTR_Edge c){ return std::ranges::contains(nodes, c->start) || std::ranges::contains(nodes, c->end);});
|
2024-10-26 02:14:41 +02:00
|
|
|
|
2024-11-01 14:08:27 +01:00
|
|
|
VEC_SPTR_Node adjacent_nodes;
|
2024-10-26 02:14:41 +02:00
|
|
|
|
2024-11-01 02:38:47 +01:00
|
|
|
for(auto c : erase_connections){
|
|
|
|
|
if(!c->start->selected) adjacent_nodes.push_back(c->start);
|
|
|
|
|
if(!c->end->selected) adjacent_nodes.push_back(c->end);
|
2024-10-26 02:14:41 +02:00
|
|
|
}
|
|
|
|
|
|
2024-11-01 14:08:27 +01:00
|
|
|
auto reroute_signals = sm.signals | RANGE_FILTER([nodes](SPTR_Signal s){return std::ranges::contains(nodes, s->next);});
|
2024-10-26 02:14:41 +02:00
|
|
|
|
2024-11-01 02:38:47 +01:00
|
|
|
for(auto s : reroute_signals){
|
2024-10-26 02:14:41 +02:00
|
|
|
float dist = 10000000;
|
2024-11-01 14:08:27 +01:00
|
|
|
SPTR_Node next_node;
|
2024-11-01 02:38:47 +01:00
|
|
|
for(auto n : adjacent_nodes){
|
|
|
|
|
if(n->position.dist(s->position) < dist) {
|
|
|
|
|
dist = n->position.dist(s->position);
|
|
|
|
|
next_node = n;
|
2024-10-26 02:14:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
2024-11-01 02:38:47 +01:00
|
|
|
s->next = next_node;
|
|
|
|
|
s->last = next_node;
|
2024-10-26 02:14:41 +02:00
|
|
|
}
|
|
|
|
|
|
2024-11-01 14:08:27 +01:00
|
|
|
auto rebase_signals = sm.signals | RANGE_FILTER([nodes](SPTR_Signal s){return std::ranges::contains(nodes, s->start);});
|
2024-10-26 02:14:41 +02:00
|
|
|
|
2024-11-01 02:38:47 +01:00
|
|
|
for(auto s : rebase_signals){
|
|
|
|
|
s->start = s->next;
|
2024-10-26 02:14:41 +02:00
|
|
|
}
|
|
|
|
|
|
2024-11-02 02:06:26 +01:00
|
|
|
for(auto n : adjacent_nodes){
|
|
|
|
|
std::erase_if(n->connections, [n, nodes](SPTR_Edge c){ return std::ranges::contains(nodes, c->start) || std::ranges::contains(nodes, c->end);});
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-01 02:38:47 +01:00
|
|
|
for(auto n : nodes){
|
2024-11-01 14:08:27 +01:00
|
|
|
std::erase_if(gm.edges, [n](SPTR_Edge c){ return c->start == n || c->end == n;});
|
2024-10-26 02:14:41 +02:00
|
|
|
}
|
2024-11-01 14:08:27 +01:00
|
|
|
std::erase_if(gm.nodes, [nodes](SPTR_Node n){ return std::ranges::contains(nodes, n);});
|
2024-10-26 02:14:41 +02:00
|
|
|
}
|
|
|
|
|
|
2024-11-01 02:38:47 +01:00
|
|
|
void draw(Vec2D<float> mouse_pos, Camera2D camera){
|
2024-10-25 16:41:37 +02:00
|
|
|
mutex.lock();
|
|
|
|
|
updateMidiPorts();
|
2024-10-28 02:07:47 +01:00
|
|
|
mutex.unlock();
|
2024-10-30 14:55:24 +01:00
|
|
|
gm.drawNodes(mouse_pos, camera);
|
2024-11-01 02:38:47 +01:00
|
|
|
gm.drawEdges(mouse_pos, camera);
|
2024-10-25 16:41:37 +02:00
|
|
|
sm.drawSignals(mouse_pos, camera);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawUI(Vec2D<float> *mouse_pos, Camera2D *camera){
|
|
|
|
|
mutex.lock();
|
|
|
|
|
ui.draw(mouse_pos, camera);
|
|
|
|
|
mutex.unlock();
|
|
|
|
|
}
|
|
|
|
|
};
|