#pragma once #include #include #include "interaction-manager.h" #include "nlohmann/json.hpp" #include "datatypes.h" #include "canvas.h" #include "graph-manager.h" #include "midi-node.h" #include "node.h" #include "raylib.h" #include "signal-manager.h" #include "state.h" #include "ui.h" #include using json = nlohmann::json; namespace VISEQ::APP { class AppManager{ public: AppManager() : im(gm->getPtr(), sm->getPtr(), canvas), ui(sm->getPtr(), gm->getPtr()) {} std::mutex mutex; std::shared_ptr state = APP::State::get(); std::shared_ptr canvas = std::make_shared(); std::shared_ptr gm = std::make_shared(); std::shared_ptr sm = std::make_shared(gm->getPtr(), &mutex); VISEQ::INTERACTION::InteractionManager im; UI::AppUI ui; NLOHMANN_DEFINE_TYPE_INTRUSIVE(AppManager, gm, sm); void init(){ canvas->camera.target = (Vector2){ state->settings.width/2.0f, state->settings.height/2.0f }; canvas->camera.offset = (Vector2){ state->settings.width/2.0f, state->settings.height/2.0f }; canvas->camera.rotation = 0.0f; canvas->camera.zoom = 1.0f; } void close(){ std::ofstream file("state.json"); file << json(*this); std::cout << std::setw(4) << json(*this) << std::endl; } void startSignals(){ sm->startSignalThread(); } void loadState(){ if(std::filesystem::exists("state.json")){ std::ifstream f("state.json"); json graph = json::parse(f); for(auto n : graph.at("gm").at("nodes")){ std::cout << "object? " << n << std::endl; if(n.is_object()){ std::cout << "nodeType = " << n.at("nodeType").get() << std::endl; if(n.at("nodeType").get() == NodeType::MIDINODE) gm->addNode(n.template get>()); if(n.at("nodeType").get() == NodeType::CONFIGNODE) gm->addNode(n.template get>()); } } int highest_id = 0; Node hid; for(auto n : graph.at("gm").at("nodes")){ std::cout << n << std::endl; if(n.is_object()){ Node mn = n.template get(); if(mn.id > highest_id) { highest_id = mn.id; hid = mn; } } } for(auto e : graph.at("gm").at("edges")){ if(e.at("id") > highest_id){ highest_id = e.at("id"); } } for(auto e : graph.at("gm").at("edges")){ int start_id = e.at("start").get(); int end_id = e.at("end").get(); VEC_WPTR_Node start = gm->getNodesByID(start_id); VEC_WPTR_Node end = gm->getNodesByID(end_id); if(!start.empty() && !end.empty()) { std::cout << std::format("connection {} to {}", start_id, end_id) << std::endl; gm->addConnection(start.front(), end.front()); } } gm->lastEdge().lock()->newId(highest_id); for(auto s : graph.at("sm").at("signals")){ int start_id = s.at("start").get(); int next_id = s.at("next").get(); int last_id = s.at("last").get(); std::shared_ptr ms = s; VEC_WPTR_Node start = gm->getNodesByID(start_id); VEC_WPTR_Node last = gm->getNodesByID(last_id); VEC_WPTR_Node next = gm->getNodesByID(next_id); ms->start = start.front(); ms->next = next.front(); ms->last = last.front(); sm->signals.push_back(ms); std::cout << std::format("adding signal with start node {}", start_id) << std::endl; } } else { for(int i = 0; i < 4; ++i){ gm->createMidiNode(Vec2Df{(float)i * state->settings.grid*4 + 7 * state->settings.grid, 2 * state->settings.grid*4}); } for(int i = 3; i >= 0; --i){ gm->createMidiNode(Vec2Df{(float)i * state->settings.grid*4 + 7 * state->settings.grid, 3 * state->settings.grid*4}); } for(int i = 0; i < 8; ++i){ gm->addConnection(gm->getNode(i), gm->getNode((i+1) % 8)); } sm->addSignalAtNode(gm->getFirstNode()); } } void updateMidiPorts(){ for(auto& n : gm->getMidiNodes()){ auto nc = std::dynamic_pointer_cast(n.lock()); for(auto& mo : sm->midi.midi_out_ports){ if(!nc->midi_outs.contains(mo.number) && mo.enabled){ nc->midi_outs[mo.number] = {mo.number, mo.port.port_name, false}; } if(nc->midi_outs.contains(mo.number) && !mo.enabled){ nc->midi_outs.erase(mo.number); } } } } void update(){ state->update(canvas->camera); canvas->update(); gm->update(); mutex.lock(); updateMidiPorts(); mutex.unlock(); im.update(); } void draw(){ BeginDrawing(); ClearBackground((Color){46,46,46}); canvas->drawStart(); canvas->draw(); gm->drawNodes(SCREEN_MOUSE, canvas->camera); gm->drawEdges(SCREEN_MOUSE, canvas->camera); sm->drawSignals(SCREEN_MOUSE, canvas->camera); im.draw(); canvas->drawEnd(); drawUI(); EndDrawing(); } void drawUI(){ mutex.lock(); ui.draw(SCREEN_MOUSE, canvas->camera); mutex.unlock(); } }; }