From 3b822c1110f6670e0ed65a94df453443de8d1f9f Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Sun, 19 Feb 2023 20:52:07 -0800 Subject: [PATCH] save/sync data with binary arraymap --- app/node/block/block.cpp | 10 ++ app/node/block/block.h | 2 + app/node/output/track/track.cpp | 170 +++++++++++++++++++++++++++----- app/node/output/track/track.h | 11 ++- app/node/value.h | 5 + 5 files changed, 170 insertions(+), 28 deletions(-) diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index fb030e5b5..46bedb6ea 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -134,4 +134,14 @@ void Block::InvalidateCache(const TimeRange& range, const QString& from, int ele super::InvalidateCache(r, from, element, options); } +void Block::set_previous_next(Block *previous, Block *next) +{ + if (previous) { + previous->set_next(next); + } + if (next) { + next->set_previous(previous); + } +} + } diff --git a/app/node/block/block.h b/app/node/block/block.h index 2ad077ee5..08afa94d0 100644 --- a/app/node/block/block.h +++ b/app/node/block/block.h @@ -118,6 +118,8 @@ public: static const QString kLengthInput; + static void set_previous_next(Block *previous, Block *next); + public slots: signals: diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index e1bdde7f3..090e8d6c1 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -39,12 +39,14 @@ const double Track::kTrackHeightInterval = 0.5; const QString Track::kBlockInput = QStringLiteral("block_in"); const QString Track::kMutedInput = QStringLiteral("muted_in"); +const QString Track::kArrayMapInput = QStringLiteral("arraymap_in"); Track::Track() : track_type_(Track::kNone), index_(-1), locked_(false), - sequence_(nullptr) + sequence_(nullptr), + ignore_arraymap_(0) { AddInput(kBlockInput, NodeValue::kNone, InputFlags(kInputFlagArray | kInputFlagNotKeyframable | kInputFlagHidden)); @@ -54,6 +56,9 @@ Track::Track() : AddInput(kMutedInput, NodeValue::kBoolean, false, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable)); + AddInput(kArrayMapInput, NodeValue::kBinary, InputFlags(kInputFlagStatic | kInputFlagHidden)); + IgnoreInvalidationsFrom(kArrayMapInput); + // Set default height track_height_ = kTrackHeightDefault; } @@ -194,7 +199,7 @@ void Track::SetTrackHeight(const double &height) emit TrackHeightChanged(track_height_); } -void Track::InputConnectedEvent(const QString &input, int element, Node *output) +/*void Track::InputConnectedEvent(const QString &input, int element, Node *output) { if (input == kBlockInput) { if (element == -1) { @@ -321,7 +326,7 @@ void Track::InputDisconnectedEvent(const QString &input, int element, Node *outp Node::InvalidateCache(invalidate_range, kBlockInput); } -} +}*/ void Track::InputValueChangedEvent(const QString &input, int element) { @@ -329,6 +334,34 @@ void Track::InputValueChangedEvent(const QString &input, int element) if (input == kMutedInput) { emit MutedChanged(IsMuted()); + } else if (input == kArrayMapInput) { + if (ignore_arraymap_ > 0) { + qDebug() << "ignored our own array map update"; + ignore_arraymap_--; + } else { + qDebug() << "received REAL array map update"; + + block_array_indexes_ = GetStandardValue(kArrayMapInput).value< QVector >(); + blocks_.reserve(block_array_indexes_.size()); + Block *prev = nullptr; + for (int i = 0; i < block_array_indexes_.size(); i++) { + Block *b = static_cast(GetConnectedOutput(kBlockInput, block_array_indexes_.at(i))); + + Block::set_previous_next(prev, b); + + if (b) { + blocks_.append(b); + prev = b; + } else { + block_array_indexes_.removeAt(i); + i--; + } + } + if (prev) { + prev->set_next(nullptr); + } + UpdateInOutFrom(0); + } } } @@ -488,39 +521,48 @@ void Track::InsertBlockAfter(Block *block, Block *before) Q_ASSERT(before_index >= 0); - if (before_index == blocks_.size() - 1) { - AppendBlock(block); - } else { - InsertBlockAtIndex(block, before_index + 1); - } + InsertBlockAtIndex(block, before_index + 1); } } void Track::PrependBlock(Block *block) { - InputArrayPrepend(kBlockInput); - Node::ConnectEdge(block, NodeInput(this, kBlockInput, 0)); - - // Everything has shifted at this point - Node::InvalidateCache(TimeRange(0, track_length()), kBlockInput); + InsertBlockAtIndex(block, 0); } void Track::InsertBlockAtIndex(Block *block, int index) { - int insert_index = GetArrayIndexFromCacheIndex(index); - InputArrayInsert(kBlockInput, insert_index); - Node::ConnectEdge(block, NodeInput(this, kBlockInput, insert_index)); + // Set track + Q_ASSERT(block->track() == nullptr); + block->set_track(this); + + // Update array + int array_index = ConnectBlock(block); + blocks_.insert(index, block); + block_array_indexes_.insert(index, array_index); + + // Handle previous/next + Block *previous = (index > 0) ? blocks_.at(index - 1) : nullptr; + Block *next = (index < blocks_.size()-1) ? blocks_.at(index + 1) : nullptr ; + Block::set_previous_next(previous, block); + Block::set_previous_next(block, next); + + // Update in/out + UpdateInOutFrom(index); + + connect(block, &Block::LengthChanged, this, &Track::BlockLengthChanged); Node::InvalidateCache(TimeRange(block->in(), track_length()), kBlockInput); + + emit BlockAdded(block); + + ignore_arraymap_++; + SetStandardValue(kArrayMapInput, QVariant::fromValue(block_array_indexes_)); } void Track::AppendBlock(Block *block) { - InputArrayAppend(kBlockInput); - Node::ConnectEdge(block, NodeInput(this, kBlockInput, InputArraySize(kBlockInput) - 1)); - - // Invalidate area that block was added to - Node::InvalidateCache(TimeRange(block->in(), block->out()), kBlockInput); + InsertBlockAtIndex(block, blocks_.size()); } void Track::RippleRemoveBlock(Block *block) @@ -528,24 +570,87 @@ void Track::RippleRemoveBlock(Block *block) rational remove_in = block->in(); rational remove_out = block->out(); - InputArrayRemove(kBlockInput, GetArrayIndexFromBlock(block)); + emit BlockRemoved(block); + + // Set track + Q_ASSERT(block->track() == this); + block->set_track(nullptr); + + // Update array + int index = blocks_.indexOf(block); + Q_ASSERT(index != -1); + + int array_index = block_array_indexes_.at(index); + + blocks_.removeAt(index); + block_array_indexes_.removeAt(index); + + Node::DisconnectEdge(block, NodeInput(this, kBlockInput, array_index)); + empty_inputs_.push_back(array_index); + disconnect(block, &Block::LengthChanged, this, &Track::BlockLengthChanged); + + // Handle previous/next + Block *previous = (index > 0) ? blocks_.at(index - 1) : nullptr; + Block *next = (index < blocks_.size()) ? blocks_.at(index) : nullptr; + Block::set_previous_next(previous, next); + block->set_previous(nullptr); + block->set_next(nullptr); + + // Update in/outs + UpdateInOutFrom(index); Node::InvalidateCache(TimeRange(remove_in, qMax(track_length(), remove_out)), kBlockInput); + + ignore_arraymap_++; + SetStandardValue(kArrayMapInput, QVariant::fromValue(block_array_indexes_)); } void Track::ReplaceBlock(Block *old, Block *replace) { - int index_of_old_block = GetArrayIndexFromBlock(old); + emit BlockRemoved(old); + + // Set track + Q_ASSERT(old->track() == this); + old->set_track(nullptr); + + Q_ASSERT(replace->track() == nullptr); + replace->set_track(this); + + // Update array + int cache_index = blocks_.indexOf(old); + int index_of_old_block = GetArrayIndexFromCacheIndex(cache_index); DisconnectEdge(old, NodeInput(this, kBlockInput, index_of_old_block)); - ConnectEdge(replace, NodeInput(this, kBlockInput, index_of_old_block)); + blocks_.replace(cache_index, replace); + disconnect(old, &Block::LengthChanged, this, &Track::BlockLengthChanged); + connect(replace, &Block::LengthChanged, this, &Track::BlockLengthChanged); + + // Handle previous/next + replace->set_previous(old->previous()); + replace->set_next(old->next()); + old->set_previous(nullptr); + old->set_next(nullptr); + if (replace->previous()) { + replace->previous()->set_next(replace); + } + if (replace->next()) { + replace->next()->set_previous(replace); + } if (old->length() == replace->length()) { Node::InvalidateCache(TimeRange(replace->in(), replace->out()), kBlockInput); } else { + // Update in/outs + UpdateInOutFrom(cache_index); + Node::InvalidateCache(TimeRange(replace->in(), track_length()), kBlockInput); } + + emit BlockAdded(replace); + + ignore_arraymap_++; + SetStandardValue(kArrayMapInput, QVariant::fromValue(block_array_indexes_)); } rational Track::track_length() const @@ -734,6 +839,23 @@ void Track::ProcessAudioTrack(const NodeValueRow &value, const NodeGlobals &glob table->Push(NodeValue::kSamples, QVariant::fromValue(block_range_buffer), this); } +int Track::ConnectBlock(Block *b) +{ + if (!empty_inputs_.empty()) { + int index = empty_inputs_.front(); + empty_inputs_.pop_front(); + + Node::ConnectEdge(b, NodeInput(this, kBlockInput, index)); + + return index; + } else { + int old_sz = InputArraySize(kBlockInput); + InputArrayAppend(kBlockInput); + Node::ConnectEdge(b, NodeInput(this, kBlockInput, old_sz)); + return old_sz; + } +} + void Track::BlockLengthChanged() { // Assumes sender is a Block diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index ad1eaa5b4..8f0414ab8 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -400,6 +400,7 @@ public: static const QString kBlockInput; static const QString kMutedInput; + static const QString kArrayMapInput; public slots: void SetMuted(bool e); @@ -443,10 +444,6 @@ signals: void BlocksRefreshed(); protected: - virtual void InputConnectedEvent(const QString& input, int element, Node *output) override; - - virtual void InputDisconnectedEvent(const QString& input, int element, Node *output) override; - virtual void InputValueChangedEvent(const QString& input, int element) override; private: @@ -460,11 +457,15 @@ private: void ProcessAudioTrack(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const; + int ConnectBlock(Block *b); + TimeRangeList block_length_pending_invalidations_; QVector blocks_; QVector block_array_indexes_; + std::list empty_inputs_; + Track::Type track_type_; double track_height_; @@ -475,6 +476,8 @@ private: Sequence *sequence_; + int ignore_arraymap_; + private slots: void BlockLengthChanged(); diff --git a/app/node/value.h b/app/node/value.h index 2e033849f..d42ba9a59 100644 --- a/app/node/value.h +++ b/app/node/value.h @@ -187,6 +187,11 @@ public: */ kSubtitleParams, + /** + * Binary Data + */ + kBinary, + /** * End of list */