static void AddProcessAfterState(StateModel& statemodel, const Process::ProcessModel& proc) { ProcessStateDataInterface* state = proc.startStateData(); if (!state) return; auto next_proc_fun = [&](const State::MessageList& ml) { auto& messages = statemodel.messages(); for (const ProcessStateWrapper& prev_proc : statemodel.previousProcesses()) { prev_proc.process().setMessages(ml, messages.rootNode()); } updateTreeWithMessageList( messages.rootNode(), ml, proc.id(), ProcessPosition::Following); statemodel.sig_statesUpdated(); }; statemodel.followingProcesses().emplace_back(state); auto& wrapper = statemodel.followingProcesses().back(); QObject::connect( state, &ProcessStateDataInterface::messagesChanged, &wrapper, next_proc_fun); next_proc_fun(state->messages()); }
void ProcessModel::on_processRemoved(const Process::ProcessModel & proc) { auto proc_id = proc.id(); auto fac = iscore::AppContext().components.factory<Audio::AudioStreamEngine::ProcessComponentFactoryList>().factory(proc); if(!fac) return; bool in = fac->hasInput(); bool out = fac->hasOutput(); if(!in && out) { auto it = ossia::find(m_dataProcesses, proc_id); if(it != m_dataProcesses.end()) m_dataProcesses.erase(it); } else if(in && out) { auto it = ossia::find(m_fxProcesses, proc_id); if(it != m_fxProcesses.end()) m_fxProcesses.erase(it); } else if(in && !out) { auto it = ossia::find(m_sendProcesses, proc_id); if(it != m_sendProcesses.end()) m_sendProcesses.erase(it); } else { // send, mix return; } for (auto it = m_routings.begin(); it != m_routings.end(); ) { if ((*it).in == proc.id() || (*it).out == proc.id()) { it = m_routings.erase(it); } else { ++ it; } } emit structureChanged(); }
static void RemoveProcessBeforeState( StateModel& statemodel, const Process::ProcessModel& proc) { ProcessStateDataInterface* state = proc.endStateData(); if (!state) return; auto it = ossia::find_if(statemodel.previousProcesses(), [&](const auto& elt) { return state == &elt.process(); }); updateTreeWithRemovedProcess( statemodel.messages().rootNode(), proc.id(), ProcessPosition::Previous); statemodel.sig_statesUpdated(); // TODO debug the need for this check if (it != statemodel.previousProcesses().end()) statemodel.previousProcesses().erase(it); }
static void AddProcessBeforeState( StateModel& statemodel, const Process::ProcessModel& proc) { // TODO this should be fused with the notion of State Process. ProcessStateDataInterface* state = proc.endStateData(); if (!state) return; auto prev_proc_fun = [&](const State::MessageList& ml) { // TODO have some collapsing between all the processes of a state // NOTE how to prevent these states from being played // twice ? mark them ? // TODO which one should be sent ? the ones // from the process ? auto& messages = statemodel.messages(); for (const ProcessStateWrapper& next_proc : statemodel.followingProcesses()) { next_proc.process().setMessages(ml, messages.rootNode()); } updateTreeWithMessageList( messages.rootNode(), ml, proc.id(), ProcessPosition::Previous); statemodel.sig_statesUpdated(); }; statemodel.previousProcesses().emplace_back(state); auto& wrapper = statemodel.previousProcesses().back(); QObject::connect( state, &ProcessStateDataInterface::messagesChanged, &wrapper, prev_proc_fun); prev_proc_fun(state->messages()); }
void SlotModel::on_deleteSharedProcessModel( const Process::ProcessModel& proc) { using namespace std; auto it = find_if(begin(layers), end(layers), [id = proc.id()](const Process::LayerModel& lm) { return lm.processModel().id() == id; }); if(it != end(layers)) { layers.remove((*it).id()); } }
void ConstraintElement::on_processAdded( const Process::ProcessModel& iscore_proc) // TODO ProcessExecutionView { // The DocumentPlugin creates the elements in the processes. // TODO maybe have an execution_view template on processes, that // gives correct const / non_const access ? auto proc = const_cast<Process::ProcessModel*>(&iscore_proc); auto fac = m_ctx.processes.factory(*proc, m_ctx.sys, m_ctx.doc); if(fac) { auto plug = fac->make(*this, *proc, m_ctx, getStrongId(iscore_proc.components), this); if(plug) { auto id = iscore_proc.id(); std::unique_ptr<ProcessWrapper> wp; if(proc->useParentDuration()) { wp = std::make_unique<BasicProcessWrapper>( m_ossia_constraint, plug->OSSIAProcess(), iscore::convert::time(plug->iscoreProcess().duration()), m_iscore_constraint.looping() ); } else { wp = std::make_unique<LoopingProcessWrapper>( m_ossia_constraint, plug->OSSIAProcess(), iscore::convert::time(plug->iscoreProcess().duration()), m_iscore_constraint.looping()) ; } m_processes.insert( std::make_pair( id, OSSIAProcess(plug, std::move(wp)))); } } }
void ProcessModel::on_processAdded(const Process::ProcessModel & proc) { auto fac = iscore::AppContext().components.factory<Audio::AudioStreamEngine::ProcessComponentFactoryList>().factory(proc); if(!fac) return; bool in = fac->hasInput(); bool out = fac->hasOutput(); auto proc_id = proc.id(); if(!in && out) { m_dataProcesses.push_back({proc_id, 1.0}); for(const auto& fx : m_fxProcesses) { m_routings.insert(Routing{proc_id, fx.process, 1.0}); } for(const auto& send : m_sendProcesses) { m_routings.insert(Routing{proc_id, send, 1.0}); } } else if(in && out) { // For now we forbid mixing FX each into another. m_fxProcesses.push_back({proc_id, 1.0}); for(const auto& other : m_dataProcesses) { m_routings.insert(Routing{other.process, proc_id, 1.0}); } for(const auto& other : m_fxProcesses) { // By default we disable mixing Fx's into each other // to prevent cycles. m_routings.insert(Routing{other.process, proc_id, 1.0, false}); m_routings.insert(Routing{proc_id, other.process, 1.0, false}); } for(const auto& send : m_sendProcesses) { m_routings.insert(Routing{proc_id, send, 1.0}); } } else if(in && !out) { m_sendProcesses.push_back(proc_id); for(const auto& other : m_dataProcesses) { m_routings.insert(Routing{other.process, proc_id, 1.0}); } for(const auto& other : m_fxProcesses) { m_routings.insert(Routing{other.process, proc_id, 1.0}); } } else { // mix return; } emit structureChanged(); }