2024-10-22 01:55:31 +02:00
# pragma once
# include "datatypes.h"
2024-10-30 14:55:24 +01:00
# include "graph-manager.h"
2024-10-22 01:55:31 +02:00
# include "signal.h"
# include "midi.h"
# include <chrono>
# include <thread>
class SignalManager {
public :
2024-10-25 16:41:37 +02:00
SignalManager ( ) { }
2024-10-30 14:55:24 +01:00
SignalManager ( GraphManager * gm , std : : mutex * mutex ) : mutex ( mutex ) , gm ( gm ) , nm ( nm ) { }
2024-10-22 01:55:31 +02:00
2024-10-25 16:41:37 +02:00
Midi midi ;
std : : mutex * mutex ;
2024-10-30 14:55:24 +01:00
GraphManager * gm ;
2024-10-22 01:55:31 +02:00
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 ) {
2024-10-30 14:55:24 +01:00
s . position = gm - > nodes [ s . start ] . position + Vec2D < float > { 0.1 , 0.1 } ;
2024-10-25 02:43:41 +02:00
s . next = s . start ;
s . last = s . start ;
}
2024-10-30 14:55:24 +01:00
gm - > reset ( ) ;
2024-10-25 02:43:41 +02:00
}
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-26 02:14:41 +02:00
void addSignalAtNode ( int node_id ) {
2024-10-27 00:40:57 +02:00
Color c = { ( unsigned char ) ( 20 + ( rand ( ) % 200 ) ) , 100 , ( unsigned char ) ( 20 + ( int ) ( rand ( ) % 200 ) ) , 200 } ;
2024-10-30 14:55:24 +01:00
signals . emplace ( signals . end ( ) , Signal ( gm - > nodes [ node_id ] . position . x + 1 , gm - > nodes [ node_id ] . position . y + 1 , 8.0f , 0 , c ) ) ; // position + 1 or else it does not render. why? no idea!
2024-10-26 02:14:41 +02:00
signals . back ( ) . next = node_id ;
signals . back ( ) . last = node_id ;
signals . back ( ) . start = node_id ;
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 ( ) {
2024-10-28 02:07:47 +01:00
auto last = std : : chrono : : high_resolution_clock : : now ( ) ;
2024-10-22 01:55:31 +02:00
while ( loop ) {
2024-10-28 02:07:47 +01:00
std : : chrono : : duration < double , std : : micro > diff = std : : chrono : : high_resolution_clock : : now ( ) - last ;
if ( ( int ) diff . count ( ) > = 250 ) {
2024-10-25 16:46:28 +02:00
mutex - > lock ( ) ;
2024-10-25 02:43:41 +02:00
if ( play ) {
for ( auto & s : signals ) {
2024-10-30 14:55:24 +01:00
s . direction = ( gm - > node ( s . next ) . position - s . position ) . norm ( ) ;
2024-10-25 02:43:41 +02:00
s . update ( diff . count ( ) ) ;
2024-10-30 14:55:24 +01:00
if ( s . position . dist ( & gm - > nodes [ s . next ] . position ) < 0.6f ) {
int n = gm - > next ( s . next , s . last ) ;
gm - > triggerNode ( s . next ) ;
2024-10-27 00:40:57 +02:00
2024-10-26 02:14:41 +02:00
if ( n ! = s . next & & n ! = - 1 ) {
2024-10-30 14:55:24 +01:00
for ( auto & m : gm - > nodes [ s . next ] . midi_outs ) {
2024-10-28 02:07:47 +01:00
if ( m . second . enabled ) {
2024-10-30 14:55:24 +01:00
if ( gm - > nodes [ s . next ] . send_note ) midi . note ( m . second . i , gm - > nodes [ s . next ] . midi_note_channel , gm - > nodes [ s . next ] . midi_note , gm - > nodes [ s . next ] . midi_velocity , gm - > nodes [ s . next ] . midi_gate ) ;
if ( gm - > nodes [ s . next ] . send_cc ) midi . cc ( m . second . i , gm - > nodes [ s . next ] . midi_cc_channel , gm - > nodes [ s . next ] . midi_cc , gm - > nodes [ s . next ] . midi_cc_value ) ;
if ( gm - > nodes [ s . next ] . send_pitch_bend ) midi . pitch_bend ( m . second . i , gm - > nodes [ s . next ] . midi_pitch_bend_channel , gm - > nodes [ s . next ] . midi_pitch_bend ) ;
2024-10-28 02:07:47 +01:00
}
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-28 02:07:47 +01:00
last = std : : chrono : : high_resolution_clock : : now ( ) ;
2024-10-22 01:55:31 +02:00
}
}
}
void drawSignals ( Vec2D < float > * mouse_pos , Camera2D * camera ) {
for ( auto & s : signals ) {
2024-10-28 02:07:47 +01:00
mutex - > lock ( ) ;
2024-10-22 01:55:31 +02:00
s . draw ( mouse_pos , camera ) ;
2024-10-28 02:07:47 +01:00
mutex - > unlock ( ) ;
2024-10-22 01:55:31 +02:00
}
}
} ;