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() { void MainWindow::newSubprojectAction() {
QString newName; QString newName;
bool ok = true; 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?"), newName = QInputDialog::getText(this, tr("New Subproject"), tr("What should this subproject be named?"),
QLineEdit::Normal, QString(), &ok); 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() { void MainWindow::newSFXGroupAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode(); ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group); m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group); const QString groupName = getGroupName(group);
QString newName; QString newName;
bool ok = true; bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText( newName = QInputDialog::getText(
this, tr("New SFX Group"), tr("What should the new SFX group in %1 be named?").arg(groupName), this, tr("New SFX Group"), tr("What should the new SFX group in %1 be named?").arg(groupName),
QLineEdit::Normal, QLineEdit::Normal,
QString::fromStdString(amuse::GroupId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Group)), &ok); QString::fromStdString(amuse::GroupId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Group)), &ok);
if (!ok) }
return;
ProjectModel::SoundGroupNode* node = m_projectModel->newSoundGroup(group, newName); if (!ok) {
if (node) return;
}
ProjectModel::SoundGroupNode* node = m_projectModel->newSoundGroup(group, std::move(newName));
if (node) {
openEditor(node); openEditor(node);
} }
}
void MainWindow::newSongGroupAction() { void MainWindow::newSongGroupAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode(); ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group); m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group); const QString groupName = getGroupName(group);
QString newName; QString newName;
bool ok = true; bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText( newName = QInputDialog::getText(
this, tr("New Song Group"), tr("What should the new Song group in %1 be named?").arg(groupName), this, tr("New Song Group"), tr("What should the new Song group in %1 be named?").arg(groupName),
QLineEdit::Normal, QLineEdit::Normal,
QString::fromStdString(amuse::GroupId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Group)), &ok); QString::fromStdString(amuse::GroupId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Group)), &ok);
if (!ok) }
return;
ProjectModel::SongGroupNode* node = m_projectModel->newSongGroup(group, newName); if (!ok) {
if (node) return;
}
ProjectModel::SongGroupNode* node = m_projectModel->newSongGroup(group, std::move(newName));
if (node) {
openEditor(node); openEditor(node);
} }
}
void MainWindow::newSoundMacroAction() { void MainWindow::newSoundMacroAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode(); ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group); m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group); const QString groupName = getGroupName(group);
QString newName; QString newName;
const SoundMacroTemplateEntry* templ = nullptr; const SoundMacroTemplateEntry* templ = nullptr;
int result = QDialog::Accepted; int result = QDialog::Accepted;
while (result == QDialog::Accepted && newName.isEmpty()) { while (result == QDialog::Accepted && newName.isEmpty()) {
NewSoundMacroDialog dialog(groupName, this); NewSoundMacroDialog dialog(groupName, this);
dialog.setWindowModality(Qt::WindowModal); dialog.setWindowModality(Qt::WindowModal);
@ -1356,85 +1371,108 @@ void MainWindow::newSoundMacroAction() {
newName = dialog.getName(); newName = dialog.getName();
templ = dialog.getSelectedTemplate(); templ = dialog.getSelectedTemplate();
} }
if (result == QDialog::Rejected)
return;
ProjectModel::SoundMacroNode* node = m_projectModel->newSoundMacro(group, newName, templ); if (result == QDialog::Rejected) {
if (node) return;
}
ProjectModel::SoundMacroNode* node = m_projectModel->newSoundMacro(group, std::move(newName), templ);
if (node) {
openEditor(node); openEditor(node);
} }
}
void MainWindow::newADSRAction() { void MainWindow::newADSRAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode(); ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group); m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group); const QString groupName = getGroupName(group);
QString newName; QString newName;
bool ok = true; bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText( newName = QInputDialog::getText(
this, tr("New ADSR"), tr("What should the new ADSR in %1 be named?").arg(groupName), QLineEdit::Normal, 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); QString::fromStdString(amuse::TableId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Table)), &ok);
if (!ok) }
return;
ProjectModel::ADSRNode* node = m_projectModel->newADSR(group, newName); if (!ok) {
if (node) return;
}
ProjectModel::ADSRNode* node = m_projectModel->newADSR(group, std::move(newName));
if (node) {
openEditor(node); openEditor(node);
} }
}
void MainWindow::newCurveAction() { void MainWindow::newCurveAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode(); ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group); m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group); const QString groupName = getGroupName(group);
QString newName; QString newName;
bool ok = true; bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText( newName = QInputDialog::getText(
this, tr("New Curve"), tr("What should the new Curve in %1 be named?").arg(groupName), QLineEdit::Normal, 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); QString::fromStdString(amuse::TableId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Table)), &ok);
if (!ok) }
return;
ProjectModel::CurveNode* node = m_projectModel->newCurve(group, newName); if (!ok) {
if (node) return;
}
ProjectModel::CurveNode* node = m_projectModel->newCurve(group, std::move(newName));
if (node) {
openEditor(node); openEditor(node);
} }
}
void MainWindow::newKeymapAction() { void MainWindow::newKeymapAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode(); ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group); m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group); const QString groupName = getGroupName(group);
QString newName; QString newName;
bool ok = true; bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText( newName = QInputDialog::getText(
this, tr("New Keymap"), tr("What should the new Keymap in %1 be named?").arg(groupName), QLineEdit::Normal, 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); QString::fromStdString(amuse::KeymapId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Keymap)), &ok);
if (!ok) }
return;
ProjectModel::KeymapNode* node = m_projectModel->newKeymap(group, newName); if (!ok) {
if (node) return;
}
ProjectModel::KeymapNode* node = m_projectModel->newKeymap(group, std::move(newName));
if (node) {
openEditor(node); openEditor(node);
} }
}
void MainWindow::newLayersAction() { void MainWindow::newLayersAction() {
ProjectModel::GroupNode* group = getSelectedGroupNode(); ProjectModel::GroupNode* group = getSelectedGroupNode();
m_projectModel->setIdDatabases(group); m_projectModel->setIdDatabases(group);
QString groupName = getGroupName(group); const QString groupName = getGroupName(group);
QString newName; QString newName;
bool ok = true; bool ok = true;
while (ok && newName.isEmpty())
while (ok && newName.isEmpty()) {
newName = QInputDialog::getText( newName = QInputDialog::getText(
this, tr("New Layers"), tr("What should the new Layers in %1 be named?").arg(groupName), QLineEdit::Normal, 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); QString::fromStdString(amuse::LayersId::CurNameDB->generateDefaultName(amuse::NameDB::Type::Layer)), &ok);
if (!ok) }
return;
ProjectModel::LayersNode* node = m_projectModel->newLayers(group, newName); if (!ok) {
if (node) return;
}
ProjectModel::LayersNode* node = m_projectModel->newLayers(group, std::move(newName));
if (node) {
openEditor(node); openEditor(node);
} }
}
void MainWindow::updateNavigationButtons() { void MainWindow::updateNavigationButtons() {
m_goForward->setDisabled(m_navIt == m_navList.end() || m_navIt + 1 == m_navList.end()); 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); 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); auto nullNode = amuse::MakeObj<NullNode>(this);
m_nullChild = nullNode.get(); m_nullChild = nullNode.get();
} }
@ -506,10 +506,10 @@ bool ProjectModel::clearProjectData() {
return true; return true;
} }
bool ProjectModel::openGroupData(const QString& groupName, UIMessenger& messenger) { bool ProjectModel::openGroupData(QString groupName, UIMessenger& messenger) {
m_projectDatabase.setIdDatabases(); m_projectDatabase.setIdDatabases();
QString path = QFileInfo(m_dir, groupName).filePath(); const QString path = QFileInfo(m_dir, groupName).filePath();
m_groups.insert(std::make_pair(groupName, std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(path)))); m_groups.emplace(std::move(groupName), std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(path)));
m_needsReset = true; m_needsReset = true;
return true; return true;
@ -543,10 +543,13 @@ void ProjectModel::openSongsData() {
for (auto& p : dr.getRootNode()->m_mapChildren) { for (auto& p : dr.getRootNode()->m_mapChildren) {
char* endPtr; char* endPtr;
amuse::SongId id = uint16_t(strtoul(p.first.c_str(), &endPtr, 16)); 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; continue;
}
QString path = QString::fromStdString(p.second->m_scalarString); QString path = QString::fromStdString(p.second->m_scalarString);
setMIDIPathOfSong(id, path); setMIDIPathOfSong(id, std::move(path));
} }
_resetSongRefCount(); _resetSongRefCount();
} }
@ -1015,11 +1018,12 @@ QVariant ProjectModel::data(const QModelIndex& index, int role) const {
} }
class RenameNodeUndoCommand : public EditorUndoCommand { class RenameNodeUndoCommand : public EditorUndoCommand {
QString m_redoVal, m_undoVal; QString m_redoVal;
QString m_undoVal;
public: public:
RenameNodeUndoCommand(const QString& text, ProjectModel::INode* node, const QString& redoVal) explicit RenameNodeUndoCommand(const QString& text, ProjectModel::INode* node, QString redoVal)
: EditorUndoCommand(node, text.arg(node->name())), m_redoVal(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 undo() override { g_MainWindow->projectModel()->_renameNode(m_node.get(), m_undoVal); }
void redo() override { void redo() override {
m_undoVal = m_node->name(); 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) { 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; return false;
}
assert(index.model() == this && "Not ProjectModel"); assert(index.model() == this && "Not ProjectModel");
INode* item = static_cast<INode*>(index.internalPointer()); INode* item = static_cast<INode*>(index.internalPointer());
INode* parent = item->parent(); const INode* parent = item->parent();
if (!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()));
return false; 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; return true;
} }
@ -1199,15 +1206,16 @@ std::unique_ptr<amuse::AudioGroupDatabase> ProjectModel::_delNode(GroupNode* nod
return ret; return ret;
} }
ProjectModel::GroupNode* ProjectModel::newSubproject(const QString& name) { ProjectModel::GroupNode* ProjectModel::newSubproject(QString name) {
if (m_groups.find(name) != m_groups.cend()) { if (m_groups.find(name) != m_groups.cend()) {
g_MainWindow->uiMessenger().critical(tr("Subproject Conflict"), g_MainWindow->uiMessenger().critical(tr("Subproject Conflict"),
tr("The subproject %1 is already defined").arg(name)); tr("The subproject %1 is already defined").arg(name));
return nullptr; 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 data = std::make_unique<amuse::AudioGroupDatabase>(QStringToSysString(path));
auto node = amuse::MakeObj<GroupNode>(name); auto node = amuse::MakeObj<GroupNode>(std::move(name));
_buildGroupNodeCollections(*node); _buildGroupNodeCollections(*node);
g_MainWindow->pushUndoCommand(new GroupNodeAddUndoCommand(tr("Add Subproject %1"), std::move(data), node.get())); g_MainWindow->pushUndoCommand(new GroupNodeAddUndoCommand(tr("Add Subproject %1"), std::move(data), node.get()));
return 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()); _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); setIdDatabases(group);
if (amuse::GroupId::CurNameDB->m_stringToId.find(name.toUtf8().data()) != if (amuse::GroupId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::GroupId::CurNameDB->m_stringToId.cend()) { amuse::GroupId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Sound Group Conflict"), tr("The group %1 is already defined").arg(name)); g_MainWindow->uiMessenger().critical(tr("Sound Group Conflict"), tr("The group %1 is already defined").arg(name));
return nullptr; 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)); g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<SoundGroupNode>(tr("Add Sound Group %1"), node.get(), group));
return node.get(); return node.get();
} }
@ -1306,14 +1316,16 @@ void ProjectModel::_delNode(SongGroupNode* node, GroupNode* parent, NameUndoRegi
_delGroupNode(node, parent, registry, parent->getAudioGroup()->getProj().songGroups()); _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); setIdDatabases(group);
if (amuse::GroupId::CurNameDB->m_stringToId.find(name.toUtf8().data()) != if (amuse::GroupId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::GroupId::CurNameDB->m_stringToId.cend()) { amuse::GroupId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Song Group Conflict"), tr("The group %1 is already defined").arg(name)); g_MainWindow->uiMessenger().critical(tr("Song Group Conflict"), tr("The group %1 is already defined").arg(name));
return nullptr; 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)); g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<SongGroupNode>(tr("Add Song Group %1"), node.get(), group));
return node.get(); return node.get();
} }
@ -1412,20 +1424,23 @@ void ProjectModel::_delNode(SoundMacroNode* node, GroupNode* parent, NameUndoReg
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().soundMacros()); _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) { const SoundMacroTemplateEntry* templ) {
setIdDatabases(group); setIdDatabases(group);
if (amuse::SoundMacroId::CurNameDB->m_stringToId.find(name.toUtf8().data()) != if (amuse::SoundMacroId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::SoundMacroId::CurNameDB->m_stringToId.cend()) { amuse::SoundMacroId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Sound Macro Conflict"), tr("The macro %1 is already defined").arg(name)); g_MainWindow->uiMessenger().critical(tr("Sound Macro Conflict"), tr("The macro %1 is already defined").arg(name));
return nullptr; return nullptr;
} }
auto dataNode = amuse::MakeObj<amuse::SoundMacro>(); auto dataNode = amuse::MakeObj<amuse::SoundMacro>();
if (templ) { if (templ) {
athena::io::MemoryReader r(templ->m_data, templ->m_length); athena::io::MemoryReader r(templ->m_data, templ->m_length);
dataNode->readCmds<athena::utility::NotSystemEndian>(r, 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)); g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<SoundMacroNode>(tr("Add Sound Macro %1"), node.get(), group));
return node.get(); return node.get();
} }
@ -1438,16 +1453,18 @@ void ProjectModel::_delNode(ADSRNode* node, GroupNode* parent, NameUndoRegistry&
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().tables()); _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); setIdDatabases(group);
if (amuse::TableId::CurNameDB->m_stringToId.find(name.toUtf8().data()) != if (amuse::TableId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::TableId::CurNameDB->m_stringToId.cend()) { amuse::TableId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("ADSR Conflict"), tr("The ADSR %1 is already defined").arg(name)); g_MainWindow->uiMessenger().critical(tr("ADSR Conflict"), tr("The ADSR %1 is already defined").arg(name));
return nullptr; return nullptr;
} }
auto dataNode = amuse::MakeObj<std::unique_ptr<amuse::ITable>>(); auto dataNode = amuse::MakeObj<std::unique_ptr<amuse::ITable>>();
*dataNode = std::make_unique<amuse::ADSR>(); *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)); g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<ADSRNode>(tr("Add ADSR %1"), node.get(), group));
return node.get(); return node.get();
} }
@ -1460,16 +1477,18 @@ void ProjectModel::_delNode(CurveNode* node, GroupNode* parent, NameUndoRegistry
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().tables()); _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); setIdDatabases(group);
if (amuse::TableId::CurNameDB->m_stringToId.find(name.toUtf8().data()) != if (amuse::TableId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::TableId::CurNameDB->m_stringToId.cend()) { amuse::TableId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Curve Conflict"), tr("The Curve %1 is already defined").arg(name)); g_MainWindow->uiMessenger().critical(tr("Curve Conflict"), tr("The Curve %1 is already defined").arg(name));
return nullptr; return nullptr;
} }
auto dataNode = amuse::MakeObj<std::unique_ptr<amuse::ITable>>(); auto dataNode = amuse::MakeObj<std::unique_ptr<amuse::ITable>>();
*dataNode = std::make_unique<amuse::Curve>(); *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)); g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<CurveNode>(tr("Add Curve %1"), node.get(), group));
return node.get(); return node.get();
} }
@ -1482,15 +1501,17 @@ void ProjectModel::_delNode(KeymapNode* node, GroupNode* parent, NameUndoRegistr
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().keymaps()); _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); setIdDatabases(group);
if (amuse::KeymapId::CurNameDB->m_stringToId.find(name.toUtf8().data()) != if (amuse::KeymapId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::KeymapId::CurNameDB->m_stringToId.cend()) { amuse::KeymapId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Keymap Conflict"), tr("The Keymap %1 is already defined").arg(name)); g_MainWindow->uiMessenger().critical(tr("Keymap Conflict"), tr("The Keymap %1 is already defined").arg(name));
return nullptr; return nullptr;
} }
auto dataNode = amuse::MakeObj<std::array<amuse::Keymap, 128>>(); 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)); g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<KeymapNode>(tr("Add Keymap %1"), node.get(), group));
return node.get(); return node.get();
} }
@ -1503,16 +1524,19 @@ void ProjectModel::_delNode(LayersNode* node, GroupNode* parent, NameUndoRegistr
_delPoolNode(node, parent, registry, parent->getAudioGroup()->getPool().layers()); _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); setIdDatabases(group);
if (amuse::LayersId::CurNameDB->m_stringToId.find(name.toUtf8().data()) != if (amuse::LayersId::CurNameDB->m_stringToId.find(name.toUtf8().data()) !=
amuse::LayersId::CurNameDB->m_stringToId.cend()) { amuse::LayersId::CurNameDB->m_stringToId.cend()) {
g_MainWindow->uiMessenger().critical(tr("Layers Conflict"), tr("Layers %1 is already defined").arg(name)); g_MainWindow->uiMessenger().critical(tr("Layers Conflict"), tr("Layers %1 is already defined").arg(name));
return nullptr; return nullptr;
} }
auto dataNode = amuse::MakeObj<std::vector<amuse::LayerMapping>>(); 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)); g_MainWindow->pushUndoCommand(new NodeAddUndoCommand<LayersNode>(tr("Add Layers %1"), node.get(), group));
return node.get(); return node.get();
} }
@ -2043,7 +2067,7 @@ QString ProjectModel::getMIDIPathOfSong(amuse::SongId id) const {
return search->second.m_path; 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() { std::pair<amuse::SongId, std::string> ProjectModel::bootstrapSongId() {
m_projectDatabase.setIdDatabases(); m_projectDatabase.setIdDatabases();

View File

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