static void RemoveProcessAfterState( StateModel& statemodel, const Process::ProcessModel& proc) { ProcessStateDataInterface* state = proc.startStateData(); if (!state) return; auto it = ossia::find_if(statemodel.followingProcesses(), [&](const auto& elt) { return state == &elt.process(); }); updateTreeWithRemovedProcess( statemodel.messages().rootNode(), proc.id(), ProcessPosition::Following); statemodel.sig_statesUpdated(); // TODO debug the need for this check if (it != statemodel.followingProcesses().end()) statemodel.followingProcesses().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 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(); }