#pragma once #include "datatypes.h" #include "graph-manager.h" #include "midi-node.h" #include "signal.h" #include "midi.h" #include #include #include class SignalManager{ public: SignalManager() {} SignalManager(GraphManager *gm, std::mutex *mutex) : mutex(mutex), gm(gm) {} Midi midi; std::mutex *mutex; GraphManager *gm; VEC_SPTR_Signal signals; bool loop = true; 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{0.1, 0.1}; s->next = s->start; s->last = s->start; } gm->reset(); } void startSignalThread(){ std::thread t1(&SignalManager::updateSignals, this); t1.detach(); } void stopSignalThread(){ loop = false; } void addSignalAtNode(SPTR_Node node){ Color c = {(unsigned char)(20 + (rand() % 200)), 100, (unsigned char)(20 + (int)(rand() % 200)), 200}; signals.emplace_back(std::make_shared(node->position + Vec2D{0.5f, 0.5f}, 8.0f, 0, c)); // position + 1 or else it does not render. why? no idea! signals.back()->next = node; signals.back()->last = node; signals.back()->start = node; } void removeSignal(int n){ signals.erase(signals.begin() + n); } void updateSignals(){ auto last = std::chrono::high_resolution_clock::now(); while(loop){ std::chrono::duration diff = std::chrono::high_resolution_clock::now() - last; if((int)diff.count() >= 250){ mutex->lock(); 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) < 0.6f) { SPTR_Node next_node = gm->next(s->next, s->last); s->next->trigger(); if(next_node != s->next && next_node != SPTR_Node(nullptr) && s->next->getNodeType() == NodeType::MIDINODE) { auto midinode = std::dynamic_pointer_cast(s->next); for(auto &m : midinode->midi_outs){ if(m.second.enabled) { if(midinode->send_note) midi.note(m.second.i, midinode->midi_note_channel, midinode->midi_note, midinode->midi_velocity, midinode->midi_gate); if(midinode->send_cc) midi.cc(m.second.i, midinode->midi_cc_channel, midinode->midi_cc, midinode->midi_cc_value); if(midinode->send_pitch_bend) midi.pitch_bend(m.second.i, midinode->midi_pitch_bend_channel, midinode->midi_pitch_bend); } } s->last = s->next; s->next = next_node; } } } } midi.update(); mutex->unlock(); last = std::chrono::high_resolution_clock::now(); } } } void drawSignals(Vec2D mouse_pos, Camera2D camera){ for(auto s : signals){ mutex->lock(); s->draw(mouse_pos, camera); mutex->unlock(); } } };