Editor/ProjectModel: Use std::move where applicable

Amends the node interfaces to utilize std::move where applicable. This
allows avoiding some string copies altogether, as well as some IObj
atomic reference count increments and decrements.
This commit is contained in:
Lioncash 2019-08-25 23:50:10 -04:00
parent 9cc47aa803
commit a380d4da21
3 changed files with 181 additions and 112 deletions

View File

@ -1295,60 +1295,75 @@ void MainWindow::recursiveExpandAndSelectOutline(const QModelIndex& index) const
void MainWindow::newSubprojectAction() {
QString newName;
bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText(this, tr("New Subproject"), tr("What should this subproject be named?"),
QLineEdit::Normal, QString(), &ok);
if (!ok)
return;
}
ProjectModel::GroupNode* node = m_projectModel->newSubproject(newName);
if (!ok) {
return;
}
m_projectModel->newSubproject(std::move(newName));
}
void MainWindow::newSFXGroupAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group);
const QString groupName = getGroupName(group);
QString newName;
bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText(
this, tr("New SFX Group"), tr("What should the new SFX group in %1 be named?").arg(groupName),
QLineEdit::Normal,
QString::fromStdString(amuse::GroupId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Group)), &ok);
if (!ok)
return;
}
ProjectModel::SoundGroupNode* node = m_projectModel->newSoundGroup(group, newName);
if (node)
if (!ok) {
return;
}
ProjectModel::SoundGroupNode* node = m_projectModel->newSoundGroup(group, std::move(newName));
if (node) {
openEditor(node);
}
}
void MainWindow::newSongGroupAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group);
const QString groupName = getGroupName(group);
QString newName;
bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText(
this, tr("New Song Group"), tr("What should the new Song group in %1 be named?").arg(groupName),
QLineEdit::Normal,
QString::fromStdString(amuse::GroupId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Group)), &ok);
if (!ok)
return;
}
ProjectModel::SongGroupNode* node = m_projectModel->newSongGroup(group, newName);
if (node)
if (!ok) {
return;
}
ProjectModel::SongGroupNode* node = m_projectModel->newSongGroup(group, std::move(newName));
if (node) {
openEditor(node);
}
}
void MainWindow::newSoundMacroAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group);
const QString groupName = getGroupName(group);
QString newName;
const SoundMacroTemplateEntry* templ = nullptr;
int result = QDialog::Accepted;
while (result == QDialog::Accepted && newName.isEmpty()) {
NewSoundMacroDialog dialog(groupName, this);
dialog.setWindowModality(Qt::WindowModal);
@ -1356,85 +1371,108 @@ void MainWindow::newSoundMacroAction() {
newName = dialog.getName();
templ = dialog.getSelectedTemplate();
}
if (result == QDialog::Rejected)
return;
ProjectModel::SoundMacroNode* node = m_projectModel->newSoundMacro(group, newName, templ);
if (node)
if (result == QDialog::Rejected) {
return;
}
ProjectModel::SoundMacroNode* node = m_projectModel->newSoundMacro(group, std::move(newName), templ);
if (node) {
openEditor(node);
}
}
void MainWindow::newADSRAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group);
const QString groupName = getGroupName(group);
QString newName;
bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText(
this, tr("New ADSR"), tr("What should the new ADSR in %1 be named?").arg(groupName), QLineEdit::Normal,
QString::fromStdString(amuse::TableId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Table)), &ok);
if (!ok)
return;
}
ProjectModel::ADSRNode* node = m_projectModel->newADSR(group, newName);
if (node)
if (!ok) {
return;
}
ProjectModel::ADSRNode* node = m_projectModel->newADSR(group, std::move(newName));
if (node) {
openEditor(node);
}
}
void MainWindow::newCurveAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group);
const QString groupName = getGroupName(group);
QString newName;
bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText(
this, tr("New Curve"), tr("What should the new Curve in %1 be named?").arg(groupName), QLineEdit::Normal,
QString::fromStdString(amuse::TableId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Table)), &ok);
if (!ok)
return;
}
ProjectModel::CurveNode* node = m_projectModel->newCurve(group, newName);
if (node)
if (!ok) {
return;
}
ProjectModel::CurveNode* node = m_projectModel->newCurve(group, std::move(newName));
if (node) {
openEditor(node);
}
}
void MainWindow::newKeymapAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group);
const QString groupName = getGroupName(group);
QString newName;
bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText(
this, tr("New Keymap"), tr("What should the new Keymap in %1 be named?").arg(groupName), QLineEdit::Normal,
QString::fromStdString(amuse::KeymapId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Keymap)), &ok);
if (!ok)
return;
}
ProjectModel::KeymapNode* node = m_projectModel->newKeymap(group, newName);
if (node)
if (!ok) {
return;
}
ProjectModel::KeymapNode* node = m_projectModel->newKeymap(group, std::move(newName));
if (node) {
openEditor(node);
}
}
void MainWindow::newLayersAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group);
const QString groupName = getGroupName(group);
QString newName;
bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText(
this, tr("New Layers"), tr("What should the new Layers in %1 be named?").arg(groupName), QLineEdit::Normal,
QString::fromStdString(amuse::LayersId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Layer)), &ok);
if (!ok)
return;
}
ProjectModel::LayersNode* node = m_projectModel->newLayers(group, newName);
if (node)
if (!ok) {
return;
}
ProjectModel::LayersNode* node = m_projectModel->newLayers(group, std::move(newName));
if (node) {
openEditor(node);
}
}
void MainWindow::updateNavigationButtons() {
m_goForward->setDisabled(m_navIt == m_navList.end() || m_navIt + 1 == m_navList.end());

View File

@ -410,7 +410,7 @@ void ProjectModel::NameUndoRegistry::unregisterSFXName(amuse::SongId id) {
amuse::SFXId::CurNameDB->remove(id);
}
ProjectModel::INode::INode(const QString& name) : m_name(name) {
ProjectModel::INode::INode(QString name) : m_name(std::move(name)) {
auto nullNode = amuse::MakeObj<NullNode>(this);
m_nullChild = nullNode.get();
}
@ -506,10 +506,10 @@ bool ProjectModel::clearProjectData() {
return true;
}
bool ProjectModel::openGroupData(const QString& groupName, UIMessenger& messenger) {
bool ProjectModel::openGroupData(QString groupName, UIMessenger& messenger) {
m_projectDatabase.setIdDatabases();
QString path = QFileInfo(m_dir, groupName).filePath();
m_groups.insert(std::make_pair(groupName, std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(path))));
const QString path = QFileInfo(m_dir, groupName).filePath();
m_groups.emplace(std::move(groupName), std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(path)));
m_needsReset = true;
return true;
@ -543,10 +543,13 @@ void ProjectModel::openSongsData() {
for (auto& p : dr.getRootNode()->m_mapChildren) {
char* endPtr;
amuse::SongId id = uint16_t(strtoul(p.first.c_str(), &endPtr, 16));
if (endPtr == p.first.c_str() || id.id == 0xffff)
if (endPtr == p.first.c_str() || id.id == 0xffff) {
continue;
}
QString path = QString::fromStdString(p.second->m_scalarString);
setMIDIPathOfSong(id, path);
setMIDIPathOfSong(id, std::move(path));
}
_resetSongRefCount();
}
@ -1015,11 +1018,12 @@ QVariant ProjectModel::data(const QModelIndex& index, int role) const {
}
class RenameNodeUndoCommand : public EditorUndoCommand {
QString m_redoVal, m_undoVal;
QString m_redoVal;
QString m_undoVal;
public:
RenameNodeUndoCommand(const QString& text, ProjectModel::INode* node, const QString& redoVal)
: EditorUndoCommand(node, text.arg(node->name())), m_redoVal(redoVal) {}
explicit RenameNodeUndoCommand(const QString& text, ProjectModel::INode* node, QString redoVal)
: EditorUndoCommand(node, text.arg(node->name())), m_redoVal(std::move(redoVal)) {}
void undo() override { g_MainWindow->projectModel()->_renameNode(m_node.get(), m_undoVal); }
void redo() override {
m_undoVal = m_node->name();
@ -1064,25 +1068,28 @@ void ProjectModel::_renameNode(INode* node, const QString& name) {
}
bool ProjectModel::setData(const QModelIndex& index, const QVariant& value, int role) {
if (!index.isValid() || role != Qt::EditRole)
if (!index.isValid() || role != Qt::EditRole) {
return false;
}
assert(index.model() == this && "Not ProjectModel");
INode* item = static_cast<INode*>(index.internalPointer());
INode* parent = item->parent();
if (!parent)
return false;
if (item->name() == value.toString())
return false;
if (parent->findChild(value.toString())) {
g_MainWindow->uiMessenger().critical(tr("Naming Conflict"),
tr("%1 already exists in this context").arg(value.toString()));
const INode* parent = item->parent();
if (!parent) {
return false;
}
g_MainWindow->pushUndoCommand(new RenameNodeUndoCommand(tr("Rename %1"), item, value.toString()));
QString valueStr = value.toString();
if (item->name() == valueStr) {
return false;
}
if (parent->findChild(valueStr)) {
g_MainWindow->uiMessenger().critical(tr("Naming Conflict"), tr("%1 already exists in this context").arg(valueStr));
return false;
}
g_MainWindow->pushUndoCommand(new RenameNodeUndoCommand(tr("Rename %1"), item, std::move(valueStr)));
return true;
}
@ -1199,15 +1206,16 @@ std::unique_ptr<amuse::AudioGroupDatabase> ProjectModel::_delNode(GroupNode* nod
return ret;
}
ProjectModel::GroupNode* ProjectModel::newSubproject(const QString& name) {
ProjectModel::GroupNode* ProjectModel::newSubproject(QString name) {
if (m_groups.find(name) != m_groups.cend()) {
g_MainWindow->uiMessenger().critical(tr("Subproject Conflict"),
tr("The subproject %1 is already defined").arg(name));
return nullptr;
}
QString path = QFileInfo(m_dir, name).filePath();
const QString path = QFileInfo(m_dir, name).filePath();
auto data = std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(path));
auto node = amuse::MakeObj<GroupNode>(name);
auto node = amuse::MakeObj<GroupNode>(std::move(name));
_buildGroupNodeCollections(*node);
g_MainWindow->pushUndoCommand(new GroupNodeAddUndoCommand(tr("Add Subproject %1"), std::move(data), node.get()));
return node.get();
@ -1286,14 +1294,16 @@ void ProjectModel::_delNode(SoundGroupNode* node, GroupNode* parent, NameUndoReg
_delGroupNode(node, parent, registry, parent->getAudioGroup()->getProj().sfxGroups());
}
ProjectModel::SoundGroupNode* ProjectModel::newSoundGroup(GroupNode* group, const QString& name) {
ProjectModel::SoundGroupNode* ProjectModel::newSoundGroup(GroupNode* group, QString name) {
setIdDatabases(group);
if (amuse::GroupId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::GroupId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Sound Group Conflict"), tr("The group %1 is already defined").arg(name));
return nullptr;
}
auto node = amuse::MakeObj<SoundGroupNode>(name, amuse::MakeObj<amuse::SFXGroupIndex>());
auto node = amuse::MakeObj<SoundGroupNode>(std::move(name), amuse::MakeObj<amuse::SFXGroupIndex>());
g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<SoundGroupNode>(tr("Add Sound Group %1"), node.get(), group));
return node.get();
}
@ -1306,14 +1316,16 @@ void ProjectModel::_delNode(SongGroupNode* node, GroupNode* parent, NameUndoRegi
_delGroupNode(node, parent, registry, parent->getAudioGroup()->getProj().songGroups());
}
ProjectModel::SongGroupNode* ProjectModel::newSongGroup(GroupNode* group, const QString& name) {
ProjectModel::SongGroupNode* ProjectModel::newSongGroup(GroupNode* group, QString name) {
setIdDatabases(group);
if (amuse::GroupId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::GroupId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Song Group Conflict"), tr("The group %1 is already defined").arg(name));
return nullptr;
}
auto node = amuse::MakeObj<SongGroupNode>(name, amuse::MakeObj<amuse::SongGroupIndex>());
auto node = amuse::MakeObj<SongGroupNode>(std::move(name), amuse::MakeObj<amuse::SongGroupIndex>());
g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<SongGroupNode>(tr("Add Song Group %1"), node.get(), group));
return node.get();
}
@ -1412,20 +1424,23 @@ void ProjectModel::_delNode(SoundMacroNode* node, GroupNode* parent, NameUndoReg
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().soundMacros());
}
ProjectModel::SoundMacroNode* ProjectModel::newSoundMacro(GroupNode* group, const QString& name,
ProjectModel::SoundMacroNode* ProjectModel::newSoundMacro(GroupNode* group, QString name,
const SoundMacroTemplateEntry* templ) {
setIdDatabases(group);
if (amuse::SoundMacroId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::SoundMacroId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Sound Macro Conflict"), tr("The macro %1 is already defined").arg(name));
return nullptr;
}
auto dataNode = amuse::MakeObj<amuse::SoundMacro>();
if (templ) {
athena::io::MemoryReader r(templ->m_data, templ->m_length);
dataNode->readCmds<athena::utility::NotSystemEndian>(r, templ->m_length);
}
auto node = amuse::MakeObj<SoundMacroNode>(name, dataNode);
auto node = amuse::MakeObj<SoundMacroNode>(std::move(name), std::move(dataNode));
g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<SoundMacroNode>(tr("Add Sound Macro %1"), node.get(), group));
return node.get();
}
@ -1438,16 +1453,18 @@ void ProjectModel::_delNode(ADSRNode* node, GroupNode* parent, NameUndoRegistry&
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().tables());
}
ProjectModel::ADSRNode* ProjectModel::newADSR(GroupNode* group, const QString& name) {
ProjectModel::ADSRNode* ProjectModel::newADSR(GroupNode* group, QString name) {
setIdDatabases(group);
if (amuse::TableId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::TableId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("ADSR Conflict"), tr("The ADSR %1 is already defined").arg(name));
return nullptr;
}
auto dataNode = amuse::MakeObj<std::unique_ptr<amuse::ITable>>();
*dataNode = std::make_unique<amuse::ADSR>();
auto node = amuse::MakeObj<ADSRNode>(name, dataNode);
auto node = amuse::MakeObj<ADSRNode>(std::move(name), std::move(dataNode));
g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<ADSRNode>(tr("Add ADSR %1"), node.get(), group));
return node.get();
}
@ -1460,16 +1477,18 @@ void ProjectModel::_delNode(CurveNode* node, GroupNode* parent, NameUndoRegistry
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().tables());
}
ProjectModel::CurveNode* ProjectModel::newCurve(GroupNode* group, const QString& name) {
ProjectModel::CurveNode* ProjectModel::newCurve(GroupNode* group, QString name) {
setIdDatabases(group);
if (amuse::TableId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::TableId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Curve Conflict"), tr("The Curve %1 is already defined").arg(name));
return nullptr;
}
auto dataNode = amuse::MakeObj<std::unique_ptr<amuse::ITable>>();
*dataNode = std::make_unique<amuse::Curve>();
auto node = amuse::MakeObj<CurveNode>(name, dataNode);
auto node = amuse::MakeObj<CurveNode>(std::move(name), std::move(dataNode));
g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<CurveNode>(tr("Add Curve %1"), node.get(), group));
return node.get();
}
@ -1482,15 +1501,17 @@ void ProjectModel::_delNode(KeymapNode* node, GroupNode* parent, NameUndoRegistr
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().keymaps());
}
ProjectModel::KeymapNode* ProjectModel::newKeymap(GroupNode* group, const QString& name) {
ProjectModel::KeymapNode* ProjectModel::newKeymap(GroupNode* group, QString name) {
setIdDatabases(group);
if (amuse::KeymapId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::KeymapId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Keymap Conflict"), tr("The Keymap %1 is already defined").arg(name));
return nullptr;
}
auto dataNode = amuse::MakeObj<std::array<amuse::Keymap, 128>>();
auto node = amuse::MakeObj<KeymapNode>(name, dataNode);
auto node = amuse::MakeObj<KeymapNode>(std::move(name), std::move(dataNode));
g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<KeymapNode>(tr("Add Keymap %1"), node.get(), group));
return node.get();
}
@ -1503,16 +1524,19 @@ void ProjectModel::_delNode(LayersNode* node, GroupNode* parent, NameUndoRegistr
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().layers());
}
ProjectModel::LayersNode* ProjectModel::newLayers(GroupNode* group, const QString& name) {
ProjectModel::LayersNode* ProjectModel::newLayers(GroupNode* group, QString name) {
setIdDatabases(group);
if (amuse::LayersId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::LayersId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Layers Conflict"), tr("Layers %1 is already defined").arg(name));
return nullptr;
}
auto dataNode = amuse::MakeObj<std::vector<amuse::LayerMapping>>();
auto node = amuse::MakeObj<LayersNode>(name, dataNode);
auto node = amuse::MakeObj<LayersNode>(std::move(name), std::move(dataNode));
g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<LayersNode>(tr("Add Layers %1"), node.get(), group));
return node.get();
}
@ -2043,7 +2067,7 @@ QString ProjectModel::getMIDIPathOfSong(amuse::SongId id) const {
return search->second.m_path;
}
void ProjectModel::setMIDIPathOfSong(amuse::SongId id, const QString& path) { m_midiFiles[id].m_path = path; }
void ProjectModel::setMIDIPathOfSong(amuse::SongId id, QString path) { m_midiFiles[id].m_path = std::move(path); }
std::pair<amuse::SongId, std::string> ProjectModel::bootstrapSongId() {
m_projectDatabase.setIdDatabases();

View File

@ -125,9 +125,10 @@ public:
public:
~INode() override = default;
INode(const QString& name);
INode(INode* parent) : m_parent(parent), m_row(0) { /* ONLY USED BY NULL NODE! */
}
explicit INode(QString name);
// ONLY USED BY NULL NODE!
explicit INode(INode* parent) : m_parent(parent), m_row(0) {}
int childCount() const { return int(m_children.size()); }
INode* child(int row) const {
@ -219,7 +220,7 @@ public:
virtual void unregisterNames(NameUndoRegistry& registry) const {}
};
struct NullNode final : INode {
NullNode(INode* parent) : INode(parent) {}
explicit NullNode(INode* parent) : INode(parent) {}
Type type() const override { return Type::Null; }
QString text() const override { return {}; }
@ -237,8 +238,8 @@ public:
struct BasePoolObjectNode;
struct GroupNode final : INode {
std::unordered_map<QString, std::unique_ptr<amuse::AudioGroupDatabase>>::iterator m_it;
GroupNode(const QString& name) : INode(name) {}
GroupNode(std::unordered_map<QString, std::unique_ptr<amuse::AudioGroupDatabase>>::iterator it)
explicit GroupNode(QString name) : INode(std::move(name)) {}
explicit GroupNode(std::unordered_map<QString, std::unique_ptr<amuse::AudioGroupDatabase>>::iterator it)
: INode(it->first), m_it(it) {}
int hypotheticalIndex(const QString& name) const override;
@ -257,9 +258,12 @@ public:
struct SongGroupNode final : INode {
amuse::GroupId m_id;
amuse::ObjToken<amuse::SongGroupIndex> m_index;
SongGroupNode(const QString& name, amuse::ObjToken<amuse::SongGroupIndex> index) : INode(name), m_index(index) {}
SongGroupNode(amuse::GroupId id, amuse::ObjToken<amuse::SongGroupIndex> index)
: INode(QString::fromUtf8(amuse::GroupId::CurNameDB->resolveNameFromId(id).data())), m_id(id), m_index(index) {}
explicit SongGroupNode(QString name, amuse::ObjToken<amuse::SongGroupIndex> index)
: INode(std::move(name)), m_index(std::move(index)) {}
explicit SongGroupNode(amuse::GroupId id, amuse::ObjToken<amuse::SongGroupIndex> index)
: INode(QString::fromUtf8(amuse::GroupId::CurNameDB->resolveNameFromId(id).data()))
, m_id(id)
, m_index(std::move(index)) {}
static QIcon Icon;
Type type() const override { return Type::SongGroup; }
@ -283,9 +287,12 @@ public:
struct SoundGroupNode final : INode {
amuse::GroupId m_id;
amuse::ObjToken<amuse::SFXGroupIndex> m_index;
SoundGroupNode(const QString& name, amuse::ObjToken<amuse::SFXGroupIndex> index) : INode(name), m_index(index) {}
SoundGroupNode(amuse::GroupId id, amuse::ObjToken<amuse::SFXGroupIndex> index)
: INode(QString::fromUtf8(amuse::GroupId::CurNameDB->resolveNameFromId(id).data())), m_id(id), m_index(index) {}
explicit SoundGroupNode(QString name, amuse::ObjToken<amuse::SFXGroupIndex> index)
: INode(std::move(name)), m_index(std::move(index)) {}
explicit SoundGroupNode(amuse::GroupId id, amuse::ObjToken<amuse::SFXGroupIndex> index)
: INode(QString::fromUtf8(amuse::GroupId::CurNameDB->resolveNameFromId(id).data()))
, m_id(id)
, m_index(std::move(index)) {}
static QIcon Icon;
Type type() const override { return Type::SoundGroup; }
@ -309,8 +316,8 @@ public:
struct CollectionNode final : INode {
QIcon m_icon;
Type m_collectionType;
CollectionNode(const QString& name, const QIcon& icon, Type collectionType)
: INode(name), m_icon(icon), m_collectionType(collectionType) {}
explicit CollectionNode(QString name, QIcon icon, Type collectionType)
: INode(std::move(name)), m_icon(std::move(icon)), m_collectionType(collectionType) {}
Type type() const override { return Type::Collection; }
QString text() const override { return m_name; }
@ -325,8 +332,8 @@ public:
};
struct BasePoolObjectNode : INode {
amuse::ObjectId m_id;
BasePoolObjectNode(const QString& name) : INode(name) {}
BasePoolObjectNode(amuse::ObjectId id, const QString& name) : INode(name), m_id(id) {}
explicit BasePoolObjectNode(QString name) : INode(std::move(name)) {}
explicit BasePoolObjectNode(amuse::ObjectId id, QString name) : INode(std::move(name)), m_id(id) {}
amuse::ObjectId id() const { return m_id; }
QString text() const override { return m_name; }
QIcon icon() const override { return {}; }
@ -334,9 +341,9 @@ public:
template <class ID, class T, INode::Type TP>
struct PoolObjectNode final : BasePoolObjectNode {
amuse::ObjToken<T> m_obj;
PoolObjectNode(const QString& name, amuse::ObjToken<T> obj) : BasePoolObjectNode(name), m_obj(obj) {}
PoolObjectNode(QString name, amuse::ObjToken<T> obj) : BasePoolObjectNode(std::move(name)), m_obj(std::move(obj)) {}
PoolObjectNode(ID id, amuse::ObjToken<T> obj)
: BasePoolObjectNode(id, QString::fromUtf8(ID::CurNameDB->resolveNameFromId(id).data())), m_obj(obj) {}
: BasePoolObjectNode(id, QString::fromUtf8(ID::CurNameDB->resolveNameFromId(id).data())), m_obj(std::move(obj)) {}
Type type() const override { return TP; }
AmuseItemEditFlags editFlags() const override { return TP == INode::Type::Sample ? AmuseItemNoCut : AmuseItemAll; }
@ -368,7 +375,7 @@ public:
explicit ProjectModel(const QString& path, QObject* parent = Q_NULLPTR);
bool clearProjectData();
bool openGroupData(const QString& groupName, UIMessenger& messenger);
bool openGroupData(QString groupName, UIMessenger& messenger);
void openSongsData();
void importSongsData(const QString& path);
bool reloadSampleData(const QString& groupName, UIMessenger& messenger);
@ -402,36 +409,36 @@ public:
void _preDelNode(INode* n, NameUndoRegistry& registry);
void _addNode(GroupNode* node, std::unique_ptr<amuse::AudioGroupDatabase>&& data, const NameUndoRegistry& registry);
std::unique_ptr<amuse::AudioGroupDatabase> _delNode(GroupNode* node, NameUndoRegistry& registry);
GroupNode* newSubproject(const QString& name);
GroupNode* newSubproject(QString name);
template <class NT, class T>
void _addGroupNode(NT* node, GroupNode* parent, const NameUndoRegistry& registry, T& container);
template <class NT, class T>
void _delGroupNode(NT* node, GroupNode* parent, NameUndoRegistry& registry, T& container);
void _addNode(SoundGroupNode* node, GroupNode* parent, const NameUndoRegistry& registry);
void _delNode(SoundGroupNode* node, GroupNode* parent, NameUndoRegistry& registry);
SoundGroupNode* newSoundGroup(GroupNode* group, const QString& name);
SoundGroupNode* newSoundGroup(GroupNode* group, QString name);
void _addNode(SongGroupNode* node, GroupNode* parent, const NameUndoRegistry& registry);
void _delNode(SongGroupNode* node, GroupNode* parent, NameUndoRegistry& registry);
SongGroupNode* newSongGroup(GroupNode* group, const QString& name);
SongGroupNode* newSongGroup(GroupNode* group, QString name);
template <class NT, class T>
void _addPoolNode(NT* node, GroupNode* parent, const NameUndoRegistry& registry, T& container);
template <class NT, class T>
void _delPoolNode(NT* node, GroupNode* parent, NameUndoRegistry& registry, T& container);
void _addNode(SoundMacroNode* node, GroupNode* parent, const NameUndoRegistry& registry);
void _delNode(SoundMacroNode* node, GroupNode* parent, NameUndoRegistry& registry);
SoundMacroNode* newSoundMacro(GroupNode* group, const QString& name, const SoundMacroTemplateEntry* templ = nullptr);
SoundMacroNode* newSoundMacro(GroupNode* group, QString name, const SoundMacroTemplateEntry* templ = nullptr);
void _addNode(ADSRNode* node, GroupNode* parent, const NameUndoRegistry& registry);
void _delNode(ADSRNode* node, GroupNode* parent, NameUndoRegistry& registry);
ADSRNode* newADSR(GroupNode* group, const QString& name);
ADSRNode* newADSR(GroupNode* group, QString name);
void _addNode(CurveNode* node, GroupNode* parent, const NameUndoRegistry& registry);
void _delNode(CurveNode* node, GroupNode* parent, NameUndoRegistry& registry);
CurveNode* newCurve(GroupNode* group, const QString& name);
CurveNode* newCurve(GroupNode* group, QString name);
void _addNode(KeymapNode* node, GroupNode* parent, const NameUndoRegistry& registry);
void _delNode(KeymapNode* node, GroupNode* parent, NameUndoRegistry& registry);
KeymapNode* newKeymap(GroupNode* group, const QString& name);
KeymapNode* newKeymap(GroupNode* group, QString name);
void _addNode(LayersNode* node, GroupNode* parent, const NameUndoRegistry& registry);
void _delNode(LayersNode* node, GroupNode* parent, NameUndoRegistry& registry);
LayersNode* newLayers(GroupNode* group, const QString& name);
LayersNode* newLayers(GroupNode* group, QString name);
void _renameNode(INode* node, const QString& name);
template <class NT>
@ -458,7 +465,7 @@ public:
GroupNode* getGroupOfSfx(amuse::SFXId id) const;
QString getMIDIPathOfSong(amuse::SongId id) const;
void setMIDIPathOfSong(amuse::SongId id, const QString& path);
void setMIDIPathOfSong(amuse::SongId id, QString path);
std::pair<amuse::SongId, std::string> bootstrapSongId();
void allocateSongId(amuse::SongId id, std::string_view name);
void deallocateSongId(amuse::SongId oldId);