LateReturn<> SCLang::InstallTemplate(const std::shared_ptr<ModuleTemplate> t){ Relay<> r; if(!t->has_sc_code) return r.Return(); SendOSCWithEmptyReply("/algaudioSC/installtemplate", "ss", t->GetFullID().c_str(), t->sc_code.c_str()).Then([=](){ installed_templates.insert(t->GetFullID()); std::cout << "Template " << t->GetFullID() << " installed." << std::endl; r.Return(); }); return r; }
LateReturn<std::shared_ptr<Module>> Canvas::CreateModule(std::string id){ Relay<std::shared_ptr<Module>> r; ModuleFactory::CreateNewInstance(id, shared_from_this()).Then([this,r](std::shared_ptr<Module> m){ modules.emplace(m); m->canvas = shared_from_this(); r.Return(m); }).Catch(r); return r; }
LateReturn<lo::Message> SCLang::SendOSCCustomWithLOReply(const std::string& path, const lo::Message &m){ Relay<lo::Message> r; if(!Config::Global().use_sc) return r; if(!osc) {std::cout << "WARNING: Failed to send OSC message to server, OSC not ready" << std::endl; return r;}// throw Exceptions::SCLangException("Failed to send OSC message to server, OSC not yet ready"); osc->Send(path, [=](lo::Message msg){ r.Return(msg); }, m); return r; }
LateReturn<std::shared_ptr<Canvas>> Canvas::CreateEmpty(std::shared_ptr<Canvas> parent){ Relay<std::shared_ptr<Canvas>> r; auto res = std::shared_ptr<Canvas>( new Canvas() ); res->parent = parent; auto parentgroup = (parent)? parent->GetGroup() : nullptr; if(Config::Global().use_sc){ Group::CreateNew( parentgroup ).Then([r,res](std::shared_ptr<Group> g){ res->group = g; std::cout << "New canvas group " << g->GetID() << std::endl; r.Return(res); }); }else{ std::cout << "Note: Using a FAKE group to create a new empty canvas" << std::endl; Group::CreateFake( parentgroup ).Then([r,res](std::shared_ptr<Group> g){ res->group = g; r.Return(res); }); } return r; }
LateReturn<> Subpatch::on_init_latereturn(){ Relay<> r; Sync s(5); auto parent = canvas.lock(); inlets.resize(4); bool fake = ! Config::Global().use_sc; Module::Inlet::Create("in1","Inlet 1",shared_from_this(),fake).Then([this,s](auto inlet){ inlets[0] = inlet; if(entrance) entrance->LinkOutput(0, inlet->bus->GetID()); s.Trigger(); }); Module::Inlet::Create("in2","Inlet 2",shared_from_this(),fake).Then([this,s](auto inlet){ inlets[1] = inlet; if(entrance) entrance->LinkOutput(1, inlet->bus->GetID()); s.Trigger(); }); Module::Inlet::Create("in3","Inlet 3",shared_from_this(),fake).Then([this,s](auto inlet){ inlets[2] = inlet; if(entrance) entrance->LinkOutput(2, inlet->bus->GetID()); s.Trigger(); }); Module::Inlet::Create("in4","Inlet 4",shared_from_this(),fake).Then([this,s](auto inlet){ inlets[3] = inlet; if(entrance) entrance->LinkOutput(3, inlet->bus->GetID()); s.Trigger(); }); s.WhenAll([r, this](){ if(modulegui) modulegui->OnInletsChanged(); r.Return(); }); Canvas::CreateEmpty(parent).Then([this,s](auto c){ c->owner_hint = this->shared_from_this(); internal_canvas = c; Sync s2(2); c->CreateModule("builtin/subentry").Then([this,s2](auto module){ module->position_in_canvas = Point2D(0,-300); s2.Trigger(); }); c->CreateModule("builtin/subexit").Then([this,s2](auto module){ module->position_in_canvas = Point2D(0,300); s2.Trigger(); }); s2.WhenAll([s](){s.Trigger();}); }); return r; }
LateReturn<lo::Message> SCLang::SendOSCWithLOReply(const std::string &path, std::string tag, ...){ Relay<lo::Message> r; if(!Config::Global().use_sc) return r; if(!osc) {std::cout << "WARNING: Failed to send OSC message to server, OSC not ready" << std::endl; return r;} // throw Exceptions::SCLangException("Failed to send OSC message to server, OSC not yet ready"); va_list q; va_start(q, tag); lo::Message m; std::string t = tag + "$$"; m.add_varargs(t, q); osc->Send(path, [=](lo::Message msg){ r.Return(msg); }, m); return r; }
LateReturn<> SubpatchExit::on_init_latereturn(){ Relay<> r; Sync s(4); // Check if parent canvas is managed by a subpatch. std::shared_ptr<Module> owner = canvas.lock()->owner_hint; auto owner_subpatch = std::dynamic_pointer_cast<Subpatch>(owner); // If not, throw a DoNotWantToBeCreated exception. if(!owner_subpatch) {r.LateThrow<Exceptions::ModuleDoesNotWantToBeCreated>("This module can only be created inside a subpatch."); return r;} if(owner_subpatch->HasExit()) {r.LateThrow<Exceptions::ModuleDoesNotWantToBeCreated>("Currently it is not possible to create multiple exits inside the same subpatch."); return r;} // Otherwise link to that entrance. owner_subpatch->LinkToExit(std::static_pointer_cast<SubpatchExit>( shared_from_this() )); subpatch = owner_subpatch; // Create inlets. inlets.resize(4); bool fake = ! Config::Global().use_sc; Module::Inlet::Create("in1","Inlet 1",shared_from_this(),fake).Then([this,s](auto inlet){ inlets[0] = inlet; subpatch->LinkOutput(0, inlet->bus->GetID()); s.Trigger(); }); Module::Inlet::Create("in2","Inlet 2",shared_from_this(),fake).Then([this,s](auto inlet){ inlets[1] = inlet; subpatch->LinkOutput(1, inlet->bus->GetID()); s.Trigger(); }); Module::Inlet::Create("in3","Inlet 3",shared_from_this(),fake).Then([this,s](auto inlet){ inlets[2] = inlet; subpatch->LinkOutput(2, inlet->bus->GetID()); s.Trigger(); }); Module::Inlet::Create("in4","Inlet 4",shared_from_this(),fake).Then([this,s](auto inlet){ inlets[3] = inlet; subpatch->LinkOutput(3, inlet->bus->GetID()); s.Trigger(); }); s.WhenAll([r, this](){ if(modulegui) modulegui->OnInletsChanged(); r.Return(); }); return r; }