2024-10-22 01:55:31 +02:00
|
|
|
#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:
|
2024-10-25 16:41:37 +02:00
|
|
|
SignalManager() {}
|
|
|
|
|
SignalManager(ConnectionManager *cm, std::mutex *mutex) : mutex(mutex), cm(cm) {}
|
2024-10-22 01:55:31 +02:00
|
|
|
|
2024-10-25 16:41:37 +02:00
|
|
|
Midi midi;
|
|
|
|
|
|
|
|
|
|
std::mutex *mutex;
|
2024-10-22 01:55:31 +02:00
|
|
|
ConnectionManager *cm;
|
|
|
|
|
|
|
|
|
|
std::vector<Signal> signals;
|
|
|
|
|
|
|
|
|
|
bool loop = true;
|
2024-10-25 02:43:41 +02:00
|
|
|
bool play = false;
|
|
|
|
|
|
|
|
|
|
void pause(){
|
|
|
|
|
play = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void stop(){
|
|
|
|
|
play = false;
|
|
|
|
|
reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void start(){
|
|
|
|
|
play = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reset(){
|
|
|
|
|
for(auto &s : signals){
|
|
|
|
|
s.position = s.start->position + Vec2D<float>{0.1, 0.1};
|
|
|
|
|
s.next = s.start;
|
|
|
|
|
s.last = s.start;
|
|
|
|
|
}
|
|
|
|
|
cm->reset();
|
|
|
|
|
}
|
2024-10-22 01:55:31 +02:00
|
|
|
|
|
|
|
|
void startSignalThread(){
|
|
|
|
|
std::thread t1(&SignalManager::updateSignals, this);
|
|
|
|
|
t1.detach();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void stopSignalThread(){
|
|
|
|
|
loop = false;
|
|
|
|
|
}
|
2024-10-25 16:41:37 +02:00
|
|
|
|
2024-10-22 01:55:31 +02:00
|
|
|
void addSignalAtNode(Node *node){
|
2024-10-22 03:07:11 +02:00
|
|
|
Color c = {(unsigned char)(232 - (rand() % 120)), (unsigned char)(125 + (int)(rand() % 120)), 62, 255};
|
2024-10-25 16:41:37 +02:00
|
|
|
signals.emplace(signals.end(), Signal(node->position.x+1, node->position.y+1, 5.0f, 0, c)); // position + 1 or else it does not render. why? no idea!
|
2024-10-22 01:55:31 +02:00
|
|
|
signals.back().next = node;
|
|
|
|
|
signals.back().last = node;
|
2024-10-25 02:43:41 +02:00
|
|
|
signals.back().start = node;
|
2024-10-22 01:55:31 +02:00
|
|
|
}
|
|
|
|
|
|
2024-10-22 03:07:11 +02:00
|
|
|
void removeSignal(int n){
|
|
|
|
|
signals.erase(signals.begin() + n);
|
2024-10-22 01:55:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void updateSignals(){
|
|
|
|
|
auto last = std::chrono::steady_clock::now();
|
|
|
|
|
while(loop){
|
2024-10-25 02:43:41 +02:00
|
|
|
std::chrono::duration<double, std::micro> diff = std::chrono::steady_clock::now() - last;
|
|
|
|
|
if(diff.count() > 500){
|
2024-10-25 16:46:28 +02:00
|
|
|
mutex->lock();
|
2024-10-25 02:43:41 +02:00
|
|
|
if(play){
|
|
|
|
|
for(auto& s : signals){
|
|
|
|
|
s.direction = (s.next->position - s.position).norm();
|
|
|
|
|
s.update(diff.count());
|
|
|
|
|
if(s.position.dist(&s.next->position) < 1.0f) {
|
|
|
|
|
Node* n = cm->next(s.next, s.last);
|
|
|
|
|
|
|
|
|
|
if(n != s.next && n != nullptr) {
|
|
|
|
|
for(auto &m : s.next->midi_outs){
|
2024-10-25 16:41:37 +02:00
|
|
|
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);
|
2024-10-25 02:43:41 +02:00
|
|
|
}
|
|
|
|
|
s.last = s.next;
|
|
|
|
|
s.next = n;
|
2024-10-22 01:55:31 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-25 16:46:28 +02:00
|
|
|
midi.update();
|
|
|
|
|
mutex->unlock();
|
2024-10-22 01:55:31 +02:00
|
|
|
last = std::chrono::steady_clock::now();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawSignals(Vec2D<float> *mouse_pos, Camera2D *camera){
|
|
|
|
|
for(auto& s : signals){
|
|
|
|
|
s.draw(mouse_pos, camera);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|