1
Fork 0

m::model::Actions is now part of model::Layout, use it in ActionRecorder class

This commit is contained in:
gvnnz 2023-06-14 22:45:31 +02:00
parent 255d19988d
commit 930da9752d
11 changed files with 62 additions and 46 deletions

View File

@ -36,7 +36,7 @@ IdManager actionId_;
/* -------------------------------------------------------------------------- */
const Action* getActionPtrById_(int id, const Actions::Map& source)
const Action* getActionPtrById_(int id, const model::Actions::Map& source)
{
for (const auto& [_, actions] : source)
for (const Action& action : actions)
@ -81,9 +81,9 @@ ID getNewActionId()
/* -------------------------------------------------------------------------- */
Actions::Map deserializeActions(const std::vector<Patch::Action>& pactions)
model::Actions::Map deserializeActions(const std::vector<Patch::Action>& pactions)
{
Actions::Map out;
model::Actions::Map out;
/* First pass: add actions with no relationship, that is with no prev/next
pointers filled in. */
@ -117,7 +117,7 @@ Actions::Map deserializeActions(const std::vector<Patch::Action>& pactions)
/* -------------------------------------------------------------------------- */
std::vector<Patch::Action> serializeActions(const Actions::Map& actions)
std::vector<Patch::Action> serializeActions(const model::Actions::Map& actions)
{
std::vector<Patch::Action> out;
for (const auto& kv : actions) // TODO - const auto& [_, actionsInFrame]

View File

@ -28,8 +28,8 @@
#define G_ACTION_FACTORY_H
#include "core/actions/action.h"
#include "core/actions/actions.h"
#include "core/idManager.h"
#include "core/model/actions.h"
#include "core/patch.h"
namespace giada::m::actionFactory
@ -53,8 +53,8 @@ ID getNewActionId();
/* (de)serializeActions
Creates new Actions given the patch raw data and vice versa. */
Actions::Map deserializeActions(const std::vector<Patch::Action>&);
std::vector<Patch::Action> serializeActions(const Actions::Map&);
model::Actions::Map deserializeActions(const std::vector<Patch::Action>&);
std::vector<Patch::Action> serializeActions(const model::Actions::Map&);
} // namespace giada::m::actionFactory
#endif

View File

@ -27,8 +27,8 @@
#include "core/actions/actionRecorder.h"
#include "core/actions/action.h"
#include "core/actions/actionFactory.h"
#include "core/actions/actions.h"
#include "core/const.h"
#include "core/model/actions.h"
#include "core/model/model.h"
#include "core/patch.h"
#include "utils/log.h"
@ -52,7 +52,6 @@ constexpr int MAX_LIVE_RECS_CHUNK = 128;
ActionRecorder::ActionRecorder(model::Model& m)
: m_model(m)
, m_actions(m)
{
m_liveActions.reserve(MAX_LIVE_RECS_CHUNK);
}
@ -63,7 +62,8 @@ void ActionRecorder::reset()
{
m_liveActions.clear();
actionFactory::reset();
m_actions.clearAll();
m_model.get().actions.clearAll();
m_model.swap(model::SwapType::NONE);
}
/* -------------------------------------------------------------------------- */
@ -82,7 +82,7 @@ void ActionRecorder::updateBpm(float ratio, int quantizerStep)
if (ratio == 1.0f)
return;
m_actions.updateKeyFrames([=](Frame old) {
m_model.get().actions.updateKeyFrames([=](Frame old) {
/* The division here cannot be precise. A new frame can be 44099 and the
quantizer set to 44100. That would mean two recs completely useless. So we
compute a reject value ('delta'): if it's lower than 6 frames the new frame
@ -96,6 +96,8 @@ void ActionRecorder::updateBpm(float ratio, int quantizerStep)
}
return frame;
});
m_model.swap(model::SwapType::NONE);
}
/* -------------------------------------------------------------------------- */
@ -107,7 +109,8 @@ void ActionRecorder::updateSamplerate(int systemRate, int patchRate)
float ratio = systemRate / (float)patchRate;
m_actions.updateKeyFrames([=](Frame old) { return floorf(old * ratio); });
m_model.get().actions.updateKeyFrames([=](Frame old) { return floorf(old * ratio); });
m_model.swap(model::SwapType::NONE);
}
/* -------------------------------------------------------------------------- */
@ -118,7 +121,7 @@ bool ActionRecorder::cloneActions(ID channelId, ID newChannelId)
std::vector<Action> actions;
std::unordered_map<ID, ID> map; // Action ID mapper, old -> new
m_actions.forEachAction([&](const Action& a) {
m_model.get().actions.forEachAction([&](const Action& a) {
if (a.channelId != channelId)
return;
@ -144,8 +147,7 @@ bool ActionRecorder::cloneActions(ID channelId, ID newChannelId)
a.nextId = map.at(a.nextId);
}
m_actions.rec(actions);
m_model.get().actions.rec(actions);
m_model.get().channels.get(newChannelId).hasActions = true;
m_model.swap(model::SwapType::HARD);
@ -282,6 +284,8 @@ void ActionRecorder::deleteEnvelopeAction(ID channelId, const Action& a)
updateSiblings(a3.id, a1.id, a3next.id);
deleteAction(channelId, a.id);
}
m_model.swap(model::SwapType::SOFT);
}
/* -------------------------------------------------------------------------- */
@ -319,6 +323,8 @@ void ActionRecorder::updateEnvelopeAction(ID channelId, const Action& a, Frame f
deleteEnvelopeAction(channelId, a);
recordEnvelopeAction(channelId, f, value, lastFrameInLoop);
}
m_model.swap(model::SwapType::SOFT);
}
/* -------------------------------------------------------------------------- */
@ -327,7 +333,6 @@ void ActionRecorder::updateVelocity(const Action& a, int value)
{
MidiEvent event(a.event);
event.setVelocity(value);
updateEvent(a.id, event);
}
@ -338,7 +343,8 @@ std::unordered_set<ID> ActionRecorder::consolidate()
for (auto it = m_liveActions.begin(); it != m_liveActions.end(); ++it)
consolidate(*it, it - m_liveActions.begin()); // Pass current index
m_actions.rec(m_liveActions);
m_model.get().actions.rec(m_liveActions);
m_model.swap(model::SwapType::SOFT);
std::unordered_set<ID> out;
for (const Action& action : m_liveActions)
@ -356,7 +362,7 @@ void ActionRecorder::clearAllActions()
ch.hasActions = false;
m_model.swap(model::SwapType::HARD);
m_actions.clearAll();
m_model.get().actions.clearAll();
}
/* -------------------------------------------------------------------------- */
@ -455,73 +461,76 @@ void ActionRecorder::recordNonFirstEnvelopeAction(ID channelId, Frame frame, int
const std::vector<Action>* ActionRecorder::getActionsOnFrame(Frame f) const
{
return m_actions.getActionsOnFrame(f);
return m_model.get().actions.getActionsOnFrame(f);
}
bool ActionRecorder::hasActions(ID channelId, int type) const
{
return m_actions.hasActions(channelId, type);
return m_model.get().actions.hasActions(channelId, type);
}
Action ActionRecorder::getClosestAction(ID channelId, Frame f, int type) const
{
return m_actions.getClosestAction(channelId, f, type);
return m_model.get().actions.getClosestAction(channelId, f, type);
}
std::vector<Action> ActionRecorder::getActionsOnChannel(ID channelId) const
{
return m_actions.getActionsOnChannel(channelId);
return m_model.get().actions.getActionsOnChannel(channelId);
}
void ActionRecorder::clearChannel(ID channelId)
{
m_model.get().channels.get(channelId).hasActions = false;
m_actions.clearChannel(channelId);
m_model.get().actions.clearChannel(channelId);
}
void ActionRecorder::clearActions(ID channelId, int type)
{
m_actions.clearActions(channelId, type);
m_model.get().actions.clearActions(channelId, type);
m_model.get().channels.get(channelId).hasActions = hasActions(channelId);
m_model.swap(model::SwapType::HARD);
}
Action ActionRecorder::rec(ID channelId, Frame frame, MidiEvent e)
{
Action action = m_model.get().actions.rec(channelId, frame, e);
m_model.get().channels.get(channelId).hasActions = true;
return m_actions.rec(channelId, frame, e);
m_model.swap(model::SwapType::HARD);
return action;
}
void ActionRecorder::rec(ID channelId, Frame f1, Frame f2, MidiEvent e1, MidiEvent e2)
{
m_model.get().channels.get(channelId).hasActions = true;
return m_actions.rec(channelId, f1, f2, e1, e2);
m_model.get().actions.rec(channelId, f1, f2, e1, e2);
m_model.swap(model::SwapType::HARD);
}
void ActionRecorder::updateSiblings(ID id, ID prevId, ID nextId)
{
m_actions.updateSiblings(id, prevId, nextId);
m_model.get().actions.updateSiblings(id, prevId, nextId);
m_model.swap(model::SwapType::HARD);
}
void ActionRecorder::deleteAction(ID channelId, ID id)
{
m_actions.deleteAction(id);
m_model.get().actions.deleteAction(id);
m_model.get().channels.get(channelId).hasActions = hasActions(channelId);
m_model.swap(model::SwapType::HARD);
}
void ActionRecorder::deleteAction(ID channelId, ID currId, ID nextId)
{
m_actions.deleteAction(currId, nextId);
m_model.get().actions.deleteAction(currId, nextId);
m_model.get().channels.get(channelId).hasActions = hasActions(channelId);
m_model.swap(model::SwapType::HARD);
}
void ActionRecorder::updateEvent(ID id, MidiEvent e)
{
m_actions.updateEvent(id, e);
m_model.get().actions.updateEvent(id, e);
m_model.swap(model::SwapType::HARD);
}
} // namespace giada::m

View File

@ -27,8 +27,8 @@
#ifndef G_ACTION_RECORDER_H
#define G_ACTION_RECORDER_H
#include "core/actions/actions.h"
#include "core/midiEvent.h"
#include "core/model/model.h"
#include "core/types.h"
#include <cstddef>
#include <unordered_set>
@ -148,7 +148,6 @@ private:
void consolidate(const Action& a1, std::size_t i);
model::Model& m_model;
Actions m_actions;
std::vector<Action> m_liveActions;
};
} // namespace giada::m

View File

@ -27,14 +27,13 @@
#ifndef G_ACTION_EDITOR_API_H
#define G_ACTION_EDITOR_API_H
#include "core/actions/actions.h"
#include "core/model/actions.h"
#include "core/patch.h"
#include "core/types.h"
#include <vector>
namespace giada::m
{
struct Action;
class Engine;
class Sequencer;
class ActionRecorder;

View File

@ -137,6 +137,11 @@ bool Actions::hasActions(ID channelId, int type) const
/* -------------------------------------------------------------------------- */
Actions::Map& Actions::getAll() { return m_actions; }
const Actions::Map& Actions::getAll() const { return m_actions; }
/* -------------------------------------------------------------------------- */
Action Actions::rec(ID channelId, Frame frame, MidiEvent event)
{
/* Skip duplicates. */

View File

@ -69,6 +69,12 @@ public:
bool hasActions(ID channelId, int type = 0) const;
/* getAll
Returns a reference to the internal map. */
Map& getAll();
const Map& getAll() const;
/* clearAll
Deletes all recorded actions. */

View File

@ -268,7 +268,7 @@ LoadState Model::load(const Patch& patch, PluginManager& pluginManager, int samp
getAllChannelsShared().push_back(std::move(data.shared));
}
getAllActions() = actionFactory::deserializeActions(patch.actions);
layout.actions.getAll() = actionFactory::deserializeActions(patch.actions);
layout.sequencer.status = SeqStatus::STOPPED;
layout.sequencer.bars = patch.bars;
@ -347,7 +347,7 @@ void Model::store(Patch& patch, const std::string& projectPath)
for (const auto& p : getAllPlugins())
patch.plugins.push_back(pluginFactory::serializePlugin(*p));
patch.actions = actionFactory::serializeActions(getAllActions());
patch.actions = actionFactory::serializeActions(layout.actions.getAll());
for (auto& w : getAllWaves())
{
@ -404,7 +404,6 @@ bool Model::isLocked() const
std::vector<std::unique_ptr<Wave>>& Model::getAllWaves() { return m_shared.waves; };
std::vector<std::unique_ptr<Plugin>>& Model::getAllPlugins() { return m_shared.plugins; }
Actions::Map& Model::getAllActions() { return m_shared.actions; }
std::vector<std::unique_ptr<ChannelShared>>& Model::getAllChannelsShared() { return m_shared.channelsShared; }
/* -------------------------------------------------------------------------- */
@ -470,7 +469,7 @@ void Model::debug()
puts("model::shared.actions");
for (const auto& [frame, actions] : getAllActions())
for (const auto& [frame, actions] : get().actions.getAll())
{
fmt::print("\tframe: {}\n", frame);
for (const Action& a : actions)

View File

@ -29,6 +29,7 @@
#include "core/channels/channel.h"
#include "core/const.h"
#include "core/model/actions.h"
#include "core/model/behaviors.h"
#include "core/model/channels.h"
#include "core/model/kernelAudio.h"
@ -40,7 +41,6 @@
#include "core/wave.h"
#include "deps/mcl-atomic-swapper/src/atomic-swapper.hpp"
#include "deps/mcl-audio-buffer/src/audioBuffer.hpp"
#include "src/core/actions/actions.h"
#include "utils/vector.h"
#include <memory>
@ -64,6 +64,7 @@ struct Layout
Mixer mixer;
MidiIn midiIn;
Channels channels;
Actions actions;
Behaviors behaviors;
};
@ -173,7 +174,6 @@ public:
std::vector<std::unique_ptr<Wave>>& getAllWaves();
std::vector<std::unique_ptr<Plugin>>& getAllPlugins();
Actions::Map& getAllActions();
std::vector<std::unique_ptr<ChannelShared>>& getAllChannelsShared();
/* find[*]
@ -215,7 +215,6 @@ private:
std::vector<std::unique_ptr<ChannelShared>> channelsShared;
std::vector<std::unique_ptr<Wave>> waves;
Actions::Map actions;
std::vector<std::unique_ptr<Plugin>> plugins;
};

View File

@ -31,7 +31,7 @@
#include "core/sequencer.h"
#include "core/types.h"
#include "src/core/actions/actionRecorder.h"
#include "src/core/actions/actions.h"
#include "src/core/model/actions.h"
#include "utils/log.h"
namespace giada::m

View File

@ -1,8 +1,8 @@
#include "src/core/actions/actionRecorder.h"
#include "src/core/actions/action.h"
#include "src/core/actions/actions.h"
#include "src/core/channels/channelFactory.h"
#include "src/core/const.h"
#include "src/core/model/actions.h"
#include "src/core/model/model.h"
#include "src/core/types.h"
#include <catch2/catch.hpp>