signals run in own thread for super precision!
This commit is contained in:
@@ -53,7 +53,7 @@ class ConnectionManager{
|
||||
return paths.at(return_path)->v1 == current ? paths.at(return_path)->v2 : paths.at(return_path)->v1;
|
||||
}
|
||||
|
||||
void draw(Vec2D<float> *mouse_pos, Camera2D *cam){
|
||||
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);
|
||||
|
||||
@@ -125,6 +125,20 @@ Vec2D<T> operator*(const Vec2D<T>& left, T scalar){
|
||||
return Vec2D<T>(left.x * scalar, left.y * scalar);
|
||||
};
|
||||
|
||||
// State
|
||||
|
||||
enum States {IDLE, CONFIG};
|
||||
|
||||
struct AppState{
|
||||
int width;
|
||||
int height;
|
||||
int grid;
|
||||
int bpm;
|
||||
int fps;
|
||||
float speed = 16.0f;
|
||||
int gui_selected_midi_out;
|
||||
States state;
|
||||
};
|
||||
|
||||
// MIDI
|
||||
|
||||
|
||||
+45
-47
@@ -17,8 +17,8 @@
|
||||
/*Blue: (108, 153, 187); #6c99bb*/
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "signal-manager.h"
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <raylib.h>
|
||||
#include <raymath.h>
|
||||
|
||||
@@ -30,18 +30,23 @@
|
||||
#include <stdio.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "midi.h"
|
||||
|
||||
//#include "midi.h"
|
||||
#include "node.h"
|
||||
#include "signal.h"
|
||||
|
||||
#include "connection-manager.h"
|
||||
#include "signal-manager.h"
|
||||
|
||||
AppState app;
|
||||
|
||||
std::vector<Node> nodes;
|
||||
std::vector<Signal> signals;
|
||||
|
||||
ConnectionManager cm;
|
||||
|
||||
Midi midi;
|
||||
|
||||
SignalManager sm(&app, &cm, &midi);
|
||||
|
||||
Vec2D<float> mouse_pos;
|
||||
Vec2D<float> drag_start;
|
||||
|
||||
@@ -49,14 +54,6 @@ bool mouse_clicked = false;
|
||||
bool mouse_touched = false;
|
||||
bool mouse_dragging = false;
|
||||
|
||||
enum States {IDLE, CONFIG};
|
||||
|
||||
struct AppState{
|
||||
int width;
|
||||
int height;
|
||||
int gui_selected_midi_out;
|
||||
States state;
|
||||
} app;
|
||||
|
||||
int main(){
|
||||
|
||||
@@ -70,6 +67,24 @@ int main(){
|
||||
|
||||
SetWindowMonitor(monitor);
|
||||
|
||||
app.fps = 60;
|
||||
app.bpm = 120;
|
||||
app.grid = round(((app.fps / (app.bpm / 60.0f)) * app.speed) / 4.0f); // from quarter notes to 16th notes = div by 4
|
||||
|
||||
// 120 fps
|
||||
// 120bpm = 120 1/4 Noten pro Minute = 2 1/4 Noten / s
|
||||
// 2px / frame bei 120fps = 240px / s = 14400 px / minute
|
||||
// 1/4 Note / 120 pixel
|
||||
// 1/16 Note alle 30 pixel
|
||||
|
||||
// 60 fps bei 120 bpm
|
||||
// 2px / frame bei 60fps = 120px / s = 7200 px / minute
|
||||
// 1/16 Note alle 15 pixel
|
||||
// 1/8 Note alle 30 pixel
|
||||
// 1/4 Note alle 60 pixel
|
||||
// 1/2 Note alle 120 pixel
|
||||
// 1/1 Note alle 240 pixel
|
||||
|
||||
app.width = GetMonitorWidth(monitor);
|
||||
app.height = GetMonitorHeight(monitor);
|
||||
|
||||
@@ -79,21 +94,22 @@ int main(){
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
SetTargetFPS(120);
|
||||
// std::thread t1(sm.updateSignals);
|
||||
|
||||
|
||||
SetTargetFPS(app.fps);
|
||||
|
||||
ToggleFullscreen();
|
||||
|
||||
|
||||
for(int i = 0; i < 10; i++){
|
||||
nodes.emplace(nodes.end(), Node((float)(rand() % app.width*0.5 + app.width*0.25), (float)(rand() % app.height*0.5 + app.height*0.25), 15.0f));
|
||||
}
|
||||
|
||||
for(int i = 0; i < 1; i++){
|
||||
signals.emplace(signals.end(), Signal(nodes.front().position.x+1, nodes.front().position.y+1, 5.0f, 2.0f)); // position + 1 or else it does not render. why? no idea!
|
||||
signals[i].next = &nodes.front();
|
||||
signals[i].last = &nodes.front();
|
||||
for(int i = 0; i < 8; i++){
|
||||
nodes.emplace(nodes.end(), Node((float)i * app.grid, 0.0f, 15.0f));
|
||||
}
|
||||
|
||||
sm.addSignalAtNode(&nodes.front());
|
||||
|
||||
sm.startSignalThread();
|
||||
|
||||
Vec2D<float> drag_offset;
|
||||
|
||||
Vec2D<float> cam_drag_offset;
|
||||
@@ -136,15 +152,15 @@ int main(){
|
||||
}
|
||||
|
||||
BeginDrawing();
|
||||
|
||||
DrawFPS(app.width - 300, 50);
|
||||
ClearBackground((Color){46,46,46});
|
||||
|
||||
BeginMode2D(camera);
|
||||
bool connecting = false;
|
||||
bool dragging = false;
|
||||
|
||||
for(int x = -5000; x < 5000; x+=50){
|
||||
for(int y = -5000; y < 5000; y+=50){
|
||||
for(int x = -app.grid*100; x < app.grid*100; x+=app.grid){
|
||||
for(int y = -app.grid*100; y < app.grid*100; y+=app.grid){
|
||||
// DrawLine(-5000, i, 5000, i, (Color){80,80,80,100});
|
||||
DrawPixel(x, y, (Color){120,120,120,200});
|
||||
}
|
||||
@@ -201,7 +217,7 @@ int main(){
|
||||
if(mouse_down && n.picked_up){
|
||||
if(GetTime() - drag_timer > 0.1) {
|
||||
if(IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||
n.position = (Vec2D<float>){round((mouse_pos.x+drag_offset.x)/50.0f)*50.0f, round((mouse_pos.y+drag_offset.y)/50.0f)*50.0f};
|
||||
n.position = (Vec2D<float>){round((mouse_pos.x+drag_offset.x)/app.grid)*app.grid, round((mouse_pos.y+drag_offset.y)/app.grid)*app.grid};
|
||||
} else {
|
||||
n.position = mouse_pos + drag_offset;
|
||||
}
|
||||
@@ -220,23 +236,9 @@ int main(){
|
||||
n.draw(&mouse_pos, &camera);
|
||||
}
|
||||
|
||||
cm.draw(&mouse_pos, &camera);
|
||||
cm.drawConnections(&mouse_pos, &camera);
|
||||
sm.drawSignals(&mouse_pos, &camera);
|
||||
|
||||
for(auto& s : signals){
|
||||
s.direction = (s.next->position - s.position).norm();
|
||||
if(s.position.dist(&s.next->position) < s.speed * 1.5) {
|
||||
Node* n = cm.next(s.next, s.last);
|
||||
|
||||
if(n != s.next && n != nullptr) {
|
||||
for(auto &m : s.next->midi_outs){
|
||||
if(m.second.enabled) midi.note(m.second.i, s.next->midi_channel, s.next->midi_note, s.next->midi_velocity, s.next->midi_gate);
|
||||
}
|
||||
s.last = s.next;
|
||||
s.next = n;
|
||||
}
|
||||
}
|
||||
s.draw(&mouse_pos, &camera);
|
||||
}
|
||||
midi.update();
|
||||
EndMode2D();
|
||||
|
||||
@@ -263,9 +265,7 @@ int main(){
|
||||
GuiLabel((Rectangle){20, 135 + i*20.0f, 240, 20}, "SIGNALS");
|
||||
if(GuiButton((Rectangle){20, 160 + i*20.0f, 240, 20}, "ADD RANDOM SIGNAL")){
|
||||
int ni = rand() % nodes.size();
|
||||
signals.emplace_back(Signal(nodes[ni].position.x + 1, nodes[ni].position.y + 1, 5.0f, 2.0f)); // position + 1 or else it does not render. why? no idea!
|
||||
signals.back().next = &nodes[ni];
|
||||
signals.back().last = &nodes[ni];
|
||||
sm.addSignalAtNode(&nodes[ni]);
|
||||
}
|
||||
|
||||
GuiLabel((Rectangle){20, 185 + i*20.0f, 240, 20}, "NODES");
|
||||
@@ -296,9 +296,7 @@ int main(){
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + 65, 220, 20}, "SIGNALS");
|
||||
if(GuiButton((Rectangle){np.x + 20, np.y + 90, 220, 20}, "ADD SIGNAL")){
|
||||
signals.emplace_back(Signal(n.position.x + 1, n.position.y + 1, 5.0f, 2.0f)); // position + 1 or else it does not render. why? no idea!
|
||||
signals.back().next = &n;
|
||||
signals.back().last = &n;
|
||||
sm.addSignalAtNode(&n);
|
||||
}
|
||||
|
||||
int y_midi = 120;
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ class Movable{
|
||||
Vec2D<float> position;
|
||||
Vec2D<float> direction;
|
||||
|
||||
virtual void update() {};
|
||||
virtual void update(int fps) {};
|
||||
virtual void draw(Vec2D<float> *mouse, Camera2D *cam) {};
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "connection-manager.h"
|
||||
#include "datatypes.h"
|
||||
#include "signal.h"
|
||||
#include "node.h"
|
||||
#include "midi.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
class SignalManager{
|
||||
|
||||
public:
|
||||
SignalManager(AppState *app, ConnectionManager *cm, Midi *midi) : app(app), cm(cm), midi(midi) {}
|
||||
|
||||
AppState *app;
|
||||
ConnectionManager *cm;
|
||||
Midi *midi;
|
||||
|
||||
std::vector<Signal> signals;
|
||||
|
||||
bool loop = true;
|
||||
|
||||
void startSignalThread(){
|
||||
std::thread t1(&SignalManager::updateSignals, this);
|
||||
t1.detach();
|
||||
}
|
||||
|
||||
void stopSignalThread(){
|
||||
loop = false;
|
||||
}
|
||||
|
||||
void addSignalAtNode(Node *node){
|
||||
signals.emplace(signals.end(), Signal(node->position.x+1, node->position.y+1, 5.0f, app->speed)); // position + 1 or else it does not render. why? no idea!
|
||||
signals.back().next = node;
|
||||
signals.back().last = node;
|
||||
}
|
||||
|
||||
void removeSignal(Signal *signal){
|
||||
}
|
||||
|
||||
void updateSignals(){
|
||||
auto last = std::chrono::steady_clock::now();
|
||||
while(loop){
|
||||
std::chrono::duration<double, std::milli> diff = std::chrono::steady_clock::now() - last;
|
||||
if(diff.count() > 10){
|
||||
for(auto& s : signals){
|
||||
s.direction = (s.next->position - s.position).norm();
|
||||
if(s.position.dist(&s.next->position) < s.speed * 1.5) {
|
||||
Node* n = cm->next(s.next, s.last);
|
||||
|
||||
if(n != s.next && n != nullptr) {
|
||||
for(auto &m : s.next->midi_outs){
|
||||
if(m.second.enabled) midi->note(m.second.i, s.next->midi_channel, s.next->midi_note, s.next->midi_velocity, s.next->midi_gate);
|
||||
}
|
||||
s.last = s.next;
|
||||
s.next = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
last = std::chrono::steady_clock::now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawSignals(Vec2D<float> *mouse_pos, Camera2D *camera){
|
||||
for(auto& s : signals){
|
||||
s.draw(mouse_pos, camera);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -23,6 +23,10 @@ class Signal : public Movable{
|
||||
|
||||
float radius;
|
||||
|
||||
void update(int fps){
|
||||
|
||||
}
|
||||
|
||||
void draw(Vec2D<float> *mouse, Camera2D *cam) {
|
||||
|
||||
position += direction.norm() * speed;
|
||||
|
||||
Reference in New Issue
Block a user