1
Fork 0

Remove old and unused Actions class

This commit is contained in:
gvnnz 2023-06-14 22:45:50 +02:00
parent 930da9752d
commit ce339e2d0f
3 changed files with 0 additions and 487 deletions

View File

@ -62,7 +62,6 @@ list(APPEND SOURCES
src/core/patch.cpp
src/core/actions/actionFactory.cpp
src/core/actions/actionRecorder.cpp
src/core/actions/actions.cpp
src/core/mixer.cpp
src/core/jackSynchronizer.cpp
src/core/midiSynchronizer.cpp

View File

@ -1,322 +0,0 @@
/* -----------------------------------------------------------------------------
*
* Giada - Your Hardcore Loopmachine
*
* -----------------------------------------------------------------------------
*
* Copyright (C) 2010-2023 Giovanni A. Zuliani | Monocasual Laboratories
*
* This file is part of Giada - Your Hardcore Loopmachine.
*
* Giada - Your Hardcore Loopmachine is free software: you can
* redistribute it and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* Giada - Your Hardcore Loopmachine is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------- */
#include "core/actions/actions.h"
#include "core/actions/action.h"
#include "core/actions/actionFactory.h"
#include "core/idManager.h"
#include "core/model/model.h"
#include "utils/log.h"
#include <algorithm>
#include <cassert>
#include <memory>
namespace giada::m
{
Actions::Actions(model::Model& model)
: m_model(model)
{
}
/* -------------------------------------------------------------------------- */
void Actions::clearAll()
{
model::DataLock lock = m_model.lockData();
m_model.getAllActions().clear();
}
/* -------------------------------------------------------------------------- */
void Actions::clearChannel(ID channelId)
{
removeIf([=](const Action& a) { return a.channelId == channelId; });
}
/* -------------------------------------------------------------------------- */
void Actions::clearActions(ID channelId, int type)
{
removeIf([=](const Action& a) {
return a.channelId == channelId && a.event.getStatus() == type;
});
}
/* -------------------------------------------------------------------------- */
void Actions::deleteAction(ID id)
{
removeIf([=](const Action& a) { return a.id == id; });
}
void Actions::deleteAction(ID currId, ID nextId)
{
removeIf([=](const Action& a) { return a.id == currId || a.id == nextId; });
}
/* -------------------------------------------------------------------------- */
void Actions::updateKeyFrames(std::function<Frame(Frame old)> f)
{
Map temp;
/* Copy all existing actions in local map by cloning them, with just a
difference: they have a new frame value. */
for (const auto& [oldFrame, actions] : m_model.getAllActions())
{
Frame newFrame = f(oldFrame);
for (const Action& a : actions)
{
Action copy = a;
copy.frame = newFrame;
temp[newFrame].push_back(copy);
}
G_DEBUG("{} -> {}", oldFrame, newFrame);
}
updateMapPointers(temp);
model::DataLock lock = m_model.lockData();
m_model.getAllActions() = std::move(temp);
}
/* -------------------------------------------------------------------------- */
void Actions::updateEvent(ID id, MidiEvent e)
{
model::DataLock lock = m_model.lockData();
findAction(m_model.getAllActions(), id)->event = e;
}
/* -------------------------------------------------------------------------- */
void Actions::updateSiblings(ID id, ID prevId, ID nextId)
{
model::DataLock lock = m_model.lockData();
Action* pcurr = findAction(m_model.getAllActions(), id);
Action* pprev = findAction(m_model.getAllActions(), prevId);
Action* pnext = findAction(m_model.getAllActions(), nextId);
pcurr->prev = pprev;
pcurr->prevId = pprev->id;
pcurr->next = pnext;
pcurr->nextId = pnext->id;
if (pprev != nullptr)
{
pprev->next = pcurr;
pprev->nextId = pcurr->id;
}
if (pnext != nullptr)
{
pnext->prev = pcurr;
pnext->prevId = pcurr->id;
}
}
/* -------------------------------------------------------------------------- */
bool Actions::hasActions(ID channelId, int type) const
{
for (const auto& [frame, actions] : m_model.getAllActions())
for (const Action& a : actions)
if (a.channelId == channelId && (type == 0 || type == a.event.getStatus()))
return true;
return false;
}
/* -------------------------------------------------------------------------- */
Action Actions::rec(ID channelId, Frame frame, MidiEvent event)
{
/* Skip duplicates. */
if (exists(channelId, frame, event))
return {};
Action a = actionFactory::makeAction(0, channelId, frame, event);
/* If key frame doesn't exist yet, the [] operator in std::map is smart
enough to insert a new item first. No plug-in data for now. */
model::DataLock lock = m_model.lockData();
m_model.getAllActions()[frame].push_back(a);
updateMapPointers(m_model.getAllActions());
return a;
}
/* -------------------------------------------------------------------------- */
void Actions::rec(std::vector<Action>& actions)
{
if (actions.size() == 0)
return;
model::DataLock lock = m_model.lockData();
Map& map = m_model.getAllActions();
for (const Action& a : actions)
if (!exists(a.channelId, a.frame, a.event, map))
map[a.frame].push_back(a);
updateMapPointers(map);
}
/* -------------------------------------------------------------------------- */
void Actions::rec(ID channelId, Frame f1, Frame f2, MidiEvent e1, MidiEvent e2)
{
model::DataLock lock = m_model.lockData();
Map& map = m_model.getAllActions();
map[f1].push_back(actionFactory::makeAction(0, channelId, f1, e1));
map[f2].push_back(actionFactory::makeAction(0, channelId, f2, e2));
Action* a1 = findAction(map, map[f1].back().id);
Action* a2 = findAction(map, map[f2].back().id);
a1->nextId = a2->id;
a2->prevId = a1->id;
updateMapPointers(map);
}
/* -------------------------------------------------------------------------- */
const std::vector<Action>* Actions::getActionsOnFrame(Frame frame) const
{
if (m_model.getAllActions().count(frame) == 0)
return nullptr;
return &m_model.getAllActions().at(frame);
}
/* -------------------------------------------------------------------------- */
Action Actions::getClosestAction(ID channelId, Frame f, int type) const
{
Action out = {};
forEachAction([&](const Action& a) {
if (a.event.getStatus() != type || a.channelId != channelId)
return;
if (!out.isValid() || (a.frame <= f && a.frame > out.frame))
out = a;
});
return out;
}
/* -------------------------------------------------------------------------- */
std::vector<Action> Actions::getActionsOnChannel(ID channelId) const
{
std::vector<Action> out;
forEachAction([&](const Action& a) {
if (a.channelId == channelId)
out.push_back(a);
});
return out;
}
/* -------------------------------------------------------------------------- */
void Actions::forEachAction(std::function<void(const Action&)> f) const
{
for (auto& [_, actions] : m_model.getAllActions())
for (const Action& action : actions)
f(action);
}
/* -------------------------------------------------------------------------- */
Action* Actions::findAction(Map& src, ID id)
{
for (auto& [frame, actions] : src)
for (Action& a : actions)
if (a.id == id)
return &a;
assert(false);
return nullptr;
}
/* -------------------------------------------------------------------------- */
void Actions::updateMapPointers(Map& src)
{
for (auto& kv : src)
{
for (Action& action : kv.second)
{
if (action.nextId != 0)
action.next = findAction(src, action.nextId);
if (action.prevId != 0)
action.prev = findAction(src, action.prevId);
}
}
}
/* -------------------------------------------------------------------------- */
void Actions::optimize(Map& map)
{
for (auto it = map.cbegin(); it != map.cend();)
it->second.size() == 0 ? it = map.erase(it) : ++it;
}
/* -------------------------------------------------------------------------- */
void Actions::removeIf(std::function<bool(const Action&)> f)
{
model::DataLock lock = m_model.lockData();
Map& map = m_model.getAllActions();
for (auto& [frame, actions] : map)
actions.erase(std::remove_if(actions.begin(), actions.end(), f), actions.end());
optimize(map);
updateMapPointers(map);
}
/* -------------------------------------------------------------------------- */
bool Actions::exists(ID channelId, Frame frame, const MidiEvent& event, const Map& target) const
{
for (const auto& [_, actions] : target)
for (const Action& a : actions)
if (a.channelId == channelId && a.frame == frame && a.event.getRaw() == event.getRaw())
return true;
return false;
}
/* -------------------------------------------------------------------------- */
bool Actions::exists(ID channelId, Frame frame, const MidiEvent& event) const
{
return exists(channelId, frame, event, m_model.getAllActions());
}
} // namespace giada::m

View File

@ -1,164 +0,0 @@
/* -----------------------------------------------------------------------------
*
* Giada - Your Hardcore Loopmachine
*
* -----------------------------------------------------------------------------
*
* Copyright (C) 2010-2023 Giovanni A. Zuliani | Monocasual Laboratories
*
* This file is part of Giada - Your Hardcore Loopmachine.
*
* Giada - Your Hardcore Loopmachine is free software: you can
* redistribute it and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* Giada - Your Hardcore Loopmachine is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------- */
#ifndef G_ACTIONS_H
#define G_ACTIONS_H
#include "action.h"
#include "core/idManager.h"
#include "core/midiEvent.h"
#include "core/patch.h"
#include "core/types.h"
#include <functional>
#include <map>
#include <memory>
#include <vector>
namespace giada::m::model
{
class Model;
}
namespace giada::m
{
class Actions
{
public:
using Map = std::map<Frame, std::vector<Action>>;
Actions(model::Model& model);
/* forEachAction
Applies a read-only callback on each action recorded. NEVER do anything
inside the callback that might alter the ActionMap. */
void forEachAction(std::function<void(const Action&)> f) const;
/* getActionsOnChannel
Returns a vector of actions belonging to channel 'ch'. */
std::vector<Action> getActionsOnChannel(ID channelId) const;
/* getClosestAction
Given a frame 'f' returns the closest action. */
Action getClosestAction(ID channelId, Frame f, int type) const;
/* getActionsOnFrame
Returns a pointer to a vector of actions recorded on frame 'f', or nullptr
if the frame has no actions. */
const std::vector<Action>* getActionsOnFrame(Frame f) const;
/* hasActions
Checks if the channel has at least one action recorded. */
bool hasActions(ID channelId, int type = 0) const;
/* clearAll
Deletes all recorded actions. */
void clearAll();
/* clearChannel
Clears all actions from a channel. */
void clearChannel(ID channelId);
/* clearActions
Clears the actions by type from a channel. */
void clearActions(ID channelId, int type);
/* deleteAction (1)
Deletes a specific action. */
void deleteAction(ID id);
/* deleteAction (2)
Deletes a specific pair of actions. Useful for composite stuff (i.e. MIDI). */
void deleteAction(ID currId, ID nextId);
/* updateKeyFrames
Update all the key frames in the internal map of actions, according to a
lambda function 'f'. */
void updateKeyFrames(std::function<Frame(Frame old)> f);
/* updateEvent
Changes the event in action 'a'. */
void updateEvent(ID id, MidiEvent e);
/* updateSiblings
Changes previous and next actions in action with id 'id'. Mostly used for
chained actions such as envelopes. */
void updateSiblings(ID id, ID prevId, ID nextId);
/* rec (1)
Records an action and returns it. Used by the Action Editor. */
Action rec(ID channelId, Frame frame, MidiEvent e);
/* rec (2)
Transfer a vector of actions into the current ActionMap. This is called by
recordHandler when a live session is over and consolidation is required. */
void rec(std::vector<Action>& actions);
/* rec (3)
Records two actions on channel 'channel'. Useful when recording composite
actions in the Action Editor. */
void rec(ID channelId, Frame f1, Frame f2, MidiEvent e1, MidiEvent e2);
private:
bool exists(ID channelId, Frame frame, const MidiEvent& event, const Map& target) const;
bool exists(ID channelId, Frame frame, const MidiEvent& event) const;
Action* findAction(Map& src, ID id);
/* updateMapPointers
Updates all prev/next actions pointers into the action map. This is required
after an action has been recorded, since pushing back new actions in a Action
vector makes it reallocating the existing ones. */
void updateMapPointers(Map& src);
/* optimize
Removes frames without actions. */
void optimize(Map& map);
void removeIf(std::function<bool(const Action&)> f);
model::Model& m_model;
};
} // namespace giada::m
#endif