#pragma once #include "datatypes.h" #include "graph-manager.h" #include "midi-node.h" #include "signal-manager.h" #include "ui.h" #include #include #include #include #include namespace VISEQ::APP { class AppState{ public: AppState() : sm(&gm, &mutex), ui(&settings, &sm, &gm) {} enum States {IDLE, CONFIG}; AppSettings settings; States state; std::mutex mutex; VISEQ::GRAPH::GraphManager gm; VISEQ::SIGNAL::SignalManager sm; UI::AppUI ui; void updateMidiPorts(){ for(auto&n : gm.nodes | RANGE_FILTER([](VISEQ::GRAPH::NODES::SPTR_Node n){return n->getNodeType() == NodeType::MIDINODE;})){ auto nc = std::dynamic_pointer_cast(n); for(auto& mo : sm.midi.midi_out_ports){ if(!nc->midi_outs.contains(mo.number) && mo.enabled){ nc->midi_outs[mo.number] = {mo.number, mo.port.port_name, false}; } if(nc->midi_outs.contains(mo.number) && !mo.enabled){ nc->midi_outs.erase(mo.number); } } } } void copyNodesAndConnections(VEC_SPTR_Node nodes, Vec2Df position){ VEC_SPTR_Edge copy_connections; for(auto n : nodes){ 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(*c)); } } } 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(old_node), position + old_node->drag_offset); } else { new_node = gm.copyNode(old_node, position + old_node->drag_offset); } new_node->copied = false; new_node->selected = true; for(auto c : copy_connections){ 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); } } } std::ranges::copy(copy_connections.begin(), copy_connections.end(), std::back_inserter(gm.edges)); } void removeNodes(VEC_SPTR_Node nodes){ for(auto n : gm.nodes){ n->highlighted = false; } auto erase_connections = gm.edges | RANGE_FILTER([nodes](SPTR_Edge c){ return std::ranges::contains(nodes, c->start) || std::ranges::contains(nodes, c->end);}); VEC_SPTR_Node adjacent_nodes; 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); } auto reroute_signals = sm.signals | RANGE_FILTER([nodes](SIGNAL::SPTR_Signal s){return std::ranges::contains(nodes, s->next);}); for(auto s : reroute_signals){ float dist = 10000000; SPTR_Node next_node; for(auto n : adjacent_nodes){ if(n->position.dist(s->position) < dist) { dist = n->position.dist(s->position); next_node = n; } } s->next = next_node; s->last = next_node; } auto rebase_signals = sm.signals | RANGE_FILTER([nodes](SIGNAL::SPTR_Signal s){return std::ranges::contains(nodes, s->start);}); for(auto s : rebase_signals){ s->start = s->next; } for(auto n : adjacent_nodes){ std::erase_if(n->connections, [n, nodes](VISEQ::GRAPH::EDGES::SPTR_Edge c){ return std::ranges::contains(nodes, c->start) || std::ranges::contains(nodes, c->end);}); } for(auto n : nodes){ std::erase_if(gm.edges, [n](SPTR_Edge c){ return c->start == n || c->end == n;}); } std::erase_if(gm.nodes, [nodes](SPTR_Node n){ return std::ranges::contains(nodes, n);}); } void draw(Vec2Df mouse_pos, Camera2D camera){ mutex.lock(); updateMidiPorts(); mutex.unlock(); gm.drawNodes(mouse_pos, camera); gm.drawEdges(mouse_pos, camera); sm.drawSignals(mouse_pos, camera); } void drawUI(Vec2Df *mouse_pos, Camera2D *camera){ mutex.lock(); ui.draw(mouse_pos, camera); mutex.unlock(); } }; inline void to_json(json& j, const AppState& A){ j = json{{"graphmanager", A.gm}, {"signalmanager", A.sm}, {"settings",A.settings}}; } inline void from_json(const json& j, AppState& A){ j.at("graphmanager").get_to(A.gm); // = json{{"graphmanager", A.gm}, {"signalmanager", A.sm}}; } }