json is loading, but does nothing yet

This commit is contained in:
Sebastian
2024-11-03 03:48:49 +01:00
parent a4ea20b2b3
commit 7bdd68bdcc
16 changed files with 1174 additions and 1104 deletions
+1
View File
@@ -3,3 +3,4 @@ build/**
viseq viseq
viseq.exe viseq.exe
compile_commands.json compile_commands.json
state.json
+20 -36
View File
@@ -27,30 +27,14 @@ using json = nlohmann::json;
#include <math.h> #include <math.h>
#include "libremidi/libremidi.hpp" #include "libremidi/libremidi.hpp"
enum Distribution {GEOMETRIC, ROUNDROBIN, RANDOM};
// Types
/*class GraphItem;*/
/*class Node;*/
/*class Edge;*/
/*class Signal;*/
#define RANGE_FILTER(L) std::ranges::views::filter(L) #define RANGE_FILTER(L) std::ranges::views::filter(L)
/*typedef std::shared_ptr<GraphItem> SPTR_GraphItem;*/ namespace VISEQ::GRAPH::NODES {
/*typedef std::shared_ptr<Node> SPTR_Node;*/ enum Distribution {GEOMETRIC, ROUNDROBIN, RANDOM};
/*typedef std::shared_ptr<Edge> SPTR_Edge;*/ }
/**/
/*typedef std::shared_ptr<Signal> SPTR_Signal;*/
/**/
/*typedef std::vector<SPTR_GraphItem> VEC_SPTR_GraphItem;*/
/*typedef std::vector<SPTR_Node> VEC_SPTR_Node;*/
/*typedef std::vector<SPTR_Edge> VEC_SPTR_Edge;*/
/*typedef std::vector<SPTR_Signal> VEC_SPTR_Signal;*/
// App Settings namespace VISEQ::APP{
struct AppSettings{ struct AppSettings{
int mode = 0; int mode = 0;
int width; int width;
int height; int height;
@@ -59,32 +43,32 @@ struct AppSettings{
float fps; float fps;
float speed = 16.0f; float speed = 16.0f;
int gui_selected_midi_out; int gui_selected_midi_out;
}; };
}
namespace VISEQ::GRAPH{
enum GraphItemType {NODE, EDGE};
enum NodeType {OSCNODE, MIDINODE};
}
// Graph namespace VISEQ::MIDI{
struct MidiOutPort{
enum GraphItemType {NODE, EDGE};
enum NodeType {OSCNODE, MIDINODE};
// MIDI
struct MidiOutPort{
libremidi::output_port port; libremidi::output_port port;
int number; int number;
bool enabled; bool enabled;
}; };
struct MidiOut{ struct MidiOut{
libremidi::midi_out out; libremidi::midi_out out;
int number; int number;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MidiOut, number) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MidiOut, number)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MidiOutPort, number, enabled) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MidiOutPort, number, enabled)
namespace MIDI{
inline std::vector<std::string> Fractions = {"1/32","1/16","3/32","1/8","5/32","3/16","7/32","1/4","9/32","5/16","11/32","3/8","13/32","7/16","15/32","1/2","17/32","9/16","19/32","5/8","21/32","11/16","23/32","3/4","25/32","13/16","27/32","7/8","29/32","15/16","31/32","1/1"}; inline std::vector<std::string> Fractions = {"1/32","1/16","3/32","1/8","5/32","3/16","7/32","1/4","9/32","5/16","11/32","3/8","13/32","7/16","15/32","1/2","17/32","9/16","19/32","5/8","21/32","11/16","23/32","3/4","25/32","13/16","27/32","7/8","29/32","15/16","31/32","1/1"};
inline std::vector<std::string> Notes = { inline std::vector<std::string> Notes = {
"C-1", "C#-1", "D-1", "D#-1", "E-1", "F-1", "F#-1", "G-1", "C-1", "C#-1", "D-1", "D#-1", "E-1", "F-1", "F#-1", "G-1",
"G#-1", "A-1", "A#-1", "B-1", "C0", "C#0", "D0", "D#0", "G#-1", "A-1", "A#-1", "B-1", "C0", "C#0", "D0", "D#0",
+14 -12
View File
@@ -1,16 +1,20 @@
#pragma once #pragma once
#include "datatypes.h"
#include "graph-item.h" #include "graph-item.h"
#include <memory>
#include "node.h"
class Edge : public GraphItem{ using namespace VISEQ::GRAPH;
namespace VISEQ::GRAPH::EDGES {
class Edge : public GraphItem{
public: public:
Edge() {} Edge() {}
Edge(SPTR_Node start, SPTR_Node end) : start(start), end(end) {} Edge(std::shared_ptr<NODES::Node> start, std::shared_ptr<NODES::Node> end) : start(start), end(end) {}
SPTR_Node start; std::shared_ptr<NODES::Node> start;
SPTR_Node end; std::shared_ptr<NODES::Node> end;
bool pass_forward = true; bool pass_forward = true;
bool pass_backward = true; bool pass_backward = true;
@@ -24,15 +28,13 @@ class Edge : public GraphItem{
virtual bool GActive() {return active;} virtual bool GActive() {return active;}
SPTR_Node getNextNode(SPTR_Node origin){ std::shared_ptr<NODES::Node> getNextNode(std::shared_ptr<NODES::Node> origin){
return start == origin ? end : start; return start == origin ? end : start;
} }
void draw(Vec2Df mouse_pos, Camera2D cam) {} void draw(Vec2Df mouse_pos, Camera2D cam) {}
}; };
typedef std::shared_ptr<Edge> SPTR_Edge;
/*typedef std::shared_ptr<Edge> SPTR_Edge;*/ typedef std::vector<SPTR_Edge> VEC_SPTR_Edge;
/*typedef std::vector<SPTR_Edge> VEC_SPTR_Edge;*/ }
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Edge, id, start, end, pass_forward, pass_backward)
+4 -10
View File
@@ -5,7 +5,8 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
class GraphItem{ namespace VISEQ::GRAPH {
class GraphItem{
public: public:
GraphItem() {static int _id; id=_id++;} GraphItem() {static int _id; id=_id++;}
@@ -17,14 +18,7 @@ class GraphItem{
virtual GraphItemType getType() {return graphItemType;} virtual GraphItemType getType() {return graphItemType;}
virtual ~GraphItem() = default; virtual ~GraphItem() = default;
/*void to_json(json& j, const GraphItem& G){*/ };
/* j = json{{"id",id},{"graphItemType",graphItemType},{"neighbors",neighbors}};*/
/*}*/
}; }
/*typedef std::shared_ptr<GraphItem> SPTR_GraphItem;*/
/*typedef std::vector<SPTR_GraphItem> VEC_SPTR_GraphItem;*/
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GraphItem, id, graphItemType, neighbors)
+23 -30
View File
@@ -8,9 +8,9 @@
#include "nlohmann/json.hpp" #include "nlohmann/json.hpp"
#include "button.h" #include "button.h"
#include "node.h"
#include "midi-node.h" #include "midi-node.h"
#include "edge.h" #include "edge.h"
#include "node.h"
#include <algorithm> #include <algorithm>
#include <cstdio> #include <cstdio>
@@ -26,49 +26,35 @@
using json = nlohmann::json; using json = nlohmann::json;
typedef std::shared_ptr<GraphItem> SPTR_GraphItem; using namespace VISEQ::GRAPH::NODES;
typedef std::shared_ptr<Node> SPTR_Node; using namespace VISEQ::GRAPH::EDGES;
typedef std::shared_ptr<Edge> SPTR_Edge;
typedef std::shared_ptr<Signal> SPTR_Signal; namespace VISEQ::GRAPH {
typedef std::vector<SPTR_GraphItem> VEC_SPTR_GraphItem; class GraphManager{
typedef std::vector<SPTR_Node> VEC_SPTR_Node;
typedef std::vector<SPTR_Edge> VEC_SPTR_Edge;
typedef std::vector<SPTR_Signal> VEC_SPTR_Signal;
class GraphManager{
public: public:
GraphManager() {} GraphManager() {}
VEC_SPTR_Node nodes; NODES::VEC_SPTR_Node nodes;
VEC_SPTR_Edge edges; EDGES::VEC_SPTR_Edge edges;
VEC_SPTR_Edge remove_edges; EDGES::VEC_SPTR_Edge remove_edges;
VEC_SPTR_Edge split_edges; EDGES::VEC_SPTR_Edge split_edges;
std::map<SPTR_Node, int> counter; std::map<NODES::SPTR_Node, int> counter;
/*void to_json(json& j, const GraphManager& G){*/ NODES::SPTR_Node getRandomNode(){
/* j = json{{"nodes", G.nodes}, {"edges", G.edges}};*/
/*}*/
/**/
/*void from_json(const json& j, GraphManager& G){*/
/**/
/*}*/
SPTR_Node getRandomNode(){
VEC_SPTR_GraphItem o; VEC_SPTR_GraphItem o;
std::ranges::sample(nodes, std::back_inserter(o), 1, std::mt19937{std::random_device{}()}); std::ranges::sample(nodes, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return std::dynamic_pointer_cast<Node>(o.front()); return std::dynamic_pointer_cast<VISEQ::GRAPH::NODES::Node>(o.front());
} }
SPTR_Edge getRandomEdge(){ EDGES::SPTR_Edge getRandomEdge(){
VEC_SPTR_GraphItem o; VEC_SPTR_GraphItem o;
std::ranges::sample(edges, std::back_inserter(o), 1, std::mt19937{std::random_device{}()}); std::ranges::sample(edges, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
return std::dynamic_pointer_cast<Edge>(o.front()); return std::dynamic_pointer_cast<VISEQ::GRAPH::EDGES::Edge>(o.front());
} }
void copyNodes(VEC_SPTR_Node _nodes, Vec2Df position){ void copyNodes(VEC_SPTR_Node _nodes, Vec2Df position){
@@ -291,6 +277,13 @@ class GraphManager{
} }
} }
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GraphManager, nodes, edges) inline void to_json(json& j, const GraphManager& G){
j = json{{"nodes", G.nodes}, {"edges", G.edges}};
}
inline void from_json(const json& j, GraphManager& G){
j.at("nodes").get_to(G.nodes); // = json{{"nodes", G.nodes}, {"edges", G.edges}};
}
}
+23 -7
View File
@@ -6,6 +6,10 @@
* *
*/ */
#include "graph-manager.h"
#include "vmath.h"
#include <filesystem>
#include <fstream>
#define RAYGUI_IMPLEMENTATION #define RAYGUI_IMPLEMENTATION
#include <raylib.h> #include <raylib.h>
#include <raymath.h> #include <raymath.h>
@@ -24,9 +28,11 @@
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include "state-io.h"
using json = nlohmann::json; using json = nlohmann::json;
AppState app; VISEQ::APP::AppState app;
Vec2Df mouse_pos; Vec2Df mouse_pos;
Vec2Df drag_start; Vec2Df drag_start;
@@ -72,6 +78,13 @@ int main(){
camera.rotation = 0.0f; camera.rotation = 0.0f;
camera.zoom = 1.0f; camera.zoom = 1.0f;
if(std::filesystem::exists("state.json")){
std::ifstream f("state.json");
json graph = json::parse(f);
app.gm = graph["graphmanager"].template get<VISEQ::GRAPH::GraphManager>();
} else {
for(int i = 0; i < 4; ++i){ for(int i = 0; i < 4; ++i){
app.gm.addMidiNode(Vec2Df{(float)i * app.settings.grid*4 + 7 * app.settings.grid, 2 * app.settings.grid*4}); app.gm.addMidiNode(Vec2Df{(float)i * app.settings.grid*4 + 7 * app.settings.grid, 2 * app.settings.grid*4});
} }
@@ -82,9 +95,9 @@ int main(){
for(int i = 0; i < 8; ++i){ for(int i = 0; i < 8; ++i){
app.gm.addConnection(app.gm.nodes[i], app.gm.nodes[(i+1) % 8]); app.gm.addConnection(app.gm.nodes[i], app.gm.nodes[(i+1) % 8]);
} }
app.sm.addSignalAtNode(app.gm.nodes.front()); app.sm.addSignalAtNode(app.gm.nodes.front());
}
app.sm.startSignalThread(); app.sm.startSignalThread();
enum InteractionState {HOVER_CANVAS, HOVER_NODE, HOVER_CONNECTOR, DRAG_NODE, CONNECT_NODE, DRAW_SELECTION, DELETE_SELECTED_NODES, COPY_SELECTED_NODES, PASTE_SELECTED_NODES}; enum InteractionState {HOVER_CANVAS, HOVER_NODE, HOVER_CONNECTOR, DRAG_NODE, CONNECT_NODE, DRAW_SELECTION, DELETE_SELECTED_NODES, COPY_SELECTED_NODES, PASTE_SELECTED_NODES};
@@ -223,7 +236,7 @@ int main(){
float pol_r = steps; float pol_r = steps;
float pol_theta = Vector2Angle(Vec2Df{1,0},(mouse_pos - dragNode->neighbor->position)); float pol_theta = Vector2Angle(Vec2Df{1,0},(mouse_pos - dragNode->neighbor->position));
Vec2Df polar = VMath::polarToCartesian(pol_r, pol_theta); Vec2Df polar = VISEQ::VMATH::polarToCartesian(pol_r, pol_theta);
dragNode->position = dragNode->neighbor->position + polar; dragNode->position = dragNode->neighbor->position + polar;
} else { } else {
dragNode->position = mouse_pos + dragNode->drag_offset; dragNode->position = mouse_pos + dragNode->drag_offset;
@@ -330,8 +343,8 @@ int main(){
midiNode->midi_pitch_bend += wheel; midiNode->midi_pitch_bend += wheel;
break;} break;}
}; };
if(midiNode->midi_note < 0 ) midiNode->midi_note = app.sm.midi.midiNotes.size()-1; if(midiNode->midi_note < 0 ) midiNode->midi_note = VISEQ::MIDI::Notes.size()-1;
if(midiNode->midi_note >= app.sm.midi.midiNotes.size() ) midiNode->midi_note = 0; if(midiNode->midi_note >= VISEQ::MIDI::Notes.size() ) midiNode->midi_note = 0;
if(midiNode->midi_cc < 0 ) midiNode->midi_cc = 127; if(midiNode->midi_cc < 0 ) midiNode->midi_cc = 127;
if(midiNode->midi_cc > 127 ) midiNode->midi_cc = 0; if(midiNode->midi_cc > 127 ) midiNode->midi_cc = 0;
@@ -390,7 +403,10 @@ int main(){
EndDrawing(); EndDrawing();
} }
std::cout << std::setw(4) << json(app.gm) << std::endl; std::ofstream file("state.json");
file << json(app);
std::cout << std::setw(4) << json(app) << std::endl;
CloseWindow(); CloseWindow();
+11 -12
View File
@@ -7,17 +7,17 @@
#define RADIUS 14.0f #define RADIUS 14.0f
struct NodeMidiOut{ namespace VISEQ::GRAPH::NODES {
class MidiNode : public Node{
public:
struct NodeMidiOut{
int i; int i;
std::string name; std::string name;
bool enabled; bool enabled;
}; };
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(NodeMidiOut, i, name, enabled)
class MidiNode : public Node{
public:
MidiNode() {} MidiNode() {}
MidiNode(Vec2Df position) : Node(position) {} MidiNode(Vec2Df position) : Node(position) {}
@@ -63,7 +63,7 @@ class MidiNode : public Node{
float time = 0; float time = 0;
float last = 0; float last = 0;
virtual NodeType getNodeType() override {return nodeType;} virtual NodeType getNodeType() const override {return nodeType;}
void setMidiPort(int midi_port, bool state){ void setMidiPort(int midi_port, bool state){
midi_outs[midi_port].enabled = state; midi_outs[midi_port].enabled = state;
@@ -167,6 +167,5 @@ class MidiNode : public Node{
} }
if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200}); if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200});
} }
}; };
}
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MidiNode, id, nodeType, send_note, send_cc, send_pc, send_pitch_bend, midi_outs, mode, midi_note_channel, midi_note, midi_velocity, midi_gate, midi_cc_channel, midi_cc, midi_cc_value, midi_pc_channel, midi_pc, midi_pc_value, midi_pitch_bend_channel, midi_pitch_bend)
+8 -25
View File
@@ -8,10 +8,11 @@
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <memory> #include <memory>
#include <numbers>
#include "datatypes.h" #include "datatypes.h"
struct NoteTimer{ namespace VISEQ::MIDI {
struct NoteTimer{
int midi_out; int midi_out;
int channel; int channel;
int note; int note;
@@ -19,35 +20,15 @@ struct NoteTimer{
float start; float start;
int gate; int gate;
bool erase = false; bool erase = false;
}; };
class Midi { class Midi {
public: public:
Midi() { Midi() {
enumerate(); enumerate();
} }
std::vector<std::string> midiNotes = {
"C-1", "C#-1", "D-1", "D#-1", "E-1", "F-1", "F#-1", "G-1",
"G#-1", "A-1", "A#-1", "B-1", "C0", "C#0", "D0", "D#0",
"E0", "F0", "F#0", "G0", "G#0", "A0", "A#0", "B0",
"C1", "C#1", "D1", "D#1", "E1", "F1", "F#1", "G1",
"G#1", "A1", "A#1", "B1", "C2", "C#2", "D2", "D#2",
"E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2",
"C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3",
"G#3", "A3", "A#3", "B3", "C4", "C#4", "D4", "D#4",
"E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4",
"C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5",
"G#5", "A5", "A#5", "B5", "C6", "C#6", "D6", "D#6",
"E6", "F6", "F#6", "G6", "G#6", "A6", "A#6", "B6",
"C7", "C#7", "D7", "D#7", "E7", "F7", "F#7", "G7",
"G#7", "A7", "A#7", "B7", "C8", "C#8", "D8", "D#8",
"E8", "F8", "F#8", "G8", "G#8", "A8", "A#8", "B8",
"C9", "C#9", "D9", "D#9", "E9", "F9", "F#9", "G9",
"G#9", "A9", "A#9", "B9", "C10"
};
libremidi::observer obs; libremidi::observer obs;
std::map<int, std::shared_ptr<libremidi::midi_out>> midi_outs; std::map<int, std::shared_ptr<libremidi::midi_out>> midi_outs;
@@ -126,4 +107,6 @@ class Midi {
} }
} }
} }
}; };
}
+4 -7
View File
@@ -2,8 +2,8 @@
#include "datatypes.h" #include "datatypes.h"
namespace VISEQ::BASE {
class Movable{ class Movable{
public: public:
Movable() {} Movable() {}
@@ -37,9 +37,6 @@ class Movable{
virtual void update(double frametime) {}; virtual void update(double frametime) {};
virtual void update() {}; virtual void update() {};
/*virtual void to_json(json& j, const Movable& M){*/ };
/* j = json{{"position", M.position}, {"direction", M.direction}, {"speed", M.speed}};*/
/*}*/
};
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Movable, position, direction, speed) }
+11 -18
View File
@@ -3,18 +3,17 @@
#include <memory> #include <memory>
#include <raylib.h> #include <raylib.h>
#include "nlohmann/json.hpp"
#include "datatypes.h" #include "datatypes.h"
#include "graph-item.h" #include "graph-item.h"
#include "moveable.h" #include "moveable.h"
class Edge; namespace VISEQ::GRAPH::EDGES{
class Edge;
}
typedef std::shared_ptr<Edge> SPTR_Edge; namespace VISEQ::GRAPH::NODES {
typedef std::vector<SPTR_Edge> VEC_SPTR_Edge;
class Node : public Movable, public GraphItem{ class Node : public BASE::Movable, public GraphItem{
public: public:
Node() {} Node() {}
@@ -25,29 +24,23 @@ class Node : public Movable, public GraphItem{
std::shared_ptr<Node> neighbor; std::shared_ptr<Node> neighbor;
VEC_SPTR_Edge connections; std::vector<std::shared_ptr<VISEQ::GRAPH::EDGES::Edge>> connections;
Distribution distributionMode = Distribution::GEOMETRIC; Distribution distributionMode = Distribution::GEOMETRIC;
float radius = 15.0f; float radius = 15.0f;
bool config = false; bool config = false;
virtual NodeType getNodeType() {return nodeType;} virtual NodeType getNodeType() const {return nodeType;}
virtual void SMode(int mode) {}; virtual void SMode(int mode) {};
virtual int GGate() {return 0;}; virtual int GGate() {return 0;};
virtual int GActive() {return 0;}; virtual int GActive() {return 0;};
virtual void trigger() {}; virtual void trigger() {};
void draw(Vec2Df mouse_pos, Camera2D cam) override {} void draw(Vec2Df mouse_pos, Camera2D cam) override {}
}; };
typedef std::shared_ptr<Node> SPTR_Node; typedef std::shared_ptr<VISEQ::GRAPH::NODES::Node> SPTR_Node;
typedef std::vector<SPTR_Node> VEC_SPTR_Node; typedef std::vector<SPTR_Node> VEC_SPTR_Node;
}
/*inline void to_json(json& j, const std::shared_ptr<Node>& N){*/
/* j = json{{"id", N->id}, {"nodeType",N->nodeType}};*/
/*}*/
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Node, nodeType, neighbor, connections, distributionMode)
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Node, id, nodeType, distributionMode)
+15 -3
View File
@@ -10,13 +10,20 @@
#include <memory> #include <memory>
#include <thread> #include <thread>
class SignalManager{ using namespace VISEQ::GRAPH;
namespace VISEQ::SIGNAL {
typedef std::shared_ptr<Signal> SPTR_Signal;
typedef std::vector<SPTR_Signal> VEC_SPTR_Signal;
class SignalManager{
public: public:
SignalManager() {} SignalManager() {}
SignalManager(GraphManager *gm, std::mutex *mutex) : mutex(mutex), gm(gm) {} SignalManager(GraphManager *gm, std::mutex *mutex) : mutex(mutex), gm(gm) {}
Midi midi; VISEQ::MIDI::Midi midi;
std::mutex *mutex; std::mutex *mutex;
GraphManager *gm; GraphManager *gm;
@@ -113,4 +120,9 @@ class SignalManager{
} }
} }
}; };
inline void to_json(json& j, const SignalManager& G){
j = json{{"signals", G.signals}};
}
}
+11 -7
View File
@@ -1,23 +1,25 @@
#pragma once #pragma once
#include <raylib.h> #include <raylib.h>
#include "datatypes.h"
#include "moveable.h" #include "moveable.h"
#include "node.h" #include "node.h"
#include "edge.h" #include "edge.h"
class Signal : public Movable{ using namespace VISEQ::GRAPH;
namespace VISEQ::SIGNAL {
class Signal : public BASE::Movable{
public: public:
Signal(); Signal();
Signal(Vec2Df position, float r, float _speed, Color color) : Movable(position, Vec2Df(0,0), _speed), radius(r), color(color) {} Signal(Vec2Df position, float r, float _speed, Color color) : Movable(position, Vec2Df(0,0), _speed), radius(r), color(color) {}
SPTR_Node next; NODES::SPTR_Node next;
SPTR_Node last; NODES::SPTR_Node last;
SPTR_Edge edge; EDGES::SPTR_Edge edge;
SPTR_Node start; NODES::SPTR_Node start;
bool at_target = false; bool at_target = false;
@@ -37,4 +39,6 @@ class Signal : public Movable{
void draw(Vec2Df mouse, Camera2D cam) { void draw(Vec2Df mouse, Camera2D cam) {
DrawCircle(position.x, position.y, radius, color); DrawCircle(position.x, position.y, radius, color);
} }
}; };
}
+130 -54
View File
@@ -4,57 +4,60 @@
#include "graph-item.h" #include "graph-item.h"
#include "node.h" #include "node.h"
#include "edge.h" #include "edge.h"
#include "graph-manager.h" //#include "graph-manager.h"
#include "datatypes.h" #include "datatypes.h"
#include "signal.h"
#include <iostream>
#include <memory> #include <memory>
/*namespace nlohmann { */ /*using namespace VISEQ::BASE;*/
/* template <typename T>*/ /*using namespace VISEQ::SIGNAL;*/
/* struct adl_serializer<std::shared_ptr<T>> {*/ /*using namespace VISEQ::GRAPH::NODES;*/
/* static void to_json(json& j, const std::shared_ptr<T>& opt){*/ /*using namespace VISEQ::GRAPH::EDGES;*/
/* if (opt)*/
/* {*/
/* j = *opt;*/
/* }*/
/* else*/
/* {*/
/* j = nullptr;*/
/* }*/
/* }*/
/**/
/* static void from_json(const json& j, std::shared_ptr<T>& opt){*/
/* if (j.is_null())*/
/* {*/
/* opt = nullptr;*/
/* }*/
/* else*/
/* {*/
/* opt.reset(new T(j.get<T>()));*/
/* //opt = j.get<T>();*/
/* }*/
/* }*/
/* };*/
/*}*/
typedef std::shared_ptr<VISEQ::GRAPH::GraphItem> SPTR_GraphItem;
typedef std::vector<SPTR_GraphItem> VEC_SPTR_GraphItem;
namespace VISEQ::GRAPH::EDGES {
using namespace VISEQ::GRAPH::NODES;
inline void to_json(json& j, const Edge& E){ inline void to_json(json& j, const VISEQ::GRAPH::EDGES::Edge& E){
j = json{{"id",E.id}, {"start", E.start->id}, {"end",E.end->id}, {"pass_forward",E.pass_forward}, {"pass_backward", E.pass_backward}}; j = json{{"id",E.id}, {"start", E.start->id}, {"end",E.end->id}, {"pass_forward",E.pass_forward}, {"pass_backward", E.pass_backward}};
} }
inline void to_json(json& j, const SPTR_Edge& E){ inline void from_json(const json& j, Edge& E){
j.at("id").get_to(E.id);
j.at("pass_forward").get_to(E.pass_forward);
j.at("pass_backward").get_to(E.pass_backward);
}
inline void to_json(json& j, const VISEQ::GRAPH::EDGES::SPTR_Edge& E){
j = *E; j = *E;
}
inline void from_json(const json& j, VISEQ::GRAPH::EDGES::SPTR_Edge& E){
E.reset(new Edge(j.get<Edge>()));
}
} }
inline void to_json(json& j, const MidiNode& N){ namespace VISEQ::GRAPH::NODES {
/* ------------------- MIDINODE ---------------------- */
inline void to_json(json& j, const MidiNode& N){
std::vector<int> conns; std::vector<int> conns;
std::ranges::transform(N.connections.begin(), N.connections.end(), std::back_inserter(conns), [](SPTR_Edge e){ return e->id;}); std::ranges::transform(N.connections.begin(), N.connections.end(), std::back_inserter(conns), [](VISEQ::GRAPH::EDGES::SPTR_Edge e){ return e->id;});
j = json{{"id", N.id}, {"position", N.position}, {"distributionMode", N.distributionMode},
j = json{
{"id", N.id},
{"position", N.position},
{"distributionMode", N.distributionMode},
{"nodeType", N.nodeType},
{"midi_note_channel",N.midi_note_channel}, {"midi_note_channel",N.midi_note_channel},
{"midi_velocity",N.midi_velocity}, {"midi_velocity",N.midi_velocity},
{"midi_gatel",N.midi_gate}, {"midi_gate",N.midi_gate},
{"midi_cc_channel",N.midi_cc_channel}, {"midi_cc_channel",N.midi_cc_channel},
{"midi_cc",N.midi_cc}, {"midi_cc",N.midi_cc},
{"midi_cc_value",N.midi_cc_value}, {"midi_cc_value",N.midi_cc_value},
@@ -63,35 +66,108 @@ inline void to_json(json& j, const MidiNode& N){
{"midi_pitch_bend_channel",N.midi_pitch_bend_channel}, {"midi_pitch_bend_channel",N.midi_pitch_bend_channel},
{"midi_pitch_bend",N.midi_pitch_bend}, {"midi_pitch_bend",N.midi_pitch_bend},
{"connections",conns}}; {"connections",conns}};
} }
inline void to_json(json& j, const std::shared_ptr<MidiNode>& N){ inline void from_json(const json& j, MidiNode& N){
j.at("id").get_to(N.id);
j.at("position").get_to(N.position);
j.at("distributionMode").get_to(N.distributionMode);
j.at("nodeType").get_to(N.nodeType);
j.at("midi_note_channel").get_to(N.midi_note_channel);
j.at("midi_velocity").get_to(N.midi_velocity);
j.at("midi_gate").get_to(N.midi_gate);
j.at("midi_cc_channel").get_to(N.midi_cc_channel);
j.at("midi_cc").get_to(N.midi_cc);
j.at("midi_cc_value").get_to(N.midi_cc_value);
j.at("midi_pc_channel").get_to(N.midi_pc_channel);
j.at("midi_pc_value").get_to(N.midi_pc_value);
j.at("midi_pitch_bend_channel").get_to(N.midi_pitch_bend_channel);
j.at("midi_pitch_bend").get_to(N.midi_pitch_bend);
//j.at("connections").get_to(N.connections);
}
inline void to_json(json& j, const std::shared_ptr<MidiNode>& N){
j = *N; j = *N;
} }
inline void to_json(json& j, const GraphItem& G){ inline void from_json(const json& j, std::shared_ptr<MidiNode>& N){
j = json{{"id", G.id}, {"type", G.graphItemType}}; N.reset(new MidiNode(j.get<MidiNode>()));
} }
inline void to_json(json& j, const SPTR_GraphItem& G){
j = *G;
}
inline void to_json(json& j, const MidiOutPort MO){ /* ------------------- NODE ---------------------- */
j = json{{"port_id", MO.number}, {"enabled", MO.enabled}};
}
inline void to_json(json& j, const NodeMidiOut MO){
j = json{{"port_id", MO.i}, {"enabled", MO.enabled}, {"name", MO.name}};
}
inline void to_json(json& j, const Node& N){ inline void to_json(json& j, const Node& N){
if(N.nodeType == NodeType::MIDINODE){ if(N.getNodeType() == NodeType::MIDINODE){
j = dynamic_cast<const MidiNode&>(N); j = dynamic_cast<const MidiNode&>(N);
} }
}
inline void from_json(const json& j, Node& N){
if(j.at("nodeType") == NodeType::MIDINODE){
std::cout << j.at("nodeType") << std::endl;
N = j.template get<MidiNode>();
}
/*j.at("id").get_to(N.id);*/
/*j.at("position").get_to(N.position);*/
/*j.at("distributionMode").get_to(N.distributionMode);*/
/*j.at("nodeType").get_to(N.nodeType);*/
//j.at("connections").get_to(N.connections);
}
inline void to_json(json& j, const SPTR_Node& N){
j = *N;
}
inline void to_json(json& j, const MidiNode::NodeMidiOut MO){
j = json{{"port_id", MO.i}, {"enabled", MO.enabled}, {"name", MO.name}};
}
inline void from_json(const json& j, std::shared_ptr<Node>& N){
N.reset(new Node(j.get<Node>()));
}
}
namespace VISEQ::GRAPH {
inline void to_json(json& j, const GraphItem& G){
j = json{{"id", G.id}, {"type", G.graphItemType}};
}
inline void to_json(json& j, const SPTR_GraphItem& G){
j = *G;
}
} }
inline void to_json(json& j, const std::shared_ptr<Node>& N){ namespace VISEQ::BASE{
j = *N; inline void to_json(json& j, const Movable& G){
j = json{{"position", G.position}};
}
inline void to_json(json& j, const std::shared_ptr<Movable>& G){
j = *G;
}
} }
namespace VISEQ::SIGNAL{
inline void to_json(json& j, const Signal& G){
j = json{{"position", G.position},{"start",G.start->id},{"speed",G.speed}};
}
inline void to_json(json& j, const std::shared_ptr<Signal>& G){
j = *G;
}
}
namespace VISEQ::MIDI {
inline void to_json(json& j, const MidiOutPort MO){
j = json{{"port_id", MO.number}, {"enabled", MO.enabled}};
}
}
+20 -10
View File
@@ -1,6 +1,5 @@
#pragma once #pragma once
#include "edge.h"
#include "datatypes.h" #include "datatypes.h"
#include "graph-manager.h" #include "graph-manager.h"
#include "midi-node.h" #include "midi-node.h"
@@ -13,7 +12,9 @@
#include <ranges> #include <ranges>
#include <vector> #include <vector>
class AppState{ namespace VISEQ::APP {
class AppState{
public: public:
AppState() : sm(&gm, &mutex), ui(&settings, &sm, &gm) {} AppState() : sm(&gm, &mutex), ui(&settings, &sm, &gm) {}
@@ -26,13 +27,13 @@ class AppState{
std::mutex mutex; std::mutex mutex;
GraphManager gm; VISEQ::GRAPH::GraphManager gm;
SignalManager sm; VISEQ::SIGNAL::SignalManager sm;
AppUI ui; UI::AppUI ui;
void updateMidiPorts(){ void updateMidiPorts(){
for(auto&n : gm.nodes | RANGE_FILTER([](SPTR_Node n){return n->getNodeType() == NodeType::MIDINODE;})){ for(auto&n : gm.nodes | RANGE_FILTER([](VISEQ::GRAPH::NODES::SPTR_Node n){return n->getNodeType() == NodeType::MIDINODE;})){
auto nc = std::dynamic_pointer_cast<MidiNode>(n); auto nc = std::dynamic_pointer_cast<MidiNode>(n);
for(auto& mo : sm.midi.midi_out_ports){ for(auto& mo : sm.midi.midi_out_ports){
if(!nc->midi_outs.contains(mo.number) && mo.enabled){ if(!nc->midi_outs.contains(mo.number) && mo.enabled){
@@ -98,7 +99,7 @@ class AppState{
if(!c->end->selected) adjacent_nodes.push_back(c->end); if(!c->end->selected) adjacent_nodes.push_back(c->end);
} }
auto reroute_signals = sm.signals | RANGE_FILTER([nodes](SPTR_Signal s){return std::ranges::contains(nodes, s->next);}); auto reroute_signals = sm.signals | RANGE_FILTER([nodes](SIGNAL::SPTR_Signal s){return std::ranges::contains(nodes, s->next);});
for(auto s : reroute_signals){ for(auto s : reroute_signals){
float dist = 10000000; float dist = 10000000;
@@ -113,14 +114,14 @@ class AppState{
s->last = next_node; s->last = next_node;
} }
auto rebase_signals = sm.signals | RANGE_FILTER([nodes](SPTR_Signal s){return std::ranges::contains(nodes, s->start);}); auto rebase_signals = sm.signals | RANGE_FILTER([nodes](SIGNAL::SPTR_Signal s){return std::ranges::contains(nodes, s->start);});
for(auto s : rebase_signals){ for(auto s : rebase_signals){
s->start = s->next; s->start = s->next;
} }
for(auto n : adjacent_nodes){ 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);}); 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){ for(auto n : nodes){
@@ -143,4 +144,13 @@ class AppState{
ui.draw(mouse_pos, camera); ui.draw(mouse_pos, camera);
mutex.unlock(); mutex.unlock();
} }
}; };
inline void to_json(json& j, const AppState& A){
j = json{{"graphmanager", A.gm}, {"signalmanager", A.sm}};
}
inline void from_json(const json& j, AppState& A){
j.at("graphmanager").get_to(A.gm); // = json{{"graphmanager", A.gm}, {"signalmanager", A.sm}};
}
}
+8 -6
View File
@@ -12,14 +12,15 @@
#include <memory> #include <memory>
#include <ranges> #include <ranges>
class AppUI{ namespace VISEQ::APP::UI{
class AppUI{
public: public:
AppUI() {}
AppUI(AppSettings *settings, SignalManager *sm, GraphManager *gm) : settings(settings), gm(gm), sm(sm) {} AppUI(AppSettings *settings, SIGNAL::SignalManager *sm, GraphManager *gm) : settings(settings), gm(gm), sm(sm) {}
AppSettings *settings; AppSettings *settings;
GraphManager *gm; GraphManager *gm;
SignalManager *sm; SIGNAL::SignalManager *sm;
void init(){ void init(){
GuiLoadStyleDark(); GuiLoadStyleDark();
@@ -128,7 +129,7 @@ class AppUI{
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note , 100, 20}, "NOTE"); GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note , 100, 20}, "NOTE");
float v = mn->midi_note; float v = mn->midi_note;
GuiLabel((Rectangle){np.x + 210, np.y + y_cc_note , 20, 20}, sm->midi.midiNotes[(int)round(v)].c_str()); GuiLabel((Rectangle){np.x + 210, np.y + y_cc_note , 20, 20}, MIDI::Notes[(int)round(v)].c_str());
GuiLabel((Rectangle){np.x + 160, np.y + y_cc_note , 40, 20}, std::format("{}",mn->midi_note).c_str()); GuiLabel((Rectangle){np.x + 160, np.y + y_cc_note , 40, 20}, std::format("{}",mn->midi_note).c_str());
GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 30, 220, 20}, "", "", &v, 0, 127); GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 30, 220, 20}, "", "", &v, 0, 127);
mn->midi_note = round(v); mn->midi_note = round(v);
@@ -184,4 +185,5 @@ class AppUI{
drawPerNodeConfig(camera); drawPerNodeConfig(camera);
} }
}; };
}
+6 -2
View File
@@ -7,7 +7,7 @@
using json = nlohmann::json; using json = nlohmann::json;
namespace VMath{ namespace VISEQ::VMATH{
template<typename T> template<typename T>
class Vec2D{ class Vec2D{
@@ -158,4 +158,8 @@ namespace VMath{
} }
} }
using Vec2Df = VMath::Vec2D<float>; using Vec2Df = VISEQ::VMATH::Vec2D<float>;