Finish work in drag&drop of Actions

This commit is contained in:
2024-01-04 20:22:39 +01:00
parent 7571c4b1ad
commit ffe4a99baa
12 changed files with 782 additions and 489 deletions

View File

@@ -81,7 +81,9 @@ HEADERS += \
src/editor/widgets/actionscontainerwidget.h \ src/editor/widgets/actionscontainerwidget.h \
src/editor/widgets/codeeditorwidget.h \ src/editor/widgets/codeeditorwidget.h \
src/editor/widgets/drawingcanvaswidget.h \ src/editor/widgets/drawingcanvaswidget.h \
src/editor/widgets/pathpointswidget.h src/editor/widgets/pathpointswidget.h \
src/projectserialization.h \
src/stdserialization.h
SOURCES += \ SOURCES += \
src/closeeventfilter.cpp \ src/closeeventfilter.cpp \
@@ -140,7 +142,8 @@ SOURCES += \
src/editor/widgets/actionscontainerwidget.cpp \ src/editor/widgets/actionscontainerwidget.cpp \
src/editor/widgets/codeeditorwidget.cpp \ src/editor/widgets/codeeditorwidget.cpp \
src/editor/widgets/drawingcanvaswidget.cpp \ src/editor/widgets/drawingcanvaswidget.cpp \
src/editor/widgets/pathpointswidget.cpp src/editor/widgets/pathpointswidget.cpp \
src/projectserialization.cpp
FORMS += \ FORMS += \
src/editor/mainwindow.ui \ src/editor/mainwindow.ui \

View File

@@ -11,6 +11,7 @@
#include <QInputDialog> #include <QInputDialog>
#include <QDebug> #include <QDebug>
#include "projectserialization.h"
#include "models/projecttreemodel.h" #include "models/projecttreemodel.h"
#include "dialogs/preferencesdialog.h" #include "dialogs/preferencesdialog.h"
#include "dialogs/spritepropertiesdialog.h" #include "dialogs/spritepropertiesdialog.h"

View File

@@ -2,6 +2,10 @@
#include <QDebug> #include <QDebug>
#include <QIcon> #include <QIcon>
#include <QMimeData>
#include "projectserialization.h"
#include "stdserialization.h"
ActionsContainerModel::ActionsContainerModel(QObject *parent) : ActionsContainerModel::ActionsContainerModel(QObject *parent) :
QAbstractListModel{parent} QAbstractListModel{parent}
@@ -86,7 +90,7 @@ Qt::DropActions ActionsContainerModel::supportedDropActions() const
{ {
auto actions = QAbstractListModel::supportedDropActions(); auto actions = QAbstractListModel::supportedDropActions();
actions |= Qt::MoveAction; actions |= Qt::MoveAction;
actions |= Qt::TargetMoveAction; // actions |= Qt::TargetMoveAction;
return actions; return actions;
} }
@@ -94,10 +98,184 @@ Qt::DropActions ActionsContainerModel::supportedDragActions() const
{ {
auto actions = QAbstractListModel::supportedDragActions(); auto actions = QAbstractListModel::supportedDragActions();
actions |= Qt::MoveAction; actions |= Qt::MoveAction;
actions |= Qt::TargetMoveAction; // actions |= Qt::TargetMoveAction;
return actions; return actions;
} }
QStringList ActionsContainerModel::mimeTypes() const
{
return {"custom"};
}
QMimeData *ActionsContainerModel::mimeData(const QModelIndexList &indexes) const
{
if (!m_actionsContainer)
return nullptr;
if (indexes.size() <= 0)
return nullptr;
QStringList types = mimeTypes();
if (types.isEmpty())
return nullptr;
QMimeData *data = new QMimeData;
QString format = types.at(0);
QByteArray encoded;
QDataStream stream(&encoded, QDataStream::WriteOnly);
for (const auto &index : indexes)
{
const Action &action = *std::next(std::cbegin(*m_actionsContainer), index.row());
stream << action;
}
data->setData(format, encoded);
return data;
}
bool ActionsContainerModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
{
if (!m_actionsContainer)
{
qWarning() << "no container";
return false;
}
// if the drop is on an item, reject drop
if (parent.isValid() && row == -1 && column == -1)
{
// qWarning() << "drop on item";
return false;
}
return QAbstractListModel::canDropMimeData(data, action, row, column, parent);
}
bool ActionsContainerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
if (!m_actionsContainer)
{
qWarning() << "no container";
return false;
}
// check if the action is supported
if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
{
qWarning() << "wrong action";
return false;
}
// if the drop is on an item, replace the data in the items
if (parent.isValid() && row == -1 && column == -1)
{
// qWarning() << "drop on item";
return false;
}
// check if the format is supported
QStringList types = mimeTypes();
if (types.isEmpty())
return false;
QString format = types.at(0);
if (!data->hasFormat(format))
{
qWarning() << "wrong format";
return false;
}
if (row > rowCount(parent))
row = rowCount(parent);
if (row == -1)
row = rowCount(parent);
if (column == -1)
column = 0;
// decode and insert
QByteArray encoded = data->data(format);
QDataStream stream(&encoded, QDataStream::ReadOnly);
QList<Action> actions;
while (!stream.atEnd())
{
Action action;
stream >> action;
actions << std::move(action);
}
if (actions.isEmpty())
{
qWarning() << "empty actions";
return false;
}
beginInsertRows({}, row, row + actions.size() - 1);
auto iter = std::next(std::begin(*m_actionsContainer), row);
for (auto &action : actions)
iter = m_actionsContainer->insert(iter, std::move(action));
endInsertRows();
return true;
}
QMap<int, QVariant> ActionsContainerModel::itemData(const QModelIndex &index) const
{
auto itemData = QAbstractListModel::itemData(index);
qDebug() << index << itemData;
return itemData;
}
bool ActionsContainerModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
{
auto setItemData = QAbstractListModel::setItemData(index, roles);
qDebug() << index << roles << setItemData;
return setItemData;
}
bool ActionsContainerModel::removeRows(int row, int count, const QModelIndex &parent)
{
qDebug() << row << count << parent.isValid();
if (!m_actionsContainer)
return false;
if (parent.isValid())
return false;
if (row < 0 || std::size_t(row) >= m_actionsContainer->size())
{
qWarning() << "unexpected row" << row;
return false;
}
if (count < 0 || std::size_t(count) > m_actionsContainer->size() - row)
{
qWarning() << "unexpected row+count" << count << row;
return false;
}
beginRemoveRows({}, row, row + count - 1);
auto begin = std::next(std::begin(*m_actionsContainer), row);
auto end = std::next(begin, count);
m_actionsContainer->erase(begin, end);
endRemoveRows();
return true;
}
bool ActionsContainerModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
{
qDebug() << sourceRow << count << destinationChild;
if (!m_actionsContainer)
return false;
if (sourceParent.isValid())
return false;
if (destinationParent.isValid())
return false;
if (count != 1)
return false;
beginMoveRows({}, sourceRow, sourceRow, {}, destinationChild);
m_actionsContainer->splice(std::next(std::begin(*m_actionsContainer), destinationChild), *m_actionsContainer, std::next(std::begin(*m_actionsContainer), sourceRow));
endMoveRows();
return true;
}
void ActionsContainerModel::setActionsContainer(ActionsContainer *actionsContainer) void ActionsContainerModel::setActionsContainer(ActionsContainer *actionsContainer)
{ {
beginResetModel(); beginResetModel();

View File

@@ -15,10 +15,22 @@ public:
int rowCount(const QModelIndex &parent) const override; int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::ItemFlags flags(const QModelIndex &index) const override;
Qt::DropActions supportedDropActions() const override; Qt::DropActions supportedDropActions() const override;
Qt::DropActions supportedDragActions() const override; Qt::DropActions supportedDragActions() const override;
QStringList mimeTypes() const override;
QMimeData *mimeData(const QModelIndexList &indexes) const override;
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
QMap<int, QVariant> itemData(const QModelIndex &index) const override;
bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles) override;
bool removeRows(int row, int count, const QModelIndex &parent) override;
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
ActionsContainer *actionsContainer() const { return m_actionsContainer; } ActionsContainer *actionsContainer() const { return m_actionsContainer; }
void setActionsContainer(ActionsContainer *actionsContainer); void setActionsContainer(ActionsContainer *actionsContainer);

View File

@@ -5,6 +5,10 @@
#include <QDrag> #include <QDrag>
#include <QMimeData> #include <QMimeData>
#include "projectcontainer.h"
#include "projectserialization.h"
#include "stdserialization.h"
ActionDragWidget::ActionDragWidget(QWidget *parent) : ActionDragWidget::ActionDragWidget(QWidget *parent) :
QToolButton{parent} QToolButton{parent}
{ {
@@ -33,8 +37,12 @@ void ActionDragWidget::mouseMoveEvent(QMouseEvent *event)
drag->setPixmap(this->icon().pixmap(QSize{32, 32})); drag->setPixmap(this->icon().pixmap(QSize{32, 32}));
QMimeData *mimeData = new QMimeData; QMimeData *mimeData = new QMimeData;
mimeData->setData("custom", QByteArray{"aaaaaa"}); QByteArray encoded;
QDataStream stream(&encoded, QDataStream::WriteOnly);
stream << Action{ExecuteCodeAction{ .script = "hatschi" }};
mimeData->setData("custom", encoded);
drag->setMimeData(mimeData); drag->setMimeData(mimeData);
Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction); Qt::DropAction dropAction = drag->exec(Qt::CopyAction);
qDebug() << dropAction;
} }

View File

@@ -4,6 +4,7 @@
#include <QDebug> #include <QDebug>
#include <QMessageBox> #include <QMessageBox>
#include <QMenu> #include <QMenu>
#include <QKeySequence>
#include "models/actionscontainermodel.h" #include "models/actionscontainermodel.h"
#include "dialogs/codeactiondialog.h" #include "dialogs/codeactiondialog.h"
@@ -84,16 +85,55 @@ void ActionsContainerWidget::actionsContextMenuRequested(const QPoint &pos)
auto action = index.isValid() ? m_actionsModel->getAction(index) : nullptr; auto action = index.isValid() ? m_actionsModel->getAction(index) : nullptr;
QMenu menu{this}; QMenu menu{this};
menu.addAction(tr("&Edit Values"), this, [this,index](){ actionDoubleClicked(index); })->setEnabled(action); if (auto action = menu.addAction(tr("&Edit Values"), this, [this,index](){
actionDoubleClicked(index);
}))
action->setEnabled(action);
menu.addSeparator(); menu.addSeparator();
menu.addAction(tr("C&ut"))->setEnabled(false); if (auto action = menu.addAction(tr("C&ut"), this, [this](){
menu.addAction(tr("&Copy"))->setEnabled(false); QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
menu.addAction(tr("&Paste"))->setEnabled(false); }))
{
action->setEnabled(action);
action->setShortcut(QKeySequence::Cut);
}
if (auto action = menu.addAction(tr("&Copy"), this, [this](){
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
}))
{
action->setEnabled(action);
action->setShortcut(QKeySequence::Copy);
}
if (auto action = menu.addAction(tr("&Paste"), this, [this](){
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
}))
{
action->setEnabled(action);
action->setShortcut(QKeySequence::Paste);
}
menu.addSeparator(); menu.addSeparator();
menu.addAction(tr("&Delete"))->setEnabled(false); if (auto action = menu.addAction(tr("&Delete"), this, [this,index](){
if (!m_actionsModel->removeRow(index.row()))
QMessageBox::warning(this, tr("Could not remove action!"), tr("Could not remove action!"));
}))
{
action->setEnabled(action);
action->setShortcut(QKeySequence::Delete);
}
menu.addSeparator(); menu.addSeparator();
menu.addAction(tr("Select &All"))->setEnabled(false); if (auto action = menu.addAction(tr("Select &All"), this, [this](){
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
}))
{
action->setEnabled(m_actionsModel->actionsContainer() && !m_actionsModel->actionsContainer()->empty());
action->setShortcut(QKeySequence::SelectAll);
}
menu.addSeparator(); menu.addSeparator();
menu.addAction(tr("C&lear"))->setEnabled(false); if (auto action = menu.addAction(tr("C&lear"), this, [this](){
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
}))
{
action->setEnabled(m_actionsModel->actionsContainer() && !m_actionsModel->actionsContainer()->empty());
}
menu.exec(m_ui->listViewActions->viewport()->mapToGlobal(pos)); menu.exec(m_ui->listViewActions->viewport()->mapToGlobal(pos));
} }

View File

@@ -10,6 +10,9 @@
<height>667</height> <height>667</height>
</rect> </rect>
</property> </property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
@@ -56,7 +59,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="dragDropMode"> <property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum> <enum>QAbstractItemView::DragDrop</enum>
</property> </property>
<property name="defaultDropAction"> <property name="defaultDropAction">
<enum>Qt::MoveAction</enum> <enum>Qt::MoveAction</enum>

View File

@@ -18,474 +18,3 @@ template<> std::list<Object> &ProjectContainer::containerFor() { return objects;
template<> const std::list<Object> &ProjectContainer::containerFor() const { return objects; } template<> const std::list<Object> &ProjectContainer::containerFor() const { return objects; }
template<> std::list<Room> &ProjectContainer::containerFor() { return rooms; } template<> std::list<Room> &ProjectContainer::containerFor() { return rooms; }
template<> const std::list<Room> &ProjectContainer::containerFor() const { return rooms; } template<> const std::list<Room> &ProjectContainer::containerFor() const { return rooms; }
template<typename T, std::size_t Tsize>
QDataStream &operator<<(QDataStream &ds, const std::array<T, Tsize> &array)
{
for (const auto &entry : array)
ds << entry;
return ds;
}
template<typename T, std::size_t Tsize>
QDataStream &operator>>(QDataStream &ds, std::array<T, Tsize> &array)
{
for (size_t i = 0; i < Tsize; i++)
ds >> array[i];
return ds;
}
template<typename T>
QDataStream &operator<<(QDataStream &ds, const std::list<T> &list)
{
{
int entries = list.size();
ds << entries;
}
for (const auto &entry : list)
ds << entry;
return ds;
}
template<typename T>
QDataStream &operator>>(QDataStream &ds, std::list<T> &list)
{
int entries;
ds >> entries;
for (int i = 0; i < entries; i++)
{
T entry;
ds >> entry;
list.emplace_back(std::move(entry));
}
return ds;
}
template<typename T>
QDataStream &operator<<(QDataStream &ds, const std::vector<T> &list)
{
{
int entries = list.size();
ds << entries;
}
for (const auto &entry : list)
ds << entry;
return ds;
}
template<typename T>
QDataStream &operator>>(QDataStream &ds, std::vector<T> &list)
{
int entries;
ds >> entries;
for (int i = 0; i < entries; i++)
{
T entry;
ds >> entry;
list.emplace_back(std::move(entry));
}
return ds;
}
template<typename Tkey, typename Tvalue>
QDataStream &operator<<(QDataStream &ds, const std::map<Tkey, Tvalue> &map)
{
{
int entries = map.size();
ds << entries;
}
for (auto iter = std::cbegin(map); iter != std::cend(map); iter++)
ds << iter->first << iter->second;
return ds;
}
template<typename Tkey, typename Tvalue>
QDataStream &operator>>(QDataStream &ds, std::map<Tkey, Tvalue> &map)
{
int entries;
ds >> entries;
for (int i = 0; i < entries; i++)
{
Tkey key;
Tvalue value;
ds >> key
>> value;
map[std::move(key)] = std::move(value);
}
return ds;
}
template<typename ...T>
QDataStream &operator<<(QDataStream &ds, const std::variant<T...> &variant)
{
int index = variant.index();
ds << index;
using func_t = void(QDataStream&, const std::variant<T...> &);
static constexpr func_t *funcs[] = {
[](QDataStream& ds, const std::variant<T...> &variant) {
ds << std::get<T>(variant);
}...
};
funcs[index](ds, variant);
return ds;
}
// for idiotic GCC we cannot use the usual lambda syntax but instead
// have to provide a template method, GCC sucks
template<typename T, typename ...Tvariant>
std::variant<Tvariant...> variantUnpacker(QDataStream& ds)
{
T value;
ds >> value;
return value;
}
template<typename ...T>
QDataStream &operator>>(QDataStream &ds, std::variant<T...> &variant)
{
int index;
ds >> index;
using func_t = std::variant<T...> (QDataStream&);
static constexpr func_t *funcs[] = {
variantUnpacker<T, T...>...
};
variant = funcs[index](ds);
return ds;
}
QDataStream &operator<<(QDataStream &ds, const GlobalGameSettings &globalGameSettings)
{
Q_UNUSED(globalGameSettings);
//ds << globalGameSettings.;
return ds;
}
QDataStream &operator>>(QDataStream &ds, GlobalGameSettings &globalGameSettings)
{
Q_UNUSED(globalGameSettings);
//ds >> globalGameSettings.;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Sprite &sprite)
{
ds << sprite.name
<< sprite.pixmaps
<< sprite.origin.x
<< sprite.origin.y
<< sprite.preciseCollisionChecking
<< sprite.separateCollisionMasks;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Sprite &sprite)
{
ds >> sprite.name
>> sprite.pixmaps
>> sprite.origin.x
>> sprite.origin.y
>> sprite.preciseCollisionChecking
>> sprite.separateCollisionMasks;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Sound &sound)
{
ds << sound.name
<< sound.type
<< sound.path
<< sound.effects.chorus
<< sound.effects.flanger
<< sound.effects.gargle
<< sound.effects.echo
<< sound.effects.reverb
<< sound.volume
<< sound.pan
<< sound.preload;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Sound &sound)
{
ds >> sound.name
>> sound.type
>> sound.path
>> sound.effects.chorus
>> sound.effects.flanger
>> sound.effects.gargle
>> sound.effects.echo
>> sound.effects.reverb
>> sound.volume
>> sound.pan
>> sound.preload;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Background &background)
{
ds << background.name
<< background.pixmap
<< background.tileset;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Background &background)
{
ds >> background.name
>> background.pixmap
>> background.tileset;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Path::Point &point)
{
ds << point.point
<< point.sp;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Path::Point &point)
{
ds >> point.point
>> point.sp;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Path &path)
{
ds << path.name
<< path.points
<< path.type
<< path.closed
<< path.precision
<< path.snapX
<< path.snapY
<< path.gridEnabled;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Path &path)
{
ds >> path.name
>> path.points
>> path.type
>> path.closed
>> path.precision
>> path.snapX
>> path.snapY
>> path.gridEnabled;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Script &script)
{
ds << script.name
<< script.script;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Script &script)
{
ds >> script.name
>> script.script;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Font &font)
{
ds << font.name
<< font.font;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Font &font)
{
ds >> font.name
>> font.font;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const MoveFixedAction &action)
{
Q_UNUSED(action);
// ds << action.;
return ds;
}
QDataStream &operator>>(QDataStream &ds, MoveFixedAction &action)
{
Q_UNUSED(action);
// ds >> action.;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const MoveFreeAction &action)
{
Q_UNUSED(action);
// ds << action.;
return ds;
}
QDataStream &operator>>(QDataStream &ds, MoveFreeAction &action)
{
Q_UNUSED(action);
// ds >> action.;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const MoveTowardsAction &action)
{
Q_UNUSED(action);
// ds << action.;
return ds;
}
QDataStream &operator>>(QDataStream &ds, MoveTowardsAction &action)
{
Q_UNUSED(action);
// ds >> action.;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const ExecuteCodeAction &action)
{
ds << action.script;
ds << action.appliesTo;
return ds;
}
QDataStream &operator>>(QDataStream &ds, ExecuteCodeAction &action)
{
ds >> action.script;
ds >> action.appliesTo;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const TimeLine &timeLine)
{
ds << timeLine.name
<< timeLine.moments;
return ds;
}
QDataStream &operator>>(QDataStream &ds, TimeLine &timeLine)
{
ds >> timeLine.name
>> timeLine.moments;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Object &object)
{
ds << object.name
<< object.spriteName
<< object.visible
<< object.solid
<< object.depth
<< object.persistent
<< object.parentName
<< object.events
<< object.collisionEvents;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Object &object)
{
ds >> object.name
>> object.spriteName
>> object.visible
>> object.solid
>> object.depth
>> object.persistent
>> object.parentName
>> object.events
>> object.collisionEvents;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Room::Object &object)
{
ds << object.objectName
<< object.pos;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Room::Object &object)
{
ds >> object.objectName
>> object.pos;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Room &room)
{
ds << room.name
<< room.caption
<< room.width
<< room.height
<< room.speed
<< room.persistent
<< room.creationCode
<< room.snapX
<< room.snapY
<< room.gridEnabled
<< room.isometricGrid
<< room.objects;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Room &room)
{
ds >> room.name
>> room.caption
>> room.width
>> room.height
>> room.speed
>> room.persistent
>> room.creationCode
>> room.snapX
>> room.snapY
>> room.gridEnabled
>> room.isometricGrid
>> room.objects;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const ProjectContainer &project)
{
ds << project.globalGameSettings
<< project.sprites
<< project.sounds
<< project.backgrounds
<< project.paths
<< project.scripts
<< project.fonts
<< project.timeLines
<< project.objects
<< project.rooms;
return ds;
}
QDataStream &operator>>(QDataStream &ds, ProjectContainer &project)
{
ds >> project.globalGameSettings
>> project.sprites
>> project.sounds
>> project.backgrounds
>> project.paths
>> project.scripts
>> project.fonts
>> project.timeLines
>> project.objects
>> project.rooms;
return ds;
}

View File

@@ -8,7 +8,6 @@
#include <QString> #include <QString>
#include <QPixmap> #include <QPixmap>
#include <QFont> #include <QFont>
#include <QDataStream>
#include <QPoint> #include <QPoint>
struct GlobalGameSettings struct GlobalGameSettings
@@ -222,6 +221,3 @@ struct ProjectContainer
template<typename T> std::list<T> &containerFor(); template<typename T> std::list<T> &containerFor();
template<typename T> const std::list<T> &containerFor() const; template<typename T> const std::list<T> &containerFor() const;
}; };
QDataStream &operator<<(QDataStream &ds, const ProjectContainer &project);
QDataStream &operator>>(QDataStream &ds, ProjectContainer &project);

View File

@@ -0,0 +1,331 @@
#include "projectserialization.h"
#include "stdserialization.h"
QDataStream &operator<<(QDataStream &ds, const GlobalGameSettings &globalGameSettings)
{
Q_UNUSED(globalGameSettings);
//ds << globalGameSettings.;
return ds;
}
QDataStream &operator>>(QDataStream &ds, GlobalGameSettings &globalGameSettings)
{
Q_UNUSED(globalGameSettings);
//ds >> globalGameSettings.;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Sprite &sprite)
{
ds << sprite.name
<< sprite.pixmaps
<< sprite.origin.x
<< sprite.origin.y
<< sprite.preciseCollisionChecking
<< sprite.separateCollisionMasks;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Sprite &sprite)
{
ds >> sprite.name
>> sprite.pixmaps
>> sprite.origin.x
>> sprite.origin.y
>> sprite.preciseCollisionChecking
>> sprite.separateCollisionMasks;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Sound &sound)
{
ds << sound.name
<< sound.type
<< sound.path
<< sound.effects.chorus
<< sound.effects.flanger
<< sound.effects.gargle
<< sound.effects.echo
<< sound.effects.reverb
<< sound.volume
<< sound.pan
<< sound.preload;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Sound &sound)
{
ds >> sound.name
>> sound.type
>> sound.path
>> sound.effects.chorus
>> sound.effects.flanger
>> sound.effects.gargle
>> sound.effects.echo
>> sound.effects.reverb
>> sound.volume
>> sound.pan
>> sound.preload;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Background &background)
{
ds << background.name
<< background.pixmap
<< background.tileset;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Background &background)
{
ds >> background.name
>> background.pixmap
>> background.tileset;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Path::Point &point)
{
ds << point.point
<< point.sp;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Path::Point &point)
{
ds >> point.point
>> point.sp;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Path &path)
{
ds << path.name
<< path.points
<< path.type
<< path.closed
<< path.precision
<< path.snapX
<< path.snapY
<< path.gridEnabled;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Path &path)
{
ds >> path.name
>> path.points
>> path.type
>> path.closed
>> path.precision
>> path.snapX
>> path.snapY
>> path.gridEnabled;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Script &script)
{
ds << script.name
<< script.script;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Script &script)
{
ds >> script.name
>> script.script;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Font &font)
{
ds << font.name
<< font.font;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Font &font)
{
ds >> font.name
>> font.font;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const MoveFixedAction &action)
{
Q_UNUSED(action);
// ds << action.;
return ds;
}
QDataStream &operator>>(QDataStream &ds, MoveFixedAction &action)
{
Q_UNUSED(action);
// ds >> action.;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const MoveFreeAction &action)
{
Q_UNUSED(action);
// ds << action.;
return ds;
}
QDataStream &operator>>(QDataStream &ds, MoveFreeAction &action)
{
Q_UNUSED(action);
// ds >> action.;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const MoveTowardsAction &action)
{
Q_UNUSED(action);
// ds << action.;
return ds;
}
QDataStream &operator>>(QDataStream &ds, MoveTowardsAction &action)
{
Q_UNUSED(action);
// ds >> action.;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const ExecuteCodeAction &action)
{
ds << action.script;
ds << action.appliesTo;
return ds;
}
QDataStream &operator>>(QDataStream &ds, ExecuteCodeAction &action)
{
ds >> action.script;
ds >> action.appliesTo;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const TimeLine &timeLine)
{
ds << timeLine.name
<< timeLine.moments;
return ds;
}
QDataStream &operator>>(QDataStream &ds, TimeLine &timeLine)
{
ds >> timeLine.name
>> timeLine.moments;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Object &object)
{
ds << object.name
<< object.spriteName
<< object.visible
<< object.solid
<< object.depth
<< object.persistent
<< object.parentName
<< object.events
<< object.collisionEvents;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Object &object)
{
ds >> object.name
>> object.spriteName
>> object.visible
>> object.solid
>> object.depth
>> object.persistent
>> object.parentName
>> object.events
>> object.collisionEvents;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Room::Object &object)
{
ds << object.objectName
<< object.pos;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Room::Object &object)
{
ds >> object.objectName
>> object.pos;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Room &room)
{
ds << room.name
<< room.caption
<< room.width
<< room.height
<< room.speed
<< room.persistent
<< room.creationCode
<< room.snapX
<< room.snapY
<< room.gridEnabled
<< room.isometricGrid
<< room.objects;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Room &room)
{
ds >> room.name
>> room.caption
>> room.width
>> room.height
>> room.speed
>> room.persistent
>> room.creationCode
>> room.snapX
>> room.snapY
>> room.gridEnabled
>> room.isometricGrid
>> room.objects;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const ProjectContainer &project)
{
ds << project.globalGameSettings
<< project.sprites
<< project.sounds
<< project.backgrounds
<< project.paths
<< project.scripts
<< project.fonts
<< project.timeLines
<< project.objects
<< project.rooms;
return ds;
}
QDataStream &operator>>(QDataStream &ds, ProjectContainer &project)
{
ds >> project.globalGameSettings
>> project.sprites
>> project.sounds
>> project.backgrounds
>> project.paths
>> project.scripts
>> project.fonts
>> project.timeLines
>> project.objects
>> project.rooms;
return ds;
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include <QDataStream>
#include "projectcontainer.h"
QDataStream &operator<<(QDataStream &ds, const GlobalGameSettings &globalGameSettings);
QDataStream &operator>>(QDataStream &ds, GlobalGameSettings &globalGameSettings);
QDataStream &operator<<(QDataStream &ds, const Sprite &sprite);
QDataStream &operator>>(QDataStream &ds, Sprite &sprite);
QDataStream &operator<<(QDataStream &ds, const Sound &sound);
QDataStream &operator>>(QDataStream &ds, Sound &sound);
QDataStream &operator<<(QDataStream &ds, const Background &background);
QDataStream &operator>>(QDataStream &ds, Background &background);
QDataStream &operator<<(QDataStream &ds, const Path::Point &point);
QDataStream &operator>>(QDataStream &ds, Path::Point &point);
QDataStream &operator<<(QDataStream &ds, const Path &path);
QDataStream &operator>>(QDataStream &ds, Path &path);
QDataStream &operator<<(QDataStream &ds, const Script &script);
QDataStream &operator>>(QDataStream &ds, Script &script);
QDataStream &operator<<(QDataStream &ds, const Font &font);
QDataStream &operator>>(QDataStream &ds, Font &font);
QDataStream &operator<<(QDataStream &ds, const MoveFixedAction &action);
QDataStream &operator>>(QDataStream &ds, MoveFixedAction &action);
QDataStream &operator<<(QDataStream &ds, const MoveFreeAction &action);
QDataStream &operator>>(QDataStream &ds, MoveFreeAction &action);
QDataStream &operator<<(QDataStream &ds, const MoveTowardsAction &action);
QDataStream &operator>>(QDataStream &ds, MoveTowardsAction &action);
QDataStream &operator<<(QDataStream &ds, const ExecuteCodeAction &action);
QDataStream &operator>>(QDataStream &ds, ExecuteCodeAction &action);
QDataStream &operator<<(QDataStream &ds, const TimeLine &timeLine);
QDataStream &operator>>(QDataStream &ds, TimeLine &timeLine);
QDataStream &operator<<(QDataStream &ds, const Object &object);
QDataStream &operator>>(QDataStream &ds, Object &object);
QDataStream &operator<<(QDataStream &ds, const Room::Object &object);
QDataStream &operator>>(QDataStream &ds, Room::Object &object);
QDataStream &operator<<(QDataStream &ds, const Room &room);
QDataStream &operator>>(QDataStream &ds, Room &room);
QDataStream &operator<<(QDataStream &ds, const ProjectContainer &project);;
QDataStream &operator>>(QDataStream &ds, ProjectContainer &project);;

152
src/stdserialization.h Normal file
View File

@@ -0,0 +1,152 @@
#pragma once
#include <QDataStream>
#include <array>
#include <list>
#include <vector>
#include <map>
#include <variant>
template<typename T, std::size_t Tsize>
QDataStream &operator<<(QDataStream &ds, const std::array<T, Tsize> &array)
{
for (const auto &entry : array)
ds << entry;
return ds;
}
template<typename T, std::size_t Tsize>
QDataStream &operator>>(QDataStream &ds, std::array<T, Tsize> &array)
{
for (size_t i = 0; i < Tsize; i++)
ds >> array[i];
return ds;
}
template<typename T>
QDataStream &operator<<(QDataStream &ds, const std::list<T> &list)
{
{
int entries = list.size();
ds << entries;
}
for (const auto &entry : list)
ds << entry;
return ds;
}
template<typename T>
QDataStream &operator>>(QDataStream &ds, std::list<T> &list)
{
int entries;
ds >> entries;
for (int i = 0; i < entries; i++)
{
T entry;
ds >> entry;
list.emplace_back(std::move(entry));
}
return ds;
}
template<typename T>
QDataStream &operator<<(QDataStream &ds, const std::vector<T> &list)
{
{
int entries = list.size();
ds << entries;
}
for (const auto &entry : list)
ds << entry;
return ds;
}
template<typename T>
QDataStream &operator>>(QDataStream &ds, std::vector<T> &list)
{
int entries;
ds >> entries;
for (int i = 0; i < entries; i++)
{
T entry;
ds >> entry;
list.emplace_back(std::move(entry));
}
return ds;
}
template<typename Tkey, typename Tvalue>
QDataStream &operator<<(QDataStream &ds, const std::map<Tkey, Tvalue> &map)
{
{
int entries = map.size();
ds << entries;
}
for (auto iter = std::cbegin(map); iter != std::cend(map); iter++)
ds << iter->first << iter->second;
return ds;
}
template<typename Tkey, typename Tvalue>
QDataStream &operator>>(QDataStream &ds, std::map<Tkey, Tvalue> &map)
{
int entries;
ds >> entries;
for (int i = 0; i < entries; i++)
{
Tkey key;
Tvalue value;
ds >> key
>> value;
map[std::move(key)] = std::move(value);
}
return ds;
}
template<typename ...T>
QDataStream &operator<<(QDataStream &ds, const std::variant<T...> &variant)
{
int index = variant.index();
ds << index;
using func_t = void(QDataStream&, const std::variant<T...> &);
static constexpr func_t *funcs[] = {
[](QDataStream& ds, const std::variant<T...> &variant) {
ds << std::get<T>(variant);
}...
};
funcs[index](ds, variant);
return ds;
}
namespace detail {
// for idiotic GCC we cannot use the usual lambda syntax but instead
// have to provide a template method, GCC sucks
template<typename T, typename ...Tvariant>
std::variant<Tvariant...> variantUnpacker(QDataStream& ds)
{
T value;
ds >> value;
return value;
}
}
template<typename ...T>
QDataStream &operator>>(QDataStream &ds, std::variant<T...> &variant)
{
int index;
ds >> index;
using func_t = std::variant<T...> (QDataStream&);
static constexpr func_t *funcs[] = {
detail::variantUnpacker<T, T...>...
};
variant = funcs[index](ds);
return ds;
}