change: change code style to Linux style except indent.

This commit is contained in:
Mike Solar
2025-08-03 03:09:40 +08:00
parent 65ab76edc8
commit 74f73ab3be
789 changed files with 77113 additions and 68888 deletions
+214 -189
View File
@@ -34,274 +34,299 @@
#include "serializer220403.h"
#include "serializer230220.h"
namespace olive {
namespace olive
{
QVector<ProjectSerializer*> ProjectSerializer::instances_;
QVector<ProjectSerializer *> ProjectSerializer::instances_;
void ProjectSerializer::Initialize()
{
// Make sure to order these from oldest to newest
// Make sure to order these from oldest to newest
// FIXME: Implement this - yes it's a 0.1 project loader
//instances_.append(new ProjectSerializer190219);
// FIXME: Implement this - yes it's a 0.1 project loader
//instances_.append(new ProjectSerializer190219);
instances_.append(new ProjectSerializer210528);
instances_.append(new ProjectSerializer210907);
instances_.append(new ProjectSerializer211228);
instances_.append(new ProjectSerializer220403);
instances_.append(new ProjectSerializer230220);
instances_.append(new ProjectSerializer210528);
instances_.append(new ProjectSerializer210907);
instances_.append(new ProjectSerializer211228);
instances_.append(new ProjectSerializer220403);
instances_.append(new ProjectSerializer230220);
}
void ProjectSerializer::Destroy()
{
qDeleteAll(instances_);
instances_.clear();
qDeleteAll(instances_);
instances_.clear();
}
ProjectSerializer::Result ProjectSerializer::Load(Project *project, const QString &filename, LoadType load_type)
ProjectSerializer::Result ProjectSerializer::Load(Project *project,
const QString &filename,
LoadType load_type)
{
QFile project_file(filename);
QFile project_file(filename);
if (project_file.open(QFile::ReadOnly)) {
// Some project files are compressed, marked with "OVEC" at the beginning of the file. Check for
// that signature now.
std::unique_ptr<QXmlStreamReader> reader;
if (CheckCompressedID(&project_file)) {
// File is compressed, decompress into memory
QByteArray b;
b = qUncompress(project_file.readAll());
reader.reset(new QXmlStreamReader(b));
} else {
project_file.seek(0);
reader.reset(new QXmlStreamReader(&project_file));
}
if (project_file.open(QFile::ReadOnly)) {
// Some project files are compressed, marked with "OVEC" at the beginning of the file. Check for
// that signature now.
std::unique_ptr<QXmlStreamReader> reader;
if (CheckCompressedID(&project_file)) {
// File is compressed, decompress into memory
QByteArray b;
b = qUncompress(project_file.readAll());
reader.reset(new QXmlStreamReader(b));
} else {
project_file.seek(0);
reader.reset(new QXmlStreamReader(&project_file));
}
Result inner_result = Load(project, reader.get(), load_type);
Result inner_result = Load(project, reader.get(), load_type);
project_file.close();
project_file.close();
if (inner_result.code() != kSuccess) {
return inner_result;
}
if (inner_result.code() != kSuccess) {
return inner_result;
}
if (reader->hasError()) {
Result r(kXmlError);
r.SetDetails(reader->errorString());
return r;
} else {
return inner_result;
}
} else {
return kFileError;
}
if (reader->hasError()) {
Result r(kXmlError);
r.SetDetails(reader->errorString());
return r;
} else {
return inner_result;
}
} else {
return kFileError;
}
}
ProjectSerializer::Result ProjectSerializer::Load(Project *project, QXmlStreamReader *reader, LoadType load_type)
ProjectSerializer::Result ProjectSerializer::Load(Project *project,
QXmlStreamReader *reader,
LoadType load_type)
{
// Determine project version
uint version = 0;
Result res = kUnknownVersion;
// Determine project version
uint version = 0;
Result res = kUnknownVersion;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("olive")
|| reader->name() == QStringLiteral("project")) { // 0.1 projects only
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("olive") ||
reader->name() == QStringLiteral("project")) { // 0.1 projects only
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("version")) { // 230220+ projects
version = attr.value().toUInt();
} else if (reader->name() == QStringLiteral("url")) { // 230220+ projects
project->SetSavedURL(attr.value().toString());
}
}
XMLAttributeLoop(reader, attr)
{
if (attr.name() ==
QStringLiteral("version")) { // 230220+ projects
version = attr.value().toUInt();
} else if (reader->name() ==
QStringLiteral("url")) { // 230220+ projects
project->SetSavedURL(attr.value().toString());
}
}
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("version")) { // projects <= 220403
version = reader->readElementText().toUInt();
} else if (reader->name() == QStringLiteral("url")) { // projects <= 220403
if (project) {
project->SetSavedURL(reader->readElementText());
} else {
reader->skipCurrentElement();
}
} else {
// Handle any other value with the serializer
res = LoadWithSerializerVersion(version, project, reader, load_type);
}
}
} else {
reader->skipCurrentElement();
}
}
while (XMLReadNextStartElement(reader)) {
if (reader->name() ==
QStringLiteral("version")) { // projects <= 220403
version = reader->readElementText().toUInt();
} else if (reader->name() ==
QStringLiteral("url")) { // projects <= 220403
if (project) {
project->SetSavedURL(reader->readElementText());
} else {
reader->skipCurrentElement();
}
} else {
// Handle any other value with the serializer
res = LoadWithSerializerVersion(version, project, reader,
load_type);
}
}
} else {
reader->skipCurrentElement();
}
}
return res;
return res;
}
ProjectSerializer::Result ProjectSerializer::Paste(LoadType load_type, Project *project)
ProjectSerializer::Result ProjectSerializer::Paste(LoadType load_type,
Project *project)
{
QString clipboard = Core::PasteStringFromClipboard();
if (clipboard.isEmpty()) {
return kNoData;
}
QString clipboard = Core::PasteStringFromClipboard();
if (clipboard.isEmpty()) {
return kNoData;
}
QXmlStreamReader reader(clipboard);
QXmlStreamReader reader(clipboard);
return ProjectSerializer::Load(project, &reader, load_type);
return ProjectSerializer::Load(project, &reader, load_type);
}
ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data, bool compress)
ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data,
bool compress)
{
QString temp_save = FileFunctions::GetSafeTemporaryFilename(data.GetFilename());
QString temp_save =
FileFunctions::GetSafeTemporaryFilename(data.GetFilename());
QFile project_file(temp_save);
QFile project_file(temp_save);
if (project_file.open(QFile::WriteOnly)) {
QByteArray b;
QXmlStreamWriter writer(&b);
if (project_file.open(QFile::WriteOnly)) {
QByteArray b;
QXmlStreamWriter writer(&b);
Result inner_result = Save(&writer, data);
Result inner_result = Save(&writer, data);
if (writer.hasError()) {
Result r(kXmlError);
return r;
}
if (writer.hasError()) {
Result r(kXmlError);
return r;
}
if (compress) {
project_file.write("OVEC");
project_file.write(qCompress(b));
} else {
project_file.write(b);
}
if (compress) {
project_file.write("OVEC");
project_file.write(qCompress(b));
} else {
project_file.write(b);
}
project_file.close();
project_file.close();
if (inner_result != kSuccess) {
return inner_result;
}
if (inner_result != kSuccess) {
return inner_result;
}
// Save was successful, we can now rewrite the original file
if (FileFunctions::RenameFileAllowOverwrite(temp_save, data.GetFilename())) {
return kSuccess;
} else {
Result r(kOverwriteError);
r.SetDetails(temp_save);
return r;
}
} else {
Result r(kFileError);
r.SetDetails(temp_save);
return r;
}
// Save was successful, we can now rewrite the original file
if (FileFunctions::RenameFileAllowOverwrite(temp_save,
data.GetFilename())) {
return kSuccess;
} else {
Result r(kOverwriteError);
r.SetDetails(temp_save);
return r;
}
} else {
Result r(kFileError);
r.SetDetails(temp_save);
return r;
}
}
ProjectSerializer::Result ProjectSerializer::Save(QXmlStreamWriter *writer, const SaveData &data)
ProjectSerializer::Result ProjectSerializer::Save(QXmlStreamWriter *writer,
const SaveData &data)
{
writer->setAutoFormatting(true);
writer->setAutoFormatting(true);
writer->writeStartDocument();
writer->writeStartDocument();
writer->writeStartElement("olive");
writer->writeStartElement("olive");
// By default, save as last serializer which, assuming the instances are ordered correctly,
// will be the newest file format. But we may allow saving as older versions later on.
ProjectSerializer *serializer = instances_.last();
// By default, save as last serializer which, assuming the instances are ordered correctly,
// will be the newest file format. But we may allow saving as older versions later on.
ProjectSerializer *serializer = instances_.last();
// Version is stored in YYMMDD from whenever the project format was last changed
// Allows easy integer math for checking project versions.
writer->writeAttribute(QStringLiteral("version"), QString::number(serializer->Version()));
// Version is stored in YYMMDD from whenever the project format was last changed
// Allows easy integer math for checking project versions.
writer->writeAttribute(QStringLiteral("version"),
QString::number(serializer->Version()));
if (!data.GetFilename().isEmpty()) {
writer->writeAttribute("url", data.GetFilename());
}
if (!data.GetFilename().isEmpty()) {
writer->writeAttribute("url", data.GetFilename());
}
serializer->Save(writer, data, nullptr);
serializer->Save(writer, data, nullptr);
writer->writeEndElement(); // olive
writer->writeEndElement(); // olive
writer->writeEndDocument();
writer->writeEndDocument();
if (writer->hasError()) {
return kXmlError;
}
if (writer->hasError()) {
return kXmlError;
}
return kSuccess;
return kSuccess;
}
ProjectSerializer::Result ProjectSerializer::Copy(const SaveData &data)
{
QString copy_str;
QXmlStreamWriter writer(&copy_str);
QString copy_str;
QXmlStreamWriter writer(&copy_str);
ProjectSerializer::Result res = ProjectSerializer::Save(&writer, data);
ProjectSerializer::Result res = ProjectSerializer::Save(&writer, data);
if (res == kSuccess) {
Core::CopyStringToClipboard(copy_str);
}
if (res == kSuccess) {
Core::CopyStringToClipboard(copy_str);
}
return res;
return res;
}
bool ProjectSerializer::CheckCompressedID(QFile *file)
{
QByteArray b = file->read(4);
return !memcmp(b.data(), "OVEC", 4);
QByteArray b = file->read(4);
return !memcmp(b.data(), "OVEC", 4);
}
bool ProjectSerializer::IsCancelled() const
{
return false;
return false;
}
ProjectSerializer::Result ProjectSerializer::LoadWithSerializerVersion(uint version, Project *project, QXmlStreamReader *reader, LoadType load_type)
ProjectSerializer::Result
ProjectSerializer::LoadWithSerializerVersion(uint version, Project *project,
QXmlStreamReader *reader,
LoadType load_type)
{
// Failed to find version in file
if (version == 0) {
return kUnknownVersion;
}
// Failed to find version in file
if (version == 0) {
return kUnknownVersion;
}
// We should now have the version, if we have a serializer for it, use it to load the project
ProjectSerializer *serializer = nullptr;
// We should now have the version, if we have a serializer for it, use it to load the project
ProjectSerializer *serializer = nullptr;
foreach (ProjectSerializer *s, instances_) {
if (version == s->Version()) {
serializer = s;
break;
} else if (version < s->Version()) {
// Assuming the instance list is in order, if the project version is less than any version
// we find, we must not support it anymore
return kProjectTooOld;
}
}
foreach (ProjectSerializer *s, instances_) {
if (version == s->Version()) {
serializer = s;
break;
} else if (version < s->Version()) {
// Assuming the instance list is in order, if the project version is less than any version
// we find, we must not support it anymore
return kProjectTooOld;
}
}
if (serializer) {
LoadData ld = serializer->Load(project, reader, load_type, nullptr);
Result r(kSuccess);
if (reader->hasError()) {
r = Result(kXmlError);
r.SetDetails(QCoreApplication::translate("Serializer", "%1 on line %2").arg(reader->errorString(), QString::number(reader->lineNumber())));
}
r.SetLoadData(ld);
return r;
} else {
// Reached the end of the list with no serializer, assume too new
return kProjectTooNew;
}
if (serializer) {
LoadData ld = serializer->Load(project, reader, load_type, nullptr);
Result r(kSuccess);
if (reader->hasError()) {
r = Result(kXmlError);
r.SetDetails(
QCoreApplication::translate("Serializer", "%1 on line %2")
.arg(reader->errorString(),
QString::number(reader->lineNumber())));
}
r.SetLoadData(ld);
return r;
} else {
// Reached the end of the list with no serializer, assume too new
return kProjectTooNew;
}
}
void ProjectSerializer::SaveData::SetOnlySerializeNodesAndResolveGroups(QVector<Node *> nodes)
void ProjectSerializer::SaveData::SetOnlySerializeNodesAndResolveGroups(
QVector<Node *> nodes)
{
// For any groups, add children
for (int i=0; i<nodes.size(); i++) {
// If this is a group, add the child nodes too
if (NodeGroup *g = dynamic_cast<NodeGroup*>(nodes.at(i))) {
for (auto it=g->GetContextPositions().cbegin(); it!=g->GetContextPositions().cend(); it++) {
if (!nodes.contains(it.key())) {
nodes.append(it.key());
}
}
}
}
// For any groups, add children
for (int i = 0; i < nodes.size(); i++) {
// If this is a group, add the child nodes too
if (NodeGroup *g = dynamic_cast<NodeGroup *>(nodes.at(i))) {
for (auto it = g->GetContextPositions().cbegin();
it != g->GetContextPositions().cend(); it++) {
if (!nodes.contains(it.key())) {
nodes.append(it.key());
}
}
}
}
SetOnlySerializeNodes(nodes);
SetOnlySerializeNodes(nodes);
}
}
+179 -109
View File
@@ -27,7 +27,8 @@
#include "node/project.h"
#include "typeserializer.h"
namespace olive {
namespace olive
{
/**
* @brief An abstract base class for serializing/deserializing project data
@@ -35,167 +36,236 @@ namespace olive {
* The goal of this is to further abstract serialized project data from their
* in-memory representations.
*/
class ProjectSerializer
{
class ProjectSerializer {
public:
enum LoadType
{
kProject,
kOnlyNodes,
kOnlyClips,
kOnlyMarkers,
kOnlyKeyframes
};
enum LoadType {
kProject,
kOnlyNodes,
kOnlyClips,
kOnlyMarkers,
kOnlyKeyframes
};
ProjectSerializer() = default;
ProjectSerializer() = default;
virtual ~ProjectSerializer(){}
virtual ~ProjectSerializer()
{
}
DISABLE_COPY_MOVE(ProjectSerializer)
DISABLE_COPY_MOVE(ProjectSerializer)
enum ResultCode {
kSuccess,
kProjectTooOld,
kProjectTooNew,
kUnknownVersion,
kFileError,
kXmlError,
kOverwriteError,
kNoData
};
enum ResultCode {
kSuccess,
kProjectTooOld,
kProjectTooNew,
kUnknownVersion,
kFileError,
kXmlError,
kOverwriteError,
kNoData
};
using SerializedProperties = QHash<Node*, QMap<QString, QString> >;
using SerializedKeyframes = QHash<QString, QVector<NodeKeyframe*> >;
using SerializedProperties = QHash<Node *, QMap<QString, QString>>;
using SerializedKeyframes = QHash<QString, QVector<NodeKeyframe *>>;
class LoadData
{
public:
LoadData() = default;
class LoadData {
public:
LoadData() = default;
SerializedProperties properties;
SerializedProperties properties;
std::vector<TimelineMarker*> markers;
std::vector<TimelineMarker *> markers;
SerializedKeyframes keyframes;
SerializedKeyframes keyframes;
MainWindowLayoutInfo layout;
MainWindowLayoutInfo layout;
QVector<Node*> nodes;
QVector<Node *> nodes;
Node::OutputConnections promised_connections;
Node::OutputConnections promised_connections;
};
};
class Result {
public:
Result(const ResultCode &code)
: code_(code)
{
}
class Result
{
public:
Result(const ResultCode &code) :
code_(code)
{}
bool operator==(const ResultCode &code)
{
return code_ == code;
}
bool operator!=(const ResultCode &code)
{
return code_ != code;
}
bool operator==(const ResultCode &code) { return code_ == code; }
bool operator!=(const ResultCode &code) { return code_ != code; }
const ResultCode &code() const
{
return code_;
}
const ResultCode &code() const { return code_; }
const QString &GetDetails() const
{
return details_;
}
const QString &GetDetails() const { return details_; }
void SetDetails(const QString &s)
{
details_ = s;
}
void SetDetails(const QString &s) { details_ = s; }
const LoadData &GetLoadData() const
{
return load_data_;
}
const LoadData &GetLoadData() const { return load_data_; }
void SetLoadData(const LoadData &p)
{
load_data_ = p;
}
void SetLoadData(const LoadData &p) { load_data_ = p; }
private:
ResultCode code_;
private:
ResultCode code_;
QString details_;
QString details_;
LoadData load_data_;
};
LoadData load_data_;
class SaveData {
public:
SaveData(LoadType type, Project *project = nullptr,
const QString &filename = QString())
{
type_ = type;
project_ = project;
filename_ = filename;
}
};
Project *GetProject() const
{
return project_;
}
void SetProject(Project *p)
{
project_ = p;
}
class SaveData
{
public:
SaveData(LoadType type, Project *project = nullptr, const QString &filename = QString())
{
type_ = type;
project_ = project;
filename_ = filename;
}
const QString &GetFilename() const
{
return filename_;
}
void SetFilename(const QString &s)
{
filename_ = s;
}
Project *GetProject() const { return project_; }
void SetProject(Project *p) { project_ = p; }
LoadType type() const
{
return type_;
}
const QString &GetFilename() const { return filename_; }
void SetFilename(const QString &s) { filename_ = s; }
const MainWindowLayoutInfo &GetLayout() const
{
return layout_;
}
void SetLayout(const MainWindowLayoutInfo &layout)
{
layout_ = layout;
}
LoadType type() const { return type_; }
const QVector<Node *> &GetOnlySerializeNodes() const
{
return only_serialize_nodes_;
}
void SetOnlySerializeNodes(const QVector<Node *> &only)
{
only_serialize_nodes_ = only;
}
void SetOnlySerializeNodesAndResolveGroups(QVector<Node *> only);
const MainWindowLayoutInfo &GetLayout() const { return layout_; }
void SetLayout(const MainWindowLayoutInfo &layout) { layout_ = layout; }
const std::vector<TimelineMarker *> &GetOnlySerializeMarkers() const
{
return only_serialize_markers_;
}
void SetOnlySerializeMarkers(const std::vector<TimelineMarker *> &only)
{
only_serialize_markers_ = only;
}
const QVector<Node*> &GetOnlySerializeNodes() const { return only_serialize_nodes_; }
void SetOnlySerializeNodes(const QVector<Node*> &only) { only_serialize_nodes_ = only; }
void SetOnlySerializeNodesAndResolveGroups(QVector<Node*> only);
const std::vector<NodeKeyframe *> &GetOnlySerializeKeyframes() const
{
return only_serialize_keyframes_;
}
void SetOnlySerializeKeyframes(const std::vector<NodeKeyframe *> &only)
{
only_serialize_keyframes_ = only;
}
const std::vector<TimelineMarker*> &GetOnlySerializeMarkers() const { return only_serialize_markers_; }
void SetOnlySerializeMarkers(const std::vector<TimelineMarker*> &only) { only_serialize_markers_ = only; }
const SerializedProperties &GetProperties() const
{
return properties_;
}
void SetProperties(const SerializedProperties &p)
{
properties_ = p;
}
const std::vector<NodeKeyframe*> &GetOnlySerializeKeyframes() const { return only_serialize_keyframes_; }
void SetOnlySerializeKeyframes(const std::vector<NodeKeyframe*> &only) { only_serialize_keyframes_ = only; }
private:
LoadType type_;
const SerializedProperties &GetProperties() const { return properties_; }
void SetProperties(const SerializedProperties &p) { properties_ = p; }
Project *project_;
private:
LoadType type_;
QString filename_;
Project *project_;
MainWindowLayoutInfo layout_;
QString filename_;
QVector<Node *> only_serialize_nodes_;
MainWindowLayoutInfo layout_;
SerializedProperties properties_;
QVector<Node*> only_serialize_nodes_;
std::vector<TimelineMarker *> only_serialize_markers_;
SerializedProperties properties_;
std::vector<NodeKeyframe *> only_serialize_keyframes_;
};
std::vector<TimelineMarker*> only_serialize_markers_;
static void Initialize();
std::vector<NodeKeyframe*> only_serialize_keyframes_;
static void Destroy();
};
static Result Load(Project *project, const QString &filename,
LoadType load_type);
static Result Load(Project *project, QXmlStreamReader *read_device,
LoadType load_type);
static Result Paste(LoadType load_type, Project *project = nullptr);
static void Initialize();
static Result Save(const SaveData &data, bool compress);
static Result Save(QXmlStreamWriter *write_device, const SaveData &data);
static Result Copy(const SaveData &data);
static void Destroy();
static Result Load(Project *project, const QString &filename, LoadType load_type);
static Result Load(Project *project, QXmlStreamReader *read_device, LoadType load_type);
static Result Paste(LoadType load_type, Project *project = nullptr);
static Result Save(const SaveData &data, bool compress);
static Result Save(QXmlStreamWriter *write_device, const SaveData &data);
static Result Copy(const SaveData &data);
static bool CheckCompressedID(QFile *file);
static bool CheckCompressedID(QFile *file);
protected:
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const = 0;
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const = 0;
virtual void Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const {}
virtual void Save(QXmlStreamWriter *writer, const SaveData &data,
void *reserved) const
{
}
virtual uint Version() const = 0;
virtual uint Version() const = 0;
bool IsCancelled() const;
bool IsCancelled() const;
private:
static Result LoadWithSerializerVersion(uint version, Project *project, QXmlStreamReader *reader, LoadType load_type);
static QVector<ProjectSerializer*> instances_;
static Result LoadWithSerializerVersion(uint version, Project *project,
QXmlStreamReader *reader,
LoadType load_type);
static QVector<ProjectSerializer *> instances_;
};
}
@@ -20,11 +20,14 @@
#include "serializer190219.h"
namespace olive {
ProjectSerializer::LoadData ProjectSerializer190219::Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const
namespace olive
{
return LoadData();
ProjectSerializer::LoadData
ProjectSerializer190219::Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const
{
return LoadData();
}
}
+10 -10
View File
@@ -23,21 +23,21 @@
#include "serializer.h"
namespace olive {
class ProjectSerializer190219 : public ProjectSerializer
namespace olive
{
class ProjectSerializer190219 : public ProjectSerializer {
public:
ProjectSerializer190219() = default;
ProjectSerializer190219() = default;
protected:
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
virtual uint Version() const override
{
return 190219;
}
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const override;
virtual uint Version() const override
{
return 190219;
}
};
}
File diff suppressed because it is too large Load Diff
+53 -45
View File
@@ -23,73 +23,81 @@
#include "serializer.h"
namespace olive {
class ProjectSerializer210528 : public ProjectSerializer
namespace olive
{
class ProjectSerializer210528 : public ProjectSerializer {
public:
ProjectSerializer210528() = default;
ProjectSerializer210528() = default;
protected:
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const override;
virtual uint Version() const override
{
return 210528;
}
virtual uint Version() const override
{
return 210528;
}
private:
struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
QString output_param;
};
struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
QString output_param;
};
struct BlockLink {
Node* block;
quintptr link;
};
struct BlockLink {
Node *block;
quintptr link;
};
struct GroupLink {
NodeGroup *group;
quintptr input_node;
QString input_id;
int input_element;
};
struct GroupLink {
NodeGroup *group;
quintptr input_node;
QString input_id;
int input_element;
};
QHash<quintptr, Node*> node_ptrs;
QList<SerializedConnection> desired_connections;
QList<BlockLink> block_links;
QVector<GroupLink> group_input_links;
QHash<NodeGroup*, quintptr> group_output_links;
QHash<quintptr, Node *> node_ptrs;
QList<SerializedConnection> desired_connections;
QList<BlockLink> block_links;
QVector<GroupLink> group_input_links;
QHash<NodeGroup *, quintptr> group_output_links;
};
};
void LoadNode(Node *node, XMLNodeData &xml_node_data,
QXmlStreamReader *reader) const;
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
void LoadColorManager(QXmlStreamReader *reader, Project *project) const;
void LoadColorManager(QXmlStreamReader* reader, Project *project) const;
void LoadProjectSettings(QXmlStreamReader *reader, Project *project) const;
void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const;
void LoadInput(Node *node, QXmlStreamReader *reader,
XMLNodeData &xml_node_data) const;
void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const;
void LoadImmediate(QXmlStreamReader *reader, Node *node,
const QString &input, int element,
XMLNodeData &xml_node_data) const;
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr,
Node::Position *pos) const;
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
void PostConnect(const XMLNodeData &xml_node_data) const;
void PostConnect(const XMLNodeData &xml_node_data) const;
void LoadNodeCustom(QXmlStreamReader *reader, Node *node,
XMLNodeData &xml_node_data) const;
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
void LoadTimelinePoints(QXmlStreamReader *reader,
ViewerOutput *points) const;
void LoadTimelinePoints(QXmlStreamReader *reader, ViewerOutput *points) const;
void LoadWorkArea(QXmlStreamReader *reader,
TimelineWorkArea *workarea) const;
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
void LoadMarkerList(QXmlStreamReader *reader,
TimelineMarkerList *markers) const;
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
};
}
File diff suppressed because it is too large Load Diff
+52 -44
View File
@@ -23,72 +23,80 @@
#include "serializer.h"
namespace olive {
class ProjectSerializer210907 : public ProjectSerializer
namespace olive
{
class ProjectSerializer210907 : public ProjectSerializer {
public:
ProjectSerializer210907() = default;
ProjectSerializer210907() = default;
protected:
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const override;
virtual uint Version() const override
{
return 210907;
}
virtual uint Version() const override
{
return 210907;
}
private:
struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
};
struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
};
struct BlockLink {
Node* block;
quintptr link;
};
struct BlockLink {
Node *block;
quintptr link;
};
struct GroupLink {
NodeGroup *group;
quintptr input_node;
QString input_id;
int input_element;
};
struct GroupLink {
NodeGroup *group;
quintptr input_node;
QString input_id;
int input_element;
};
QHash<quintptr, Node*> node_ptrs;
QList<SerializedConnection> desired_connections;
QList<BlockLink> block_links;
QVector<GroupLink> group_input_links;
QHash<NodeGroup*, quintptr> group_output_links;
QHash<quintptr, Node *> node_ptrs;
QList<SerializedConnection> desired_connections;
QList<BlockLink> block_links;
QVector<GroupLink> group_input_links;
QHash<NodeGroup *, quintptr> group_output_links;
};
};
void LoadNode(Node *node, XMLNodeData &xml_node_data,
QXmlStreamReader *reader) const;
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
void LoadColorManager(QXmlStreamReader *reader, Project *project) const;
void LoadColorManager(QXmlStreamReader* reader, Project *project) const;
void LoadProjectSettings(QXmlStreamReader *reader, Project *project) const;
void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const;
void LoadInput(Node *node, QXmlStreamReader *reader,
XMLNodeData &xml_node_data) const;
void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const;
void LoadImmediate(QXmlStreamReader *reader, Node *node,
const QString &input, int element,
XMLNodeData &xml_node_data) const;
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr,
Node::Position *pos) const;
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
void PostConnect(const XMLNodeData &xml_node_data) const;
void PostConnect(const XMLNodeData &xml_node_data) const;
void LoadNodeCustom(QXmlStreamReader *reader, Node *node,
XMLNodeData &xml_node_data) const;
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
void LoadTimelinePoints(QXmlStreamReader *reader,
ViewerOutput *points) const;
void LoadTimelinePoints(QXmlStreamReader *reader, ViewerOutput *points) const;
void LoadWorkArea(QXmlStreamReader *reader,
TimelineWorkArea *workarea) const;
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
void LoadMarkerList(QXmlStreamReader *reader,
TimelineMarkerList *markers) const;
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
};
}
File diff suppressed because it is too large Load Diff
+53 -45
View File
@@ -23,73 +23,81 @@
#include "serializer.h"
namespace olive {
class ProjectSerializer211228 : public ProjectSerializer
namespace olive
{
class ProjectSerializer211228 : public ProjectSerializer {
public:
ProjectSerializer211228() = default;
ProjectSerializer211228() = default;
protected:
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const override;
virtual uint Version() const override
{
return 211228;
}
virtual uint Version() const override
{
return 211228;
}
private:
struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
};
struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
};
struct BlockLink {
Node* block;
quintptr link;
};
struct BlockLink {
Node *block;
quintptr link;
};
struct GroupLink {
NodeGroup *group;
quintptr input_node;
QString input_id;
int input_element;
};
struct GroupLink {
NodeGroup *group;
quintptr input_node;
QString input_id;
int input_element;
};
QHash<quintptr, Node*> node_ptrs;
QList<SerializedConnection> desired_connections;
QList<BlockLink> block_links;
QVector<GroupLink> group_input_links;
QHash<NodeGroup*, quintptr> group_output_links;
QHash<Node*, QUuid> node_uuids;
QHash<quintptr, Node *> node_ptrs;
QList<SerializedConnection> desired_connections;
QList<BlockLink> block_links;
QVector<GroupLink> group_input_links;
QHash<NodeGroup *, quintptr> group_output_links;
QHash<Node *, QUuid> node_uuids;
};
};
void LoadNode(Node *node, XMLNodeData &xml_node_data,
QXmlStreamReader *reader) const;
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
void LoadColorManager(QXmlStreamReader *reader, Project *project) const;
void LoadColorManager(QXmlStreamReader* reader, Project *project) const;
void LoadProjectSettings(QXmlStreamReader *reader, Project *project) const;
void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const;
void LoadInput(Node *node, QXmlStreamReader *reader,
XMLNodeData &xml_node_data) const;
void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const;
void LoadImmediate(QXmlStreamReader *reader, Node *node,
const QString &input, int element,
XMLNodeData &xml_node_data) const;
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr,
Node::Position *pos) const;
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
void PostConnect(const XMLNodeData &xml_node_data) const;
void PostConnect(const XMLNodeData &xml_node_data) const;
void LoadNodeCustom(QXmlStreamReader *reader, Node *node,
XMLNodeData &xml_node_data) const;
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
void LoadTimelinePoints(QXmlStreamReader *reader,
ViewerOutput *points) const;
void LoadTimelinePoints(QXmlStreamReader *reader, ViewerOutput *points) const;
void LoadWorkArea(QXmlStreamReader *reader,
TimelineWorkArea *workarea) const;
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
void LoadMarkerList(QXmlStreamReader *reader,
TimelineMarkerList *markers) const;
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
};
}
File diff suppressed because it is too large Load Diff
+62 -53
View File
@@ -23,83 +23,92 @@
#include "serializer.h"
namespace olive {
class ProjectSerializer220403 : public ProjectSerializer
namespace olive
{
class ProjectSerializer220403 : public ProjectSerializer {
public:
ProjectSerializer220403() = default;
ProjectSerializer220403() = default;
protected:
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const override;
virtual uint Version() const override
{
return 220403;
}
virtual uint Version() const override
{
return 220403;
}
private:
struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
};
struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
};
struct BlockLink {
Node* block;
quintptr link;
};
struct BlockLink {
Node *block;
quintptr link;
};
struct GroupLink {
NodeGroup *group;
QString passthrough_id;
quintptr input_node;
QString input_id;
int input_element;
QString custom_name;
InputFlags custom_flags;
NodeValue::Type data_type;
QVariant default_val;
QHash<QString, QVariant> custom_properties;
};
struct GroupLink {
NodeGroup *group;
QString passthrough_id;
quintptr input_node;
QString input_id;
int input_element;
QString custom_name;
InputFlags custom_flags;
NodeValue::Type data_type;
QVariant default_val;
QHash<QString, QVariant> custom_properties;
};
QHash<quintptr, Node*> node_ptrs;
QList<SerializedConnection> desired_connections;
QList<BlockLink> block_links;
QVector<GroupLink> group_input_links;
QHash<NodeGroup*, quintptr> group_output_links;
QHash<Node*, QUuid> node_uuids;
QHash<quintptr, Node *> node_ptrs;
QList<SerializedConnection> desired_connections;
QList<BlockLink> block_links;
QVector<GroupLink> group_input_links;
QHash<NodeGroup *, quintptr> group_output_links;
QHash<Node *, QUuid> node_uuids;
};
};
void LoadNode(Node *node, XMLNodeData &xml_node_data,
QXmlStreamReader *reader) const;
void LoadNode(Node *node, XMLNodeData &xml_node_data, QXmlStreamReader *reader) const;
void LoadColorManager(QXmlStreamReader *reader, Project *project) const;
void LoadColorManager(QXmlStreamReader* reader, Project *project) const;
void LoadProjectSettings(QXmlStreamReader *reader, Project *project) const;
void LoadProjectSettings(QXmlStreamReader* reader, Project *project) const;
void LoadInput(Node *node, QXmlStreamReader *reader,
XMLNodeData &xml_node_data) const;
void LoadInput(Node *node, QXmlStreamReader* reader, XMLNodeData &xml_node_data) const;
void LoadImmediate(QXmlStreamReader *reader, Node *node,
const QString &input, int element,
XMLNodeData &xml_node_data) const;
void LoadImmediate(QXmlStreamReader *reader, Node *node, const QString& input, int element, XMLNodeData& xml_node_data) const;
void LoadKeyframe(QXmlStreamReader *reader, NodeKeyframe *key,
NodeValue::Type data_type) const;
void LoadKeyframe(QXmlStreamReader *reader, NodeKeyframe *key, NodeValue::Type data_type) const;
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr,
Node::Position *pos) const;
bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos) const;
void PostConnect(const XMLNodeData &xml_node_data) const;
void PostConnect(const XMLNodeData &xml_node_data) const;
void LoadNodeCustom(QXmlStreamReader *reader, Node *node,
XMLNodeData &xml_node_data) const;
void LoadNodeCustom(QXmlStreamReader *reader, Node *node, XMLNodeData &xml_node_data) const;
void LoadTimelinePoints(QXmlStreamReader *reader,
ViewerOutput *viewer) const;
void LoadTimelinePoints(QXmlStreamReader *reader, ViewerOutput *viewer) const;
void LoadMarker(QXmlStreamReader *reader, TimelineMarker *marker) const;
void LoadMarker(QXmlStreamReader *reader, TimelineMarker *marker) const;
void LoadWorkArea(QXmlStreamReader *reader,
TimelineWorkArea *workarea) const;
void LoadWorkArea(QXmlStreamReader *reader, TimelineWorkArea *workarea) const;
void LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const;
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
void LoadMarkerList(QXmlStreamReader *reader,
TimelineMarkerList *markers) const;
void LoadValueHint(Node::ValueHint *hint, QXmlStreamReader *reader) const;
};
}
+501 -433
View File
@@ -26,459 +26,527 @@
#include "node/group/group.h"
#include "node/serializeddata.h"
#include <QtCore>
namespace olive {
ProjectSerializer230220::LoadData ProjectSerializer230220::Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const
namespace olive
{
QMap<quintptr, QMap<QString, QString> > properties;
QMap<quintptr, QMap<quintptr, Node::Position> > positions;
LoadData load_data;
SerializedData project_data;
switch (load_type) {
case kProject:
{
if (reader->name() == QStringLiteral("project")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("project")) {
project_data = project->Load(reader);
} else if (reader->name() == QStringLiteral("layout")) {
load_data.layout = MainWindowLayoutInfo::fromXml(reader, project_data.node_ptrs);
} else {
reader->skipCurrentElement();
}
}
PostConnect(project->nodes(), &project_data);
} else {
reader->skipCurrentElement();
}
break;
}
case kOnlyMarkers:
{
if (reader->name() == QStringLiteral("markers")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("marker")) {
TimelineMarker *marker = new TimelineMarker();
marker->load(reader);
load_data.markers.push_back(marker);
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
break;
}
case kOnlyKeyframes:
{
if (reader->name() == QStringLiteral("keyframes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
QString node_id;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
node_id = attr.value().toString();
break;
}
}
Node *n = nullptr;
if (!node_id.isEmpty()) {
n = NodeFactory::CreateFromID(node_id);
}
if (!n) {
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("input")) {
QString input_id;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
input_id = attr.value().toString();
break;
}
}
if (input_id.isEmpty()) {
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("element")) {
QString element_id;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
element_id = attr.value().toString();
break;
}
}
if (element_id.isEmpty()) {
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("track")) {
QString track_id;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
track_id = attr.value().toString();
break;
}
}
if (track_id.isEmpty()) {
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("key")) {
NodeKeyframe *key = new NodeKeyframe();
key->set_input(input_id);
key->set_element(element_id.toInt());
key->set_track(track_id.toInt());
key->load(reader, n->GetInputDataType(input_id));
load_data.keyframes[node_id].append(key);
} else {
reader->skipCurrentElement();
}
}
}
} else {
reader->skipCurrentElement();
}
}
}
} else {
reader->skipCurrentElement();
}
}
}
} else {
reader->skipCurrentElement();
}
}
}
delete n;
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
break;
}
case kOnlyClips:
case kOnlyNodes:
{
if ((load_type == kOnlyNodes && reader->name() == QStringLiteral("nodes")) || (load_type == kOnlyClips && reader->name() == QStringLiteral("timeline"))) {
QMap<quintptr, Node*> skipped_items;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
QString id;
quintptr ptr = 0;
QVector<quintptr> items;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("ptr")) {
ptr = attr.value().toULongLong();
} else if (attr.name() == QStringLiteral("items")) {
QVector<QStringView> l = attr.value().split(',');
items.reserve(l.size());
for (const QStringView &s : l) {
items.append(s.toULongLong());
}
}
}
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
bool dependency_of_item = false;
if (project && !items.empty()) {
for (quintptr p : items) {
if (project->nodes().contains(reinterpret_cast<Node*>(p))) {
dependency_of_item = true;
break;
}
}
}
if (dependency_of_item) {
reader->skipCurrentElement();
} else {
Node* node = NodeFactory::CreateFromID(id);
if (!node) {
qWarning() << "Failed to find node with ID" << id;
reader->skipCurrentElement();
} else {
if (project && node->IsItem() && ptr) {
// If we're pasting an object into the same project, we should re-use the item
// rather than duplicate.
Node *existing = reinterpret_cast<Node *>(ptr);
if (project->nodes().contains(existing)) {
// Connect this
skipped_items.insert(ptr, existing);
// Don't continue loading this
delete node;
node = nullptr;
// Skip element
reader->skipCurrentElement();
}
}
if (node) {
// Disable cache while node is being loaded (we'll re-enable it later)
node->SetCachesEnabled(false);
node->Load(reader, &project_data);
load_data.nodes.append(node);
}
}
}
}
} else if (reader->name() == QStringLiteral("properties")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr ptr = 0;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
ptr = attr.value().toULongLong();
// Only attribute we're looking for right now
break;
}
}
if (ptr) {
QMap<QString, QString> properties_for_node;
while (XMLReadNextStartElement(reader)) {
properties_for_node.insert(reader->name().toString(), reader->readElementText());
}
properties.insert(ptr, properties_for_node);
}
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
}
if (!skipped_items.empty()) {
for (auto it = project_data.desired_connections.begin(); it != project_data.desired_connections.end(); ) {
const SerializedData::SerializedConnection &sc = *it;
if (Node *si = skipped_items.value(sc.output_node)) {
// Convert this to a promised connection
Node::OutputConnection oc = {si, sc.input};
load_data.promised_connections.push_back(oc);
it = project_data.desired_connections.erase(it);
} else {
it++;
}
}
}
// Resolve serialized properties (if any)
for (auto it=properties.cbegin(); it!=properties.cend(); it++) {
Node *node = project_data.node_ptrs.value(it.key());
if (node) {
load_data.properties.insert(node, it.value());
}
}
PostConnect(load_data.nodes, &project_data);
} else {
reader->skipCurrentElement();
}
break;
}
}
return load_data;
}
void WriteNodeMap(QXmlStreamWriter *writer, Node *node, const QVector<Node*> &nodes)
ProjectSerializer230220::LoadData
ProjectSerializer230220::Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const
{
writer->writeStartElement(QStringLiteral("node"));
QMap<quintptr, QMap<QString, QString>> properties;
QMap<quintptr, QMap<quintptr, Node::Position>> positions;
LoadData load_data;
SerializedData project_data;
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(node)));
switch (load_type) {
case kProject: {
if (reader->name() == QStringLiteral("project")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("project")) {
project_data = project->Load(reader);
} else if (reader->name() == QStringLiteral("layout")) {
load_data.layout = MainWindowLayoutInfo::fromXml(
reader, project_data.node_ptrs);
} else {
reader->skipCurrentElement();
}
}
for (auto oc : node->output_connections()) {
if (nodes.contains(oc.second.node())) {
WriteNodeMap(writer, oc.second.node(), nodes);
}
}
PostConnect(project->nodes(), &project_data);
} else {
reader->skipCurrentElement();
}
break;
}
case kOnlyMarkers: {
if (reader->name() == QStringLiteral("markers")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("marker")) {
TimelineMarker *marker = new TimelineMarker();
marker->load(reader);
load_data.markers.push_back(marker);
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
break;
}
case kOnlyKeyframes: {
if (reader->name() == QStringLiteral("keyframes")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
QString node_id;
XMLAttributeLoop(reader, attr)
{
if (attr.name() == QStringLiteral("id")) {
node_id = attr.value().toString();
break;
}
}
writer->writeEndElement();
Node *n = nullptr;
if (!node_id.isEmpty()) {
n = NodeFactory::CreateFromID(node_id);
}
if (!n) {
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("input")) {
QString input_id;
XMLAttributeLoop(reader, attr)
{
if (attr.name() == QStringLiteral("id")) {
input_id = attr.value().toString();
break;
}
}
if (input_id.isEmpty()) {
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(reader)) {
if (reader->name() ==
QStringLiteral("element")) {
QString element_id;
XMLAttributeLoop(reader, attr)
{
if (attr.name() ==
QStringLiteral("id")) {
element_id =
attr.value().toString();
break;
}
}
if (element_id.isEmpty()) {
reader->skipCurrentElement();
} else {
while (XMLReadNextStartElement(
reader)) {
if (reader->name() ==
QStringLiteral(
"track")) {
QString track_id;
XMLAttributeLoop(reader,
attr)
{
if (attr.name() ==
QStringLiteral(
"id")) {
track_id =
attr.value()
.toString();
break;
}
}
if (track_id.isEmpty()) {
reader
->skipCurrentElement();
} else {
while (
XMLReadNextStartElement(
reader)) {
if (reader
->name() ==
QStringLiteral(
"key")) {
NodeKeyframe *key =
new NodeKeyframe();
key->set_input(
input_id);
key->set_element(
element_id
.toInt());
key->set_track(
track_id
.toInt());
key->load(
reader,
n->GetInputDataType(
input_id));
load_data
.keyframes
[node_id]
.append(
key);
} else {
reader
->skipCurrentElement();
}
}
}
} else {
reader
->skipCurrentElement();
}
}
}
} else {
reader->skipCurrentElement();
}
}
}
} else {
reader->skipCurrentElement();
}
}
}
delete n;
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
break;
}
case kOnlyClips:
case kOnlyNodes: {
if ((load_type == kOnlyNodes &&
reader->name() == QStringLiteral("nodes")) ||
(load_type == kOnlyClips &&
reader->name() == QStringLiteral("timeline"))) {
QMap<quintptr, Node *> skipped_items;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
QString id;
quintptr ptr = 0;
QVector<quintptr> items;
XMLAttributeLoop(reader, attr)
{
if (attr.name() == QStringLiteral("id")) {
id = attr.value().toString();
} else if (attr.name() == QStringLiteral("ptr")) {
ptr = attr.value().toULongLong();
} else if (attr.name() == QStringLiteral("items")) {
QVector<QStringView> l = attr.value().split(',');
items.reserve(l.size());
for (const QStringView &s : l) {
items.append(s.toULongLong());
}
}
}
if (id.isEmpty()) {
qWarning() << "Failed to load node with empty ID";
reader->skipCurrentElement();
} else {
bool dependency_of_item = false;
if (project && !items.empty()) {
for (quintptr p : items) {
if (project->nodes().contains(
reinterpret_cast<Node *>(p))) {
dependency_of_item = true;
break;
}
}
}
if (dependency_of_item) {
reader->skipCurrentElement();
} else {
Node *node = NodeFactory::CreateFromID(id);
if (!node) {
qWarning()
<< "Failed to find node with ID" << id;
reader->skipCurrentElement();
} else {
if (project && node->IsItem() && ptr) {
// If we're pasting an object into the same project, we should re-use the item
// rather than duplicate.
Node *existing =
reinterpret_cast<Node *>(ptr);
if (project->nodes().contains(existing)) {
// Connect this
skipped_items.insert(ptr, existing);
// Don't continue loading this
delete node;
node = nullptr;
// Skip element
reader->skipCurrentElement();
}
}
if (node) {
// Disable cache while node is being loaded (we'll re-enable it later)
node->SetCachesEnabled(false);
node->Load(reader, &project_data);
load_data.nodes.append(node);
}
}
}
}
} else if (reader->name() == QStringLiteral("properties")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
quintptr ptr = 0;
XMLAttributeLoop(reader, attr)
{
if (attr.name() == QStringLiteral("ptr")) {
ptr = attr.value().toULongLong();
// Only attribute we're looking for right now
break;
}
}
if (ptr) {
QMap<QString, QString> properties_for_node;
while (XMLReadNextStartElement(reader)) {
properties_for_node.insert(
reader->name().toString(),
reader->readElementText());
}
properties.insert(ptr, properties_for_node);
}
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
}
if (!skipped_items.empty()) {
for (auto it = project_data.desired_connections.begin();
it != project_data.desired_connections.end();) {
const SerializedData::SerializedConnection &sc = *it;
if (Node *si = skipped_items.value(sc.output_node)) {
// Convert this to a promised connection
Node::OutputConnection oc = { si, sc.input };
load_data.promised_connections.push_back(oc);
it = project_data.desired_connections.erase(it);
} else {
it++;
}
}
}
// Resolve serialized properties (if any)
for (auto it = properties.cbegin(); it != properties.cend(); it++) {
Node *node = project_data.node_ptrs.value(it.key());
if (node) {
load_data.properties.insert(node, it.value());
}
}
PostConnect(load_data.nodes, &project_data);
} else {
reader->skipCurrentElement();
}
break;
}
}
return load_data;
}
void ProjectSerializer230220::Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const
void WriteNodeMap(QXmlStreamWriter *writer, Node *node,
const QVector<Node *> &nodes)
{
if (!data.GetOnlySerializeMarkers().empty()) {
writer->writeStartElement(QStringLiteral("markers"));
writer->writeStartElement(QStringLiteral("node"));
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
writer->writeAttribute(QStringLiteral("ptr"),
QString::number(reinterpret_cast<quintptr>(node)));
for (auto it=data.GetOnlySerializeMarkers().cbegin(); it!=data.GetOnlySerializeMarkers().cend(); it++) {
TimelineMarker *marker = *it;
writer->writeStartElement(QStringLiteral("marker"));
marker->save(writer);
writer->writeEndElement(); // marker
}
for (auto oc : node->output_connections()) {
if (nodes.contains(oc.second.node())) {
WriteNodeMap(writer, oc.second.node(), nodes);
}
}
writer->writeEndElement(); // markers
} else if (!data.GetOnlySerializeKeyframes().empty()) {
writer->writeStartElement(QStringLiteral("keyframes"));
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
// Organize keyframes into node+input
QHash<QString, QHash<QString, QMap<int, QMap<int, QVector<NodeKeyframe*> > > > > organized;
for (auto it=data.GetOnlySerializeKeyframes().cbegin(); it!=data.GetOnlySerializeKeyframes().cend(); it++) {
NodeKeyframe *key = *it;
organized[key->parent()->id()][key->input()][key->element()][key->track()].append(key);
}
for (auto it=organized.cbegin(); it!=organized.cend(); it++) {
writer->writeStartElement(QStringLiteral("node"));
writer->writeAttribute(QStringLiteral("id"), it.key());
for (auto jt=it.value().cbegin(); jt!=it.value().cend(); jt++) {
writer->writeStartElement(QStringLiteral("input"));
writer->writeAttribute(QStringLiteral("id"), jt.key());
for (auto kt=jt.value().cbegin(); kt!=jt.value().cend(); kt++) {
writer->writeStartElement(QStringLiteral("element"));
writer->writeAttribute(QStringLiteral("id"), QString::number(kt.key()));
for (auto lt=kt.value().cbegin(); lt!=kt.value().cend(); lt++) {
const QVector<NodeKeyframe *> &keys = lt.value();
writer->writeStartElement(QStringLiteral("track"));
writer->writeAttribute(QStringLiteral("id"), QString::number(lt.key()));
for (NodeKeyframe *key : keys) {
writer->writeStartElement(QStringLiteral("key"));
key->save(writer, key->parent()->GetInputDataType(key->input()));
writer->writeEndElement(); // key
}
writer->writeEndElement(); // track
}
writer->writeEndElement(); // element
}
writer->writeEndElement(); // input
}
writer->writeEndElement(); // node;
}
writer->writeEndElement(); // keyframes
} else if (!data.GetOnlySerializeNodes().empty()) {
if (data.type() == kOnlyClips) {
writer->writeStartElement(QStringLiteral("timeline"));
} else {
writer->writeStartElement(QStringLiteral("nodes"));
}
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
for (Node *n : data.GetOnlySerializeNodes()) {
writer->writeStartElement(QStringLiteral("node"));
QStringList item_list;
for (Node *i : data.GetOnlySerializeNodes()) {
if (i->IsItem() && i->InputsFrom(n, true)) {
item_list.append(QString::number(reinterpret_cast<quintptr>(i)));
}
}
if (!item_list.empty()) {
writer->writeAttribute(QStringLiteral("items"), item_list.join(','));
}
n->Save(writer);
writer->writeEndElement(); // node
}
if (!data.GetProperties().empty()) {
writer->writeStartElement(QStringLiteral("properties"));
for (auto it=data.GetProperties().cbegin(); it!=data.GetProperties().cend(); it++) {
writer->writeStartElement(QStringLiteral("node"));
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(it.key())));
for (auto jt=it.value().cbegin(); jt!=it.value().cend(); jt++) {
writer->writeTextElement(jt.key(), jt.value());
}
writer->writeEndElement(); // node
}
writer->writeEndElement(); // properties
}
writer->writeEndElement(); // nodes
} else if (Project *project = data.GetProject()) {
writer->writeStartElement(QStringLiteral("project"));
writer->writeStartElement(QStringLiteral("project"));
project->Save(writer);
writer->writeEndElement(); // project
writer->writeStartElement(QStringLiteral("layout"));
data.GetLayout().toXml(writer);
writer->writeEndElement(); // layout
writer->writeEndElement(); // project
} else {
qCritical() << "ProjectSerializer provided nothing to save";
}
writer->writeEndElement();
}
void ProjectSerializer230220::PostConnect(const QVector<Node *> &nodes, SerializedData *project_data) const
void ProjectSerializer230220::Save(QXmlStreamWriter *writer,
const SaveData &data, void *reserved) const
{
foreach (const SerializedData::SerializedConnection& con, project_data->desired_connections) {
if (Node *out = project_data->node_ptrs.value(con.output_node)) {
Node::ConnectEdge(out, con.input);
}
}
if (!data.GetOnlySerializeMarkers().empty()) {
writer->writeStartElement(QStringLiteral("markers"));
foreach (const SerializedData::BlockLink& l, project_data->block_links) {
Node *a = l.block;
Node *b = project_data->node_ptrs.value(l.link);
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
Node::Link(a, b);
}
for (auto it = data.GetOnlySerializeMarkers().cbegin();
it != data.GetOnlySerializeMarkers().cend(); it++) {
TimelineMarker *marker = *it;
writer->writeStartElement(QStringLiteral("marker"));
marker->save(writer);
writer->writeEndElement(); // marker
}
for (auto it = nodes.cbegin(); it != nodes.cend(); it++){
Node *n = *it;
writer->writeEndElement(); // markers
} else if (!data.GetOnlySerializeKeyframes().empty()) {
writer->writeStartElement(QStringLiteral("keyframes"));
n->PostLoadEvent(project_data);
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
n->SetCachesEnabled(true);
}
// Organize keyframes into node+input
QHash<QString,
QHash<QString, QMap<int, QMap<int, QVector<NodeKeyframe *>>>>>
organized;
for (auto it = data.GetOnlySerializeKeyframes().cbegin();
it != data.GetOnlySerializeKeyframes().cend(); it++) {
NodeKeyframe *key = *it;
organized[key->parent()->id()][key->input()][key->element()]
[key->track()]
.append(key);
}
for (auto it = organized.cbegin(); it != organized.cend(); it++) {
writer->writeStartElement(QStringLiteral("node"));
writer->writeAttribute(QStringLiteral("id"), it.key());
for (auto jt = it.value().cbegin(); jt != it.value().cend(); jt++) {
writer->writeStartElement(QStringLiteral("input"));
writer->writeAttribute(QStringLiteral("id"), jt.key());
for (auto kt = jt.value().cbegin(); kt != jt.value().cend();
kt++) {
writer->writeStartElement(QStringLiteral("element"));
writer->writeAttribute(QStringLiteral("id"),
QString::number(kt.key()));
for (auto lt = kt.value().cbegin(); lt != kt.value().cend();
lt++) {
const QVector<NodeKeyframe *> &keys = lt.value();
writer->writeStartElement(QStringLiteral("track"));
writer->writeAttribute(QStringLiteral("id"),
QString::number(lt.key()));
for (NodeKeyframe *key : keys) {
writer->writeStartElement(QStringLiteral("key"));
key->save(writer, key->parent()->GetInputDataType(
key->input()));
writer->writeEndElement(); // key
}
writer->writeEndElement(); // track
}
writer->writeEndElement(); // element
}
writer->writeEndElement(); // input
}
writer->writeEndElement(); // node;
}
writer->writeEndElement(); // keyframes
} else if (!data.GetOnlySerializeNodes().empty()) {
if (data.type() == kOnlyClips) {
writer->writeStartElement(QStringLiteral("timeline"));
} else {
writer->writeStartElement(QStringLiteral("nodes"));
}
writer->writeAttribute(QStringLiteral("version"), QString::number(1));
for (Node *n : data.GetOnlySerializeNodes()) {
writer->writeStartElement(QStringLiteral("node"));
QStringList item_list;
for (Node *i : data.GetOnlySerializeNodes()) {
if (i->IsItem() && i->InputsFrom(n, true)) {
item_list.append(
QString::number(reinterpret_cast<quintptr>(i)));
}
}
if (!item_list.empty()) {
writer->writeAttribute(QStringLiteral("items"),
item_list.join(','));
}
n->Save(writer);
writer->writeEndElement(); // node
}
if (!data.GetProperties().empty()) {
writer->writeStartElement(QStringLiteral("properties"));
for (auto it = data.GetProperties().cbegin();
it != data.GetProperties().cend(); it++) {
writer->writeStartElement(QStringLiteral("node"));
writer->writeAttribute(
QStringLiteral("ptr"),
QString::number(reinterpret_cast<quintptr>(it.key())));
for (auto jt = it.value().cbegin(); jt != it.value().cend();
jt++) {
writer->writeTextElement(jt.key(), jt.value());
}
writer->writeEndElement(); // node
}
writer->writeEndElement(); // properties
}
writer->writeEndElement(); // nodes
} else if (Project *project = data.GetProject()) {
writer->writeStartElement(QStringLiteral("project"));
writer->writeStartElement(QStringLiteral("project"));
project->Save(writer);
writer->writeEndElement(); // project
writer->writeStartElement(QStringLiteral("layout"));
data.GetLayout().toXml(writer);
writer->writeEndElement(); // layout
writer->writeEndElement(); // project
} else {
qCritical() << "ProjectSerializer provided nothing to save";
}
}
void ProjectSerializer230220::PostConnect(const QVector<Node *> &nodes,
SerializedData *project_data) const
{
foreach (const SerializedData::SerializedConnection &con,
project_data->desired_connections) {
if (Node *out = project_data->node_ptrs.value(con.output_node)) {
Node::ConnectEdge(out, con.input);
}
}
foreach (const SerializedData::BlockLink &l, project_data->block_links) {
Node *a = l.block;
Node *b = project_data->node_ptrs.value(l.link);
Node::Link(a, b);
}
for (auto it = nodes.cbegin(); it != nodes.cend(); it++) {
Node *n = *it;
n->PostLoadEvent(project_data);
n->SetCachesEnabled(true);
}
}
}
+14 -12
View File
@@ -23,26 +23,28 @@
#include "serializer.h"
namespace olive {
class ProjectSerializer230220 : public ProjectSerializer
namespace olive
{
class ProjectSerializer230220 : public ProjectSerializer {
public:
ProjectSerializer230220() = default;
ProjectSerializer230220() = default;
protected:
virtual LoadData Load(Project *project, QXmlStreamReader *reader, LoadType load_type, void *reserved) const override;
virtual LoadData Load(Project *project, QXmlStreamReader *reader,
LoadType load_type, void *reserved) const override;
virtual void Save(QXmlStreamWriter *writer, const SaveData &data, void *reserved) const override;
virtual void Save(QXmlStreamWriter *writer, const SaveData &data,
void *reserved) const override;
virtual uint Version() const override
{
return 230220;
}
virtual uint Version() const override
{
return 230220;
}
private:
void PostConnect(const QVector<Node*> &nodes, SerializedData *project_data) const;
void PostConnect(const QVector<Node *> &nodes,
SerializedData *project_data) const;
};
}
+41 -30
View File
@@ -20,44 +20,55 @@
#include "typeserializer.h"
namespace olive {
namespace olive
{
AudioParams TypeSerializer::LoadAudioParams(QXmlStreamReader *reader)
{
AudioParams a;
AudioParams a;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("samplerate")) {
a.set_sample_rate(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("channellayout")) {
a.set_channel_layout(reader->readElementText().toULongLong());
} else if (reader->name() == QStringLiteral("format")) {
a.set_format(SampleFormat::from_string(reader->readElementText().toStdString()));
} else if (reader->name() == QStringLiteral("enabled")) {
a.set_enabled(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("streamindex")) {
a.set_stream_index(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("duration")) {
a.set_duration(reader->readElementText().toLongLong());
} else if (reader->name() == QStringLiteral("timebase")) {
a.set_time_base(rational::fromString(reader->readElementText().toStdString()));
} else {
reader->skipCurrentElement();
}
}
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("samplerate")) {
a.set_sample_rate(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("channellayout")) {
a.set_channel_layout(reader->readElementText().toULongLong());
} else if (reader->name() == QStringLiteral("format")) {
a.set_format(SampleFormat::from_string(
reader->readElementText().toStdString()));
} else if (reader->name() == QStringLiteral("enabled")) {
a.set_enabled(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("streamindex")) {
a.set_stream_index(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("duration")) {
a.set_duration(reader->readElementText().toLongLong());
} else if (reader->name() == QStringLiteral("timebase")) {
a.set_time_base(
rational::fromString(reader->readElementText().toStdString()));
} else {
reader->skipCurrentElement();
}
}
return a;
return a;
}
void TypeSerializer::SaveAudioParams(QXmlStreamWriter *writer, const AudioParams &a)
void TypeSerializer::SaveAudioParams(QXmlStreamWriter *writer,
const AudioParams &a)
{
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(a.sample_rate()));
writer->writeTextElement(QStringLiteral("channellayout"), QString::number(a.channel_layout().u.mask));
writer->writeTextElement(QStringLiteral("format"), QString::fromStdString(a.format().to_string()));
writer->writeTextElement(QStringLiteral("enabled"), QString::number(a.enabled()));
writer->writeTextElement(QStringLiteral("streamindex"), QString::number(a.stream_index()));
writer->writeTextElement(QStringLiteral("duration"), QString::number(a.duration()));
writer->writeTextElement(QStringLiteral("timebase"), QString::fromStdString(a.time_base().toString()));
writer->writeTextElement(QStringLiteral("samplerate"),
QString::number(a.sample_rate()));
writer->writeTextElement(QStringLiteral("channellayout"),
QString::number(a.channel_layout().u.mask));
writer->writeTextElement(QStringLiteral("format"),
QString::fromStdString(a.format().to_string()));
writer->writeTextElement(QStringLiteral("enabled"),
QString::number(a.enabled()));
writer->writeTextElement(QStringLiteral("streamindex"),
QString::number(a.stream_index()));
writer->writeTextElement(QStringLiteral("duration"),
QString::number(a.duration()));
writer->writeTextElement(QStringLiteral("timebase"),
QString::fromStdString(a.time_base().toString()));
}
}
+6 -7
View File
@@ -27,18 +27,17 @@
#include "common/xmlutils.h"
namespace olive {
namespace olive
{
using namespace core;
class TypeSerializer
{
class TypeSerializer {
public:
TypeSerializer() = default;
static AudioParams LoadAudioParams(QXmlStreamReader *reader);
static void SaveAudioParams(QXmlStreamWriter *writer, const AudioParams &a);
TypeSerializer() = default;
static AudioParams LoadAudioParams(QXmlStreamReader *reader);
static void SaveAudioParams(QXmlStreamWriter *writer, const AudioParams &a);
};
}