don't use shared ptrs for project items

This commit is contained in:
itsmattkc
2020-12-16 10:28:43 +11:00
parent 1cd07bc1f7
commit e12013e2fb
31 changed files with 209 additions and 255 deletions
+6 -6
View File
@@ -61,20 +61,20 @@ void Folder::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, uint ver
return;
}
ItemPtr child;
Item* child;
if (reader->name() == QStringLiteral("folder")) {
child = std::make_shared<Folder>();
child = new Folder();
} else if (reader->name() == QStringLiteral("footage")) {
child = std::make_shared<Footage>();
child = new Footage();
} else if (reader->name() == QStringLiteral("sequence")) {
child = std::make_shared<Sequence>();
child = new Sequence();
} else {
reader->skipCurrentElement();
continue;
}
add_child(child);
child->setParent(this);
child->Load(reader, xml_node_data, version, cancelled);
}
}
@@ -85,7 +85,7 @@ void Folder::Save(QXmlStreamWriter *writer) const
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(this)));
foreach (ItemPtr child, children()) {
foreach (Item* child, children()) {
switch (child->type()) {
case Item::kFootage:
writer->writeStartElement(QStringLiteral("footage"));
+4 -4
View File
@@ -299,7 +299,7 @@ StreamPtr Footage::get_first_stream_of_type(const Stream::Type &type) const
return nullptr;
}
bool Footage::CompareFootageToFile(FootagePtr footage, const QString &filename)
bool Footage::CompareFootageToFile(Footage *footage, const QString &filename)
{
// Heuristic to determine if file has changed
QFileInfo info(filename);
@@ -311,9 +311,9 @@ bool Footage::CompareFootageToFile(FootagePtr footage, const QString &filename)
} else {
// Footage may have changed and we'll have to re-probe it. It also may not have, in which
// case nothing needs to change.
ItemPtr item = Decoder::Probe(footage->project(), filename, nullptr);
std::unique_ptr<Footage> item(Decoder::Probe(footage->project(), filename, nullptr));
if (item && item->type() == footage->type()) {
if (item) {
// Item is the same type, that's a good sign. Let's look for any differences.
// FIXME: Implement this
return true;
@@ -325,7 +325,7 @@ bool Footage::CompareFootageToFile(FootagePtr footage, const QString &filename)
return false;
}
bool Footage::CompareFootageToItsFilename(FootagePtr footage)
bool Footage::CompareFootageToItsFilename(Footage *footage)
{
return CompareFootageToFile(footage, footage->filename());
}
+3 -5
View File
@@ -32,9 +32,6 @@
namespace olive {
class Footage;
using FootagePtr = std::shared_ptr<Footage>;
/**
* @brief A reference to an external media file with metadata in a project structure
*
@@ -44,6 +41,7 @@ using FootagePtr = std::shared_ptr<Footage>;
*/
class Footage : public Item, public TimelinePoints
{
Q_OBJECT
public:
/**
* @brief Footage Constructor
@@ -202,8 +200,8 @@ public:
StreamPtr get_first_stream_of_type(const Stream::Type& type) const;
static bool CompareFootageToFile(FootagePtr footage, const QString& filename);
static bool CompareFootageToItsFilename(FootagePtr footage);
static bool CompareFootageToFile(Footage* footage, const QString& filename);
static bool CompareFootageToItsFilename(Footage* footage);
private:
/**
+28 -73
View File
@@ -23,7 +23,7 @@
namespace olive {
Item::Item() :
parent_(nullptr),
item_parent_(nullptr),
project_(nullptr)
{
}
@@ -32,65 +32,6 @@ Item::~Item()
{
}
void Item::add_child(ItemPtr c)
{
if (c->parent_ == this) {
return;
}
if (c->parent_ != nullptr) {
c->parent_->remove_child(c.get());
}
children_.append(c);
c->parent_ = this;
}
void Item::remove_child(Item *c)
{
if (c->parent_ != this) {
return;
}
// Remove all instances of this child in the list
for (int i=0;i<children_.size();i++) {
if (children_.at(i).get() == c) {
children_.removeAt(i);
i--;
}
}
c->parent_ = nullptr;
}
int Item::child_count() const
{
return children_.size();
}
Item *Item::child(int i) const
{
return children_.at(i).get();
}
const QList<ItemPtr> &Item::children() const
{
return children_;
}
ItemPtr Item::get_shared_ptr() const
{
QList<ItemPtr> siblings = parent()->children();
foreach (ItemPtr s, siblings) {
if (s.get() == this) {
return s;
}
}
return nullptr;
}
const QString &Item::name() const
{
return name_;
@@ -123,17 +64,12 @@ QString Item::rate()
return QString();
}
Item *Item::parent() const
{
return parent_;
}
const Item *Item::root() const
{
const Item* item = this;
while (item->parent()) {
item = item->parent();
while (item->item_parent()) {
item = item->item_parent();
}
return item;
@@ -151,11 +87,11 @@ void Item::set_project(Project *project)
project_ = project;
}
QList<ItemPtr> Item::get_children_of_type(Type type, bool recursive) const
QVector<Item *> Item::get_children_of_type(Type type, bool recursive) const
{
QList<ItemPtr> list;
QVector<Item *> list;
foreach (ItemPtr item, children_) {
foreach (Item* item, item_children_) {
if (item->type() == type) {
list.append(item);
}
@@ -182,12 +118,31 @@ void Item::NameChangedEvent(const QString &)
{
}
void Item::childEvent(QChildEvent *event)
{
QObject::childEvent(event);
Item* cast_test = dynamic_cast<Item*>(event->child());
if (cast_test) {
if (event->type() == QEvent::ChildAdded) {
item_children_.append(cast_test);
cast_test->item_parent_ = this;
} else if (event->type() == QEvent::ChildRemoved) {
item_children_.removeOne(cast_test);
cast_test->item_parent_ = nullptr;
}
}
}
bool Item::ChildExistsWithNameInternal(const QString &name, Item *folder)
{
// Loop through all children
for (int i=0;i<folder->child_count();i++) {
Item* child = folder->child(i);
foreach (Item* child, folder->item_children_) {
// If this child has the same name, return true
if (child->name() == name) {
return true;
+26 -17
View File
@@ -37,17 +37,15 @@ namespace olive {
class Project;
class Item;
using ItemPtr = std::shared_ptr<Item>;
/**
* @brief A base-class representing any element in a Project
*
* Project objects implement a parent-child hierarchy of Items that can be used throughout the Project. The Item class
* itself is abstract and will need to be subclassed to be used in a Project.
*/
class Item
class Item : public QObject
{
Q_OBJECT
public:
enum Type {
kFolder,
@@ -65,21 +63,26 @@ public:
*/
virtual ~Item();
DISABLE_COPY_MOVE(Item)
virtual void Load(QXmlStreamReader* reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt *cancelled) = 0;
virtual void Save(QXmlStreamWriter* writer) const = 0;
virtual Type type() const = 0;
void add_child(ItemPtr c);
void remove_child(Item* c);
int child_count() const;
Item* child(int i) const;
const QList<ItemPtr>& children() const;
int item_child_count() const
{
return item_children_.size();
}
ItemPtr get_shared_ptr() const;
Item* item_child(int i) const
{
return item_children_.at(i);
}
const QVector<Item*>& children() const
{
return item_children_;
}
const QString& name() const;
void set_name(const QString& n);
@@ -93,13 +96,17 @@ public:
virtual QString rate();
Item *parent() const;
Item *item_parent() const
{
return item_parent_;
}
const Item* root() const;
Project* project() const;
void set_project(Project* project);
QList<ItemPtr> get_children_of_type(Type type, bool recursive) const;
QVector<Item*> get_children_of_type(Type type, bool recursive) const;
virtual bool CanHaveChildren() const;
@@ -108,12 +115,14 @@ public:
protected:
virtual void NameChangedEvent(const QString& name);
virtual void childEvent(QChildEvent *event) override;
private:
bool ChildExistsWithNameInternal(const QString& name, Item* folder);
static bool ChildExistsWithNameInternal(const QString& name, Item* folder);
QList<ItemPtr> children_;
QVector<Item*> item_children_;
Item* parent_;
Item* item_parent_;
Project* project_;
-6
View File
@@ -171,12 +171,6 @@ void Sequence::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, uint v
// Link blocks
XMLLinkBlocks(xml_node_data);
// Ensure this and all children are in the main thread
// NOTE: It might be good to move the Item system to QObjects so they inherit their thread
if (QThread::currentThread() != qApp->thread()) {
moveToThread(qApp->thread());
}
}
void Sequence::Save(QXmlStreamWriter *writer) const
+2 -4
View File
@@ -31,14 +31,12 @@
namespace olive {
class Sequence;
using SequencePtr = std::shared_ptr<Sequence>;
/**
* @brief The main timeline object, an graph of edited clips that forms a complete edit
*/
class Sequence : public Item, public NodeGraph, public TimelinePoints
class Sequence : public NodeGraph, public TimelinePoints
{
Q_OBJECT
public:
Sequence();
+7 -7
View File
@@ -161,7 +161,7 @@ ColorManager *Project::color_manager()
return &color_manager_;
}
QList<ItemPtr> Project::get_items_of_type(Item::Type type) const
QVector<Item *> Project::get_items_of_type(Item::Type type) const
{
return root_.get_children_of_type(type, true);
}
@@ -204,10 +204,10 @@ const QString &Project::cache_path(bool default_if_empty) const
void Project::ColorConfigChanged()
{
QList<ItemPtr> footage = this->get_items_of_type(Item::kFootage);
QVector<Item*> footage = this->get_items_of_type(Item::kFootage);
foreach (ItemPtr item, footage) {
foreach (StreamPtr s, std::static_pointer_cast<Footage>(item)->streams()) {
foreach (Item* item, footage) {
foreach (StreamPtr s, static_cast<Footage*>(item)->streams()) {
if (s->type() == Stream::kVideo) {
std::static_pointer_cast<VideoStream>(s)->ColorConfigChanged();
}
@@ -217,10 +217,10 @@ void Project::ColorConfigChanged()
void Project::DefaultColorSpaceChanged()
{
QList<ItemPtr> footage = this->get_items_of_type(Item::kFootage);
QVector<Item*> footage = this->get_items_of_type(Item::kFootage);
foreach (ItemPtr item, footage) {
foreach (StreamPtr s, std::static_pointer_cast<Footage>(item)->streams()) {
foreach (Item* item, footage) {
foreach (StreamPtr s, static_cast<Footage*>(item)->streams()) {
if (s->type() == Stream::kVideo) {
std::static_pointer_cast<VideoStream>(s)->DefaultColorSpaceChanged();
}
+1 -1
View File
@@ -61,7 +61,7 @@ public:
ColorManager* color_manager();
QList<ItemPtr> get_items_of_type(Item::Type type) const;
QVector<Item*> get_items_of_type(Item::Type type) const;
bool is_modified() const;
void set_modified(bool e);
+25 -30
View File
@@ -64,7 +64,7 @@ QModelIndex ProjectViewModel::index(int row, int column, const QModelIndex &pare
Item* item_parent = GetItemObjectFromIndex(parent);
// Return an index to this object
return createIndex(row, column, item_parent->child(row));
return createIndex(row, column, item_parent->item_child(row));
}
QModelIndex ProjectViewModel::parent(const QModelIndex &child) const
@@ -73,7 +73,7 @@ QModelIndex ProjectViewModel::parent(const QModelIndex &child) const
Item* item = GetItemObjectFromIndex(child);
// Get Item's parent object
Item* par = item->parent();
Item* par = item->item_parent();
// If the parent is the root, return an empty index
if (par == project_->root()) {
@@ -99,11 +99,11 @@ int ProjectViewModel::rowCount(const QModelIndex &parent) const
// If the index is the root, return the root child count
if (parent == QModelIndex()) {
return project_->root()->child_count();
return project_->root()->item_child_count();
}
// Otherwise, the index must contain a valid pointer, so we just return its child count
return GetItemObjectFromIndex(parent)->child_count();
return GetItemObjectFromIndex(parent)->item_child_count();
}
int ProjectViewModel::columnCount(const QModelIndex &parent) const
@@ -375,7 +375,7 @@ bool ProjectViewModel::dropMimeData(const QMimeData *data, Qt::DropAction action
// If we didn't drop onto an item, find the nearest parent folder (should eventually terminate at root either way)
while (!drop_item->CanHaveChildren()) {
drop_item = drop_item->parent();
drop_item = drop_item->item_parent();
}
// Trigger an import
@@ -385,7 +385,7 @@ bool ProjectViewModel::dropMimeData(const QMimeData *data, Qt::DropAction action
return false;
}
void ProjectViewModel::AddChild(Item *parent, ItemPtr child)
void ProjectViewModel::AddChild(Item *parent, Item *child)
{
QModelIndex parent_index;
@@ -393,14 +393,14 @@ void ProjectViewModel::AddChild(Item *parent, ItemPtr child)
parent_index = CreateIndexFromItem(parent);
}
beginInsertRows(parent_index, parent->child_count(), parent->child_count());
beginInsertRows(parent_index, parent->item_child_count(), parent->item_child_count());
parent->add_child(child);
child->setParent(parent);
endInsertRows();
}
void ProjectViewModel::RemoveChild(Item *parent, Item *child)
void ProjectViewModel::RemoveChild(Item *parent, Item *child, QObject *new_parent)
{
QModelIndex parent_index;
@@ -412,7 +412,7 @@ void ProjectViewModel::RemoveChild(Item *parent, Item *child)
beginRemoveRows(parent_index, child_row, child_row);
parent->remove_child(child);
child->setParent(new_parent);
endRemoveRows();
}
@@ -435,11 +435,11 @@ int ProjectViewModel::IndexOfChild(Item *item) const
return -1;
}
Item* parent = item->parent();
Item* parent = item->item_parent();
if (parent != nullptr) {
for (int i=0;i<parent->child_count();i++) {
if (parent->child(i) == item) {
for (int i=0;i<parent->item_child_count();i++) {
if (parent->item_child(i) == item) {
return i;
}
}
@@ -452,7 +452,7 @@ int ProjectViewModel::ChildCount(const QModelIndex &index)
{
Item* item = GetItemObjectFromIndex(index);
return item->child_count();
return item->item_child_count();
}
Item *ProjectViewModel::GetItemObjectFromIndex(const QModelIndex &index) const
@@ -468,7 +468,7 @@ bool ProjectViewModel::ItemIsParentOfChild(Item *parent, Item *child) const
{
// Loop through parent hierarchy checking if `parent` is one of its parents
do {
child = child->parent();
child = child->item_parent();
if (parent == child) {
return true;
@@ -484,11 +484,10 @@ void ProjectViewModel::MoveItemInternal(Item *item, Item *destination)
QModelIndex destination_index = CreateIndexFromItem(destination);
beginMoveRows(item_index.parent(), item_index.row(), item_index.row(), destination_index, destination->child_count());
beginMoveRows(item_index.parent(), item_index.row(), item_index.row(),
destination_index, destination->item_child_count());
ItemPtr item_ptr = item->get_shared_ptr();
destination->add_child(item_ptr);
item->setParent(destination);
endMoveRows();
}
@@ -553,13 +552,13 @@ void ProjectViewModel::RenameItemCommand::undo_internal()
model_->RenameChild(item_, old_name_);
}
ProjectViewModel::AddItemCommand::AddItemCommand(ProjectViewModel* model, Item* folder, ItemPtr child, QUndoCommand* parent) :
ProjectViewModel::AddItemCommand::AddItemCommand(ProjectViewModel* model, Item* folder, Item* child, QUndoCommand* parent) :
UndoCommand(parent),
model_(model),
parent_(folder),
child_(child),
done_(false)
child_(child)
{
child_->setParent(&memory_manager_);
}
Project *ProjectViewModel::AddItemCommand::GetRelevantProject() const
@@ -570,18 +569,14 @@ Project *ProjectViewModel::AddItemCommand::GetRelevantProject() const
void ProjectViewModel::AddItemCommand::redo_internal()
{
model_->AddChild(parent_, child_);
done_ = true;
}
void ProjectViewModel::AddItemCommand::undo_internal()
{
model_->RemoveChild(parent_, child_.get());
done_ = false;
model_->RemoveChild(parent_, child_, &memory_manager_);
}
ProjectViewModel::RemoveItemCommand::RemoveItemCommand(ProjectViewModel *model, ItemPtr item, QUndoCommand *parent) :
ProjectViewModel::RemoveItemCommand::RemoveItemCommand(ProjectViewModel *model, Item *item, QUndoCommand *parent) :
UndoCommand(parent),
model_(model),
item_(item)
@@ -595,8 +590,8 @@ Project *ProjectViewModel::RemoveItemCommand::GetRelevantProject() const
void ProjectViewModel::RemoveItemCommand::redo_internal()
{
parent_ = item_->parent();
model_->RemoveChild(parent_, item_.get());
parent_ = item_->item_parent();
model_->RemoveChild(parent_, item_, &memory_manager_);
}
void ProjectViewModel::RemoveItemCommand::undo_internal()
+9 -9
View File
@@ -100,8 +100,8 @@ public:
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
/** Other model functions */
void AddChild(Item* parent, ItemPtr child);
void RemoveChild(Item* parent, Item* child);
void AddChild(Item* parent, Item* child);
void RemoveChild(Item* parent, Item* child, QObject* new_parent);
void RenameChild(Item* item, const QString& name);
/**
@@ -157,7 +157,7 @@ public:
*/
class AddItemCommand : public UndoCommand {
public:
AddItemCommand(ProjectViewModel* model, Item* folder, ItemPtr child, QUndoCommand* parent = nullptr);
AddItemCommand(ProjectViewModel* model, Item* folder, Item *child, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
@@ -169,8 +169,9 @@ public:
private:
ProjectViewModel* model_;
Item* parent_;
ItemPtr child_;
bool done_;
Item* child_;
QObject memory_manager_;
};
/**
@@ -178,7 +179,7 @@ public:
*/
class RemoveItemCommand : public UndoCommand {
public:
RemoveItemCommand(ProjectViewModel* model, ItemPtr item, QUndoCommand* parent = nullptr);
RemoveItemCommand(ProjectViewModel* model, Item* item, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
@@ -189,10 +190,9 @@ public:
private:
ProjectViewModel* model_;
ItemPtr item_;
Item* item_;
Item* parent_;
QObject memory_manager_;
};