diff --git a/app/node/blend/alphaover/alphaover.cpp b/app/node/blend/alphaover/alphaover.cpp index 69b429648..4956cd189 100644 --- a/app/node/blend/alphaover/alphaover.cpp +++ b/app/node/blend/alphaover/alphaover.cpp @@ -25,27 +25,27 @@ AlphaOverBlend::AlphaOverBlend() } -Node *AlphaOverBlend::copy() +Node *AlphaOverBlend::copy() const { return new AlphaOverBlend(); } -QString AlphaOverBlend::Name() +QString AlphaOverBlend::Name() const { return tr("Alpha Over"); } -QString AlphaOverBlend::id() +QString AlphaOverBlend::id() const { return "org.olivevideoeditor.Olive.alphaoverblend"; } -QString AlphaOverBlend::Description() +QString AlphaOverBlend::Description() const { return tr("A blending node that composites one texture over another using its alpha channel."); } -QString AlphaOverBlend::Code(NodeOutput *output) +QString AlphaOverBlend::Code(NodeOutput *output) const { if (output == texture_output()) { return "#version 110" diff --git a/app/node/blend/alphaover/alphaover.h b/app/node/blend/alphaover/alphaover.h index 77b81aac7..a6fb0af27 100644 --- a/app/node/blend/alphaover/alphaover.h +++ b/app/node/blend/alphaover/alphaover.h @@ -28,13 +28,13 @@ class AlphaOverBlend : public BlendNode public: AlphaOverBlend(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Description() const override; - virtual QString Code(NodeOutput* output) override; + virtual QString Code(NodeOutput* output) const override; protected: diff --git a/app/node/blend/blend.cpp b/app/node/blend/blend.cpp index cbd279e8e..7f06eb196 100644 --- a/app/node/blend/blend.cpp +++ b/app/node/blend/blend.cpp @@ -34,22 +34,22 @@ BlendNode::BlendNode() AddParameter(texture_output_); } -QString BlendNode::Category() +QString BlendNode::Category() const { return tr("Blend"); } -NodeInput *BlendNode::base_input() +NodeInput *BlendNode::base_input() const { return base_input_; } -NodeInput *BlendNode::blend_input() +NodeInput *BlendNode::blend_input() const { return blend_input_; } -NodeOutput *BlendNode::texture_output() +NodeOutput *BlendNode::texture_output() const { return texture_output_; } diff --git a/app/node/blend/blend.h b/app/node/blend/blend.h index 9f4e1ba96..bd65f9310 100644 --- a/app/node/blend/blend.h +++ b/app/node/blend/blend.h @@ -28,13 +28,13 @@ class BlendNode : public Node public: BlendNode(); - virtual QString Category() override; + virtual QString Category() const override; - NodeInput* base_input(); + NodeInput* base_input() const; - NodeInput* blend_input(); + NodeInput* blend_input() const; - NodeOutput* texture_output(); + NodeOutput* texture_output() const; private: NodeInput* base_input_; diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index 989c8b037..90718dd8b 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -33,17 +33,17 @@ Block::Block() : AddParameter(buffer_output_); } -QString Block::Category() +QString Block::Category() const { return tr("Block"); } -const rational &Block::in() +const rational &Block::in() const { return in_point_; } -const rational &Block::out() +const rational &Block::out() const { return out_point_; } @@ -58,7 +58,7 @@ void Block::set_out(const rational &out) out_point_ = out; } -const rational& Block::length() +const rational& Block::length() const { return length_; } @@ -109,27 +109,17 @@ void Block::set_next(Block *next) next_ = next; } -QVariant Block::Value(NodeOutput *output) -{ - if (output == block_output_) { - // Simply set the output value to a pointer to this Block - return PtrToValue(this); - } - - return 0; -} - -NodeOutput *Block::buffer_output() +NodeOutput *Block::buffer_output() const { return buffer_output_; } -NodeOutput *Block::block_output() +NodeOutput *Block::block_output() const { return block_output_; } -const rational &Block::media_in() +const rational &Block::media_in() const { return media_in_; } @@ -151,7 +141,7 @@ void Block::set_media_in(const rational &media_in) } } -const QString &Block::block_name() +const QString &Block::block_name() const { return block_name_; } @@ -161,7 +151,7 @@ void Block::set_block_name(const QString &name) block_name_ = name; } -rational Block::SequenceToMediaTime(const rational &sequence_time) +rational Block::SequenceToMediaTime(const rational &sequence_time) const { // These constants are not considered "values" per se, so we don't modify them if (sequence_time == RATIONAL_MIN || sequence_time == RATIONAL_MAX) { @@ -171,7 +161,7 @@ rational Block::SequenceToMediaTime(const rational &sequence_time) return sequence_time - in() + media_in(); } -rational Block::MediaToSequenceTime(const rational &media_time) +rational Block::MediaToSequenceTime(const rational &media_time) const { // These constants are not considered "values" per se, so we don't modify them if (media_time == RATIONAL_MIN || media_time == RATIONAL_MAX) { @@ -181,7 +171,7 @@ rational Block::MediaToSequenceTime(const rational &media_time) return media_time - media_in() + in(); } -void Block::CopyParameters(Block *source, Block *dest) +void Block::CopyParameters(const Block *source, Block *dest) { dest->set_block_name(source->block_name()); dest->set_length(source->length()); @@ -233,7 +223,7 @@ bool Block::HasLinks() return !linked_clips_.isEmpty(); } -bool Block::IsBlock() +bool Block::IsBlock() const { return true; } diff --git a/app/node/block/block.h b/app/node/block/block.h index 5451ee947..c52ff5cc7 100644 --- a/app/node/block/block.h +++ b/app/node/block/block.h @@ -45,16 +45,16 @@ public: kTrack }; - virtual Type type() = 0; + virtual Type type() const = 0; - virtual QString Category() override; + virtual QString Category() const override; - const rational& in(); - const rational& out(); + const rational& in() const; + const rational& out() const; void set_in(const rational& in); void set_out(const rational& out); - const rational &length(); + const rational &length() const; void set_length(const rational &length); void set_length_and_media_in(const rational &length); @@ -63,13 +63,13 @@ public: void set_previous(Block* previous); void set_next(Block* next); - NodeOutput* buffer_output(); - NodeOutput* block_output(); + NodeOutput* buffer_output() const; + NodeOutput* block_output() const; - const rational& media_in(); + const rational& media_in() const; void set_media_in(const rational& media_in); - const QString& block_name(); + const QString& block_name() const; void set_block_name(const QString& name); static void Link(Block* a, Block* b); @@ -79,9 +79,7 @@ public: const QVector& linked_clips(); bool HasLinks(); - virtual bool IsBlock() override; - - virtual QVariant Value(NodeOutput* output) override; + virtual bool IsBlock() const override; public slots: @@ -96,11 +94,11 @@ signals: void LengthChanged(const rational& length); protected: - rational SequenceToMediaTime(const rational& sequence_time); + rational SequenceToMediaTime(const rational& sequence_time) const; - rational MediaToSequenceTime(const rational& media_time); + rational MediaToSequenceTime(const rational& media_time) const; - static void CopyParameters(Block* source, Block* dest); + static void CopyParameters(const Block *source, Block* dest); Block* previous_; Block* next_; diff --git a/app/node/block/clip/clip.cpp b/app/node/block/clip/clip.cpp index d3b8d0db9..7d9541bf8 100644 --- a/app/node/block/clip/clip.cpp +++ b/app/node/block/clip/clip.cpp @@ -27,7 +27,7 @@ ClipBlock::ClipBlock() AddParameter(texture_input_); } -Node *ClipBlock::copy() +Node *ClipBlock::copy() const { ClipBlock* c = new ClipBlock(); @@ -36,27 +36,27 @@ Node *ClipBlock::copy() return c; } -Block::Type ClipBlock::type() +Block::Type ClipBlock::type() const { return kClip; } -QString ClipBlock::Name() +QString ClipBlock::Name() const { return tr("Clip"); } -QString ClipBlock::id() +QString ClipBlock::id() const { return "org.olivevideoeditor.Olive.clip"; } -QString ClipBlock::Description() +QString ClipBlock::Description() const { return tr("A time-based node that represents a media source."); } -NodeInput *ClipBlock::texture_input() +NodeInput *ClipBlock::texture_input() const { return texture_input_; } @@ -79,7 +79,7 @@ void ClipBlock::InvalidateCache(const rational &start_range, const rational &end } } -TimeRange ClipBlock::InputTimeAdjustment(NodeInput *input, const TimeRange &input_time) +TimeRange ClipBlock::InputTimeAdjustment(NodeInput *input, const TimeRange &input_time) const { if (input == texture_input_) { return TimeRange(SequenceToMediaTime(input_time.in()), SequenceToMediaTime(input_time.out())); @@ -88,11 +88,8 @@ TimeRange ClipBlock::InputTimeAdjustment(NodeInput *input, const TimeRange &inpu return Block::InputTimeAdjustment(input, input_time); } -QVariant ClipBlock::Value(NodeOutput *output) +NodeValueTable ClipBlock::Value(const NodeValueDatabase &value) const { - if (output == buffer_output()) { - // We just pass through the texture here, the renderer should have gotten the correct time from InputTimeAdjustment - return texture_input()->value(); - } - return Block::Value(output); + // We just pass through the data here, the renderer should have gotten the correct time from InputTimeAdjustment + return value.Merge(); } diff --git a/app/node/block/clip/clip.h b/app/node/block/clip/clip.h index 908ce8017..c1fb3c440 100644 --- a/app/node/block/clip/clip.h +++ b/app/node/block/clip/clip.h @@ -32,21 +32,21 @@ class ClipBlock : public Block public: ClipBlock(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual Type type() override; + virtual Type type() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Description() const override; - NodeInput* texture_input(); + NodeInput* texture_input() const; virtual void InvalidateCache(const rational &start_range, const rational &end_range, NodeInput *from = nullptr) override; - virtual TimeRange InputTimeAdjustment(NodeInput* input, const TimeRange& input_time) override; + virtual TimeRange InputTimeAdjustment(NodeInput* input, const TimeRange& input_time) const override; - virtual QVariant Value(NodeOutput* output) override; + virtual NodeValueTable Value(const NodeValueDatabase& value) const override; private: NodeInput* texture_input_; diff --git a/app/node/block/gap/gap.cpp b/app/node/block/gap/gap.cpp index c6c17a3e8..0b625ffdc 100644 --- a/app/node/block/gap/gap.cpp +++ b/app/node/block/gap/gap.cpp @@ -24,7 +24,7 @@ GapBlock::GapBlock() { } -Node *GapBlock::copy() +Node *GapBlock::copy() const { GapBlock* c = new GapBlock(); @@ -33,22 +33,22 @@ Node *GapBlock::copy() return c; } -Block::Type GapBlock::type() +Block::Type GapBlock::type() const { return kGap; } -QString GapBlock::Name() +QString GapBlock::Name() const { return tr("Gap"); } -QString GapBlock::id() +QString GapBlock::id() const { return "org.olivevideoeditor.Olive.gap"; } -QString GapBlock::Description() +QString GapBlock::Description() const { return tr("A time-based node that represents an empty space."); } diff --git a/app/node/block/gap/gap.h b/app/node/block/gap/gap.h index ceede3ceb..c98f415e9 100644 --- a/app/node/block/gap/gap.h +++ b/app/node/block/gap/gap.h @@ -32,13 +32,13 @@ class GapBlock : public Block public: GapBlock(); - virtual Node * copy() override; + virtual Node * copy() const override; - virtual Type type() override; + virtual Type type() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Description() const override; private: diff --git a/app/node/color/opacity/opacity.cpp b/app/node/color/opacity/opacity.cpp index 25f4bb7c1..33400fd3b 100644 --- a/app/node/color/opacity/opacity.cpp +++ b/app/node/color/opacity/opacity.cpp @@ -37,27 +37,27 @@ OpacityNode::OpacityNode() AddParameter(texture_output_); } -Node *OpacityNode::copy() +Node *OpacityNode::copy() const { return new OpacityNode(); } -QString OpacityNode::Name() +QString OpacityNode::Name() const { return tr("Opacity"); } -QString OpacityNode::Category() +QString OpacityNode::Category() const { return tr("Color"); } -QString OpacityNode::Description() +QString OpacityNode::Description() const { return tr("Adjust an image's opacity."); } -QString OpacityNode::id() +QString OpacityNode::id() const { return "org.olivevideoeditor.Olive.opacity"; } @@ -67,7 +67,7 @@ void OpacityNode::Retranslate() opacity_input_->set_name(tr("Opacity")); } -QString OpacityNode::Code(NodeOutput *output) +QString OpacityNode::Code(NodeOutput *output) const { if (output == texture_output()) { return "#version 110" @@ -85,12 +85,12 @@ QString OpacityNode::Code(NodeOutput *output) return Node::Code(output); } -NodeInput *OpacityNode::texture_input() +NodeInput *OpacityNode::texture_input() const { return texture_input_; } -NodeOutput *OpacityNode::texture_output() +NodeOutput *OpacityNode::texture_output() const { return texture_output_; } diff --git a/app/node/color/opacity/opacity.h b/app/node/color/opacity/opacity.h index 9570372e9..12587e629 100644 --- a/app/node/color/opacity/opacity.h +++ b/app/node/color/opacity/opacity.h @@ -29,21 +29,21 @@ class OpacityNode : public Node public: OpacityNode(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual QString Name() override; - virtual QString Category() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString Category() const override; + virtual QString Description() const override; - virtual QString id() override; + virtual QString id() const override; virtual void Retranslate() override; - virtual QString Code(NodeOutput* output) override; + virtual QString Code(NodeOutput* output) const override; - NodeInput* texture_input(); + NodeInput* texture_input() const; - NodeOutput* texture_output(); + NodeOutput* texture_output() const; private: NodeInput* opacity_input_; diff --git a/app/node/distort/transform/transform.cpp b/app/node/distort/transform/transform.cpp index 1b5078587..7af53fc2e 100644 --- a/app/node/distort/transform/transform.cpp +++ b/app/node/distort/transform/transform.cpp @@ -46,27 +46,27 @@ TransformDistort::TransformDistort() AddParameter(matrix_output_); } -Node *TransformDistort::copy() +Node *TransformDistort::copy() const { return new TransformDistort(); } -QString TransformDistort::Name() +QString TransformDistort::Name() const { return tr("Transform"); } -QString TransformDistort::id() +QString TransformDistort::id() const { return "org.olivevideoeditor.Olive.transform"; } -QString TransformDistort::Category() +QString TransformDistort::Category() const { return tr("Distort"); } -QString TransformDistort::Description() +QString TransformDistort::Description() const { return tr("Apply transformations to position, rotation, and scale."); } @@ -84,26 +84,25 @@ void TransformDistort::Retranslate() anchor_input_->set_name(tr("Anchor Point")); } -QVariant TransformDistort::Value(NodeOutput *output) +NodeValueTable TransformDistort::Value(const NodeValueDatabase &value) const { - if (output == matrix_output_) { - QMatrix4x4 mat; + QMatrix4x4 mat; - // Position translate - QVector2D pos = position_input_->value().value(); - mat.translate(pos); + // Position translate + QVector2D pos = value[position_input_].Get(NodeParam::kVec2).value(); + mat.translate(pos); - // Rotation - mat.rotate(rotation_input_->value().toFloat(), 0, 0, 1); + // Rotation + mat.rotate(value[rotation_input_].Get(NodeParam::kFloat).toFloat(), 0, 0, 1); - // Scale - mat.scale(scale_input_->value().value()*0.01f); + // Scale + mat.scale(value[scale_input_].Get(NodeParam::kVec2).value()*0.01f); - // Anchor Point - mat.translate(-anchor_input_->value().value()); + // Anchor Point + mat.translate(-value[anchor_input_].Get(NodeParam::kVec2).value()); - return mat; - } - - return 0; + // Push matrix output + NodeValueTable output = value.Merge(); + output.Push(NodeParam::kMatrix, mat); + return output; } diff --git a/app/node/distort/transform/transform.h b/app/node/distort/transform/transform.h index 988cd6233..ea9e30cd2 100644 --- a/app/node/distort/transform/transform.h +++ b/app/node/distort/transform/transform.h @@ -29,18 +29,18 @@ class TransformDistort : public Node public: TransformDistort(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Category() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Category() const override; + virtual QString Description() const override; NodeOutput* matrix_output(); virtual void Retranslate() override; - virtual QVariant Value(NodeOutput *output) override; + virtual NodeValueTable Value(const NodeValueDatabase& value) const override; private: NodeInput* position_input_; diff --git a/app/node/generator/solid/solid.cpp b/app/node/generator/solid/solid.cpp index 643ab36d7..8352cc7b6 100644 --- a/app/node/generator/solid/solid.cpp +++ b/app/node/generator/solid/solid.cpp @@ -31,37 +31,37 @@ SolidGenerator::SolidGenerator() : AddParameter(texture_output_); } -Node *SolidGenerator::copy() +Node *SolidGenerator::copy() const { return new SolidGenerator(); } -QString SolidGenerator::Name() +QString SolidGenerator::Name() const { return tr("Solid"); } -QString SolidGenerator::id() +QString SolidGenerator::id() const { return "org.olivevideoeditor.Olive.solidgenerator"; } -QString SolidGenerator::Category() +QString SolidGenerator::Category() const { return tr("Generator"); } -QString SolidGenerator::Description() +QString SolidGenerator::Description() const { return tr("Generate a solid color."); } -NodeOutput *SolidGenerator::texture_output() +NodeOutput *SolidGenerator::texture_output() const { return texture_output_; } -QString SolidGenerator::Code(NodeOutput *output) +QString SolidGenerator::Code(NodeOutput *output) const { if (output == texture_output()) { // FIXME: Not color managed diff --git a/app/node/generator/solid/solid.h b/app/node/generator/solid/solid.h index b8d76af45..bc31cad2d 100644 --- a/app/node/generator/solid/solid.h +++ b/app/node/generator/solid/solid.h @@ -34,16 +34,16 @@ class SolidGenerator : public Node public: SolidGenerator(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Category() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Category() const override; + virtual QString Description() const override; - NodeOutput* texture_output(); + NodeOutput* texture_output() const; - virtual QString Code(NodeOutput* output) override; + virtual QString Code(NodeOutput* output) const override; private: NodeInput* color_input_; diff --git a/app/node/input/media/audio/audio.cpp b/app/node/input/media/audio/audio.cpp index 9dcddb700..5b9b5e4f0 100644 --- a/app/node/input/media/audio/audio.cpp +++ b/app/node/input/media/audio/audio.cpp @@ -6,27 +6,27 @@ AudioInput::AudioInput() AddParameter(samples_output_); } -Node *AudioInput::copy() +Node *AudioInput::copy() const { return new AudioInput(); } -QString AudioInput::Name() +QString AudioInput::Name() const { return tr("Audio Input"); } -QString AudioInput::id() +QString AudioInput::id() const { return "org.olivevideoeditor.Olive.audioinput"; } -QString AudioInput::Category() +QString AudioInput::Category() const { return tr("Input"); } -QString AudioInput::Description() +QString AudioInput::Description() const { return tr("Import an audio footage stream."); } @@ -36,12 +36,7 @@ NodeOutput *AudioInput::samples_output() return samples_output_; } -QVariant AudioInput::Value(NodeOutput *output) +NodeValueTable AudioInput::Value(const NodeValueDatabase &value) const { - if (output == samples_output_) { - // Simple passthrough from footage input - return footage_input_->value(); - } - - return MediaInput::Value(output); + return value[footage_input_]; } diff --git a/app/node/input/media/audio/audio.h b/app/node/input/media/audio/audio.h index f8ae6a15d..646dc2b48 100644 --- a/app/node/input/media/audio/audio.h +++ b/app/node/input/media/audio/audio.h @@ -8,17 +8,17 @@ class AudioInput : public MediaInput public: AudioInput(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Category() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Category() const override; + virtual QString Description() const override; NodeOutput* samples_output(); protected: - virtual QVariant Value(NodeOutput* output) override; + virtual NodeValueTable Value(const NodeValueDatabase& value) const override; private: NodeOutput* samples_output_; diff --git a/app/node/input/media/video/video.cpp b/app/node/input/media/video/video.cpp index a6ccb6f16..5e2483a71 100644 --- a/app/node/input/media/video/video.cpp +++ b/app/node/input/media/video/video.cpp @@ -18,27 +18,27 @@ VideoInput::VideoInput() AddParameter(texture_output_); } -Node *VideoInput::copy() +Node *VideoInput::copy() const { return new VideoInput(); } -QString VideoInput::Name() +QString VideoInput::Name() const { return tr("Video Input"); } -QString VideoInput::id() +QString VideoInput::id() const { return "org.olivevideoeditor.Olive.videoinput"; } -QString VideoInput::Category() +QString VideoInput::Category() const { return tr("Input"); } -QString VideoInput::Description() +QString VideoInput::Description() const { return tr("Import a video footage stream."); } @@ -48,17 +48,17 @@ void VideoInput::Release() MediaInput::Release(); } -NodeInput *VideoInput::matrix_input() +NodeInput *VideoInput::matrix_input() const { return matrix_input_; } -NodeOutput *VideoInput::texture_output() +NodeOutput *VideoInput::texture_output() const { return texture_output_; } -QString VideoInput::Code(NodeOutput *output) +QString VideoInput::Code(NodeOutput *output) const { if (output == texture_output()) { return "#version 110\n" diff --git a/app/node/input/media/video/video.h b/app/node/input/media/video/video.h index d722454a4..0a5589feb 100644 --- a/app/node/input/media/video/video.h +++ b/app/node/input/media/video/video.h @@ -11,20 +11,20 @@ class VideoInput : public MediaInput public: VideoInput(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Category() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Category() const override; + virtual QString Description() const override; virtual void Release() override; - NodeInput* matrix_input(); + NodeInput* matrix_input() const; - NodeOutput* texture_output(); + NodeOutput* texture_output() const; - virtual QString Code(NodeOutput* output) override; + virtual QString Code(NodeOutput* output) const override; //virtual void Hash(QCryptographicHash *hash, NodeOutput* from, const rational &time) override; diff --git a/app/node/node.cpp b/app/node/node.cpp index 3732adc50..13d9a7ebe 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -45,13 +45,13 @@ Node::~Node() } } -QString Node::Category() +QString Node::Category() const { // Return an empty category for any nodes that don't use one return QString(); } -QString Node::Description() +QString Node::Description() const { // Return an empty string by default return QString(); @@ -85,11 +85,11 @@ void Node::AddParameter(NodeParam *param) } } -QVariant Node::Value(NodeOutput *output) +NodeValueTable Node::Value(const NodeValueDatabase &value) const { - Q_UNUSED(output) + Q_UNUSED(value) - return QVariant(); + return NodeValueTable(); } void Node::InvalidateCache(const rational &start_range, const rational &end_range, NodeInput *from) @@ -99,7 +99,7 @@ void Node::InvalidateCache(const rational &start_range, const rational &end_rang SendInvalidateCache(start_range, end_range); } -TimeRange Node::InputTimeAdjustment(NodeInput *input, const TimeRange &input_time) +TimeRange Node::InputTimeAdjustment(NodeInput *input, const TimeRange &input_time) const { Q_UNUSED(input) @@ -156,26 +156,6 @@ void Node::UnlockUserInput() user_input_lock_.unlock(); } -void Node::LockProcessing() -{ - processing_lock_.lock(); -} - -void Node::UnlockProcessing() -{ - processing_lock_.unlock(); -} - -bool Node::IsProcessingLocked() -{ - if (processing_lock_.tryLock()) { - processing_lock_.unlock(); - return false; - } else { - return true; - } -} - void Node::CopyInputs(Node *source, Node *destination, bool include_connections) { Q_ASSERT(source->id() == destination->id()); @@ -232,7 +212,7 @@ void Node::DuplicateConnectionsBetweenLists(const QList &source, const Q } } -bool Node::CanBeDeleted() +bool Node::CanBeDeleted() const { return can_be_deleted_; } @@ -242,12 +222,12 @@ void Node::SetCanBeDeleted(bool s) can_be_deleted_ = s; } -bool Node::IsBlock() +bool Node::IsBlock() const { return false; } -bool Node::IsTrack() +bool Node::IsTrack() const { return false; } @@ -278,12 +258,12 @@ NodeOutput *Node::LastProcessedOutput() return o; } -const QList& Node::parameters() +const QList& Node::parameters() const { return params_; } -int Node::IndexOfParameter(NodeParam *param) +int Node::IndexOfParameter(NodeParam *param) const { return params_.indexOf(param); } @@ -296,7 +276,7 @@ int Node::IndexOfParameter(NodeParam *param) * TRUE to recursively traverse each node for a complete dependency graph. FALSE to return only the immediate * dependencies. */ -void GetDependenciesInternal(Node* n, QList& list, bool traverse) { +void GetDependenciesInternal(const Node* n, QList& list, bool traverse) { foreach (NodeParam* p, n->parameters()) { if (p->type() == NodeParam::kInput) { Node* connected = static_cast(p)->get_connected_node(); @@ -312,7 +292,7 @@ void GetDependenciesInternal(Node* n, QList& list, bool traverse) { } } -QList Node::GetDependencies() +QList Node::GetDependencies() const { QList node_list; @@ -321,7 +301,7 @@ QList Node::GetDependencies() return node_list; } -QList Node::GetExclusiveDependencies() +QList Node::GetExclusiveDependencies() const { QList deps = GetDependencies(); @@ -356,7 +336,7 @@ QList Node::GetExclusiveDependencies() return deps; } -QList Node::GetImmediateDependencies() +QList Node::GetImmediateDependencies() const { QList node_list; @@ -365,14 +345,14 @@ QList Node::GetImmediateDependencies() return node_list; } -QString Node::Code(NodeOutput *output) +QString Node::Code(NodeOutput *output) const { Q_UNUSED(output) return QString(); } -NodeParam *Node::GetParameterWithID(const QString &id) +NodeParam *Node::GetParameterWithID(const QString &id) const { foreach (NodeParam* param, params_) { if (param->id() == id) { @@ -383,7 +363,7 @@ NodeParam *Node::GetParameterWithID(const QString &id) return nullptr; } -bool Node::OutputsTo(Node *n) +bool Node::OutputsTo(Node *n) const { foreach (NodeParam* param, params_) { if (param->type() == NodeParam::kOutput) { @@ -400,22 +380,22 @@ bool Node::OutputsTo(Node *n) return false; } -bool Node::HasInputs() +bool Node::HasInputs() const { return HasParamOfType(NodeParam::kInput, false); } -bool Node::HasOutputs() +bool Node::HasOutputs() const { return HasParamOfType(NodeParam::kOutput, false); } -bool Node::HasConnectedInputs() +bool Node::HasConnectedInputs() const { return HasParamOfType(NodeParam::kInput, true); } -bool Node::HasConnectedOutputs() +bool Node::HasConnectedOutputs() const { return HasParamOfType(NodeParam::kOutput, true); } @@ -432,7 +412,7 @@ QVariant Node::PtrToValue(void *ptr) return reinterpret_cast(ptr); } -bool Node::HasParamWithID(const QString &id) +bool Node::HasParamWithID(const QString &id) const { foreach (NodeParam* p, params_) { @@ -445,7 +425,7 @@ bool Node::HasParamWithID(const QString &id) return false; } -bool Node::HasParamOfType(NodeParam::Type type, bool must_be_connected) +bool Node::HasParamOfType(NodeParam::Type type, bool must_be_connected) const { foreach (NodeParam* p, params_) { if (p->type() == type diff --git a/app/node/node.h b/app/node/node.h index c47cb449c..1f4593307 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -30,6 +30,7 @@ #include "node/input.h" #include "node/inputarray.h" #include "node/output.h" +#include "node/value.h" /** * @brief A single processing unit that can be connected with others to create intricate processing systems @@ -59,7 +60,7 @@ public: * By default, the clone will NOT have the values and connections of the original node. The caller is responsible for * copying that data with functions like CopyInputs() as copies may be done for different reasons. */ - virtual Node* copy() = 0; + virtual Node* copy() const = 0; /** * @brief Return the name of the node @@ -67,7 +68,7 @@ public: * This is the node's name shown to the user. This must be overridden by subclasses, and preferably run through the * translator. */ - virtual QString Name() = 0; + virtual QString Name() const = 0; /** * @brief Return the unique identifier of the node @@ -76,7 +77,7 @@ public: * completely unique to this node, and preferably in bundle identifier format (e.g. "org.company.Name"). This string * should NOT be translated. */ - virtual QString id() = 0; + virtual QString id() const = 0; /** * @brief Return the category this node is in (optional for subclassing, but recommended) @@ -86,7 +87,7 @@ public: * interpreted as an empty string category. This value should be run through a translator as its largely user * oriented. */ - virtual QString Category(); + virtual QString Category() const; /** * @brief Return a description of this node's purpose (optional for subclassing, but recommended) @@ -94,7 +95,7 @@ public: * A short (1-2 sentence) description of what this node should do to help the user understand its purpose. This should * be run through a translator. */ - virtual QString Description(); + virtual QString Description() const; /** * @brief Signals the Node that it won't be used for a while and can deallocate some memory @@ -109,18 +110,18 @@ public: /** * @brief Return a list of NodeParams */ - const QList& parameters(); + const QList& parameters() const; /** * @brief Return the index of a parameter * @return Parameter index or -1 if this parameter is not part of this Node */ - int IndexOfParameter(NodeParam* param); + int IndexOfParameter(NodeParam* param) const; /** * @brief Return a list of all Nodes that this Node's inputs are connected to (does not include this Node) */ - QList GetDependencies(); + QList GetDependencies() const; /** * @brief Returns a list of Nodes that this Node is dependent on, provided no other Nodes are dependent on them @@ -128,47 +129,47 @@ public: * * Similar to GetDependencies(), but excludes any Nodes that are used outside the dependency graph of this Node. */ - QList GetExclusiveDependencies(); + QList GetExclusiveDependencies() const; /** * @brief Retrieve immediate dependencies (only nodes that are directly connected to the inputs of this one) */ - QList GetImmediateDependencies(); + QList GetImmediateDependencies() const; /** * @brief Generate OpenCL hardware accelerated code for this Node */ - virtual QString Code(NodeOutput* output); + virtual QString Code(NodeOutput* output) const; /** * @brief Returns the parameter with the specified ID (or nullptr if it doesn't exist) */ - NodeParam* GetParameterWithID(const QString& id); + NodeParam* GetParameterWithID(const QString& id) const; /** * @brief Returns whether this Node outputs data to the Node `n` in any way */ - bool OutputsTo(Node* n); + bool OutputsTo(Node* n) const; /** * @brief Return whether this Node has input parameters */ - bool HasInputs(); + bool HasInputs() const; /** * @brief Return whether this Node has output parameters */ - bool HasOutputs(); + bool HasOutputs() const; /** * @brief Return whether this Node has input parameters and at least one of them is connected */ - bool HasConnectedInputs(); + bool HasConnectedInputs() const; /** * @brief Return whether this Node has output parameters and at least one of them is connected */ - bool HasConnectedOutputs(); + bool HasConnectedOutputs() const; /** * @brief Severs all input and output connections @@ -197,7 +198,7 @@ public: */ virtual void InvalidateCache(const rational& start_range, const rational& end_range, NodeInput* from = nullptr); - virtual TimeRange InputTimeAdjustment(NodeInput* input, const TimeRange& input_time); + virtual TimeRange InputTimeAdjustment(NodeInput* input, const TimeRange& input_time) const; /** * @brief User input lock prevents any user changes while a graph is being rendered @@ -205,13 +206,6 @@ public: void LockUserInput(); void UnlockUserInput(); - /** - * @brief Processing lock prevents more than one thread trying to process a Node at once - */ - void LockProcessing(); - void UnlockProcessing(); - bool IsProcessingLocked(); - /** * @brief Copies inputs from from Node to another including connections * @@ -227,7 +221,7 @@ public: /** * @brief Return whether this Node can be deleted or not */ - bool CanBeDeleted(); + bool CanBeDeleted() const; /** * @brief Set whether this Node can be deleted in the UI or not @@ -240,7 +234,7 @@ public: * You shouldn't ever need to override this since all derivatives of Block will automatically have this set to true. * It's just a more convenient way of checking than dynamic_casting. */ - virtual bool IsBlock(); + virtual bool IsBlock() const; /** * @brief Returns whether this Node is a "Track" type or not @@ -248,7 +242,7 @@ public: * You shouldn't ever need to override this since all derivatives of Track will automatically have this set to true. * It's just a more convenient way of checking than dynamic_casting. */ - virtual bool IsTrack(); + virtual bool IsTrack() const; /** * @brief The main processing function @@ -263,12 +257,12 @@ public: * corresponding output if it's connected to one. If your node doesn't directly deal with time, the default behavior * of the NodeParam objects will handle everything related to it automatically. */ - virtual QVariant Value(NodeOutput* output); + virtual NodeValueTable Value(const NodeValueDatabase& value) const; /** * @brief Return whether a parameter with ID `id` has already been added to this Node */ - bool HasParamWithID(const QString& id); + bool HasParamWithID(const QString& id) const; protected: /** @@ -318,7 +312,7 @@ signals: void EdgeRemoved(NodeEdgePtr edge); private: - bool HasParamOfType(NodeParam::Type type, bool must_be_connected); + bool HasParamOfType(NodeParam::Type type, bool must_be_connected) const; void ConnectInput(NodeInput* input); @@ -341,11 +335,6 @@ private: */ QMutex user_input_lock_; - /** - * @brief Used for thread safety between multiple threads - */ - QMutex processing_lock_; - /** * @brief Internal variable for whether this Node can be deleted or not */ diff --git a/app/node/output/timeline/timeline.cpp b/app/node/output/timeline/timeline.cpp index 852ec0eac..d08bf07e6 100644 --- a/app/node/output/timeline/timeline.cpp +++ b/app/node/output/timeline/timeline.cpp @@ -35,7 +35,6 @@ TimelineOutput::TimelineOutput() for (int i=0;iset_data_type(NodeParam::kTrack); AddParameter(track_input); track_inputs_.replace(i, track_input); @@ -53,58 +52,61 @@ TimelineOutput::TimelineOutput() AddParameter(length_output_); } -Node *TimelineOutput::copy() +Node *TimelineOutput::copy() const { return new TimelineOutput(); } -QString TimelineOutput::Name() +QString TimelineOutput::Name() const { return tr("Timeline"); } -QString TimelineOutput::id() +QString TimelineOutput::id() const { return "org.olivevideoeditor.Olive.timeline"; } -QString TimelineOutput::Category() +QString TimelineOutput::Category() const { return tr("Output"); } -QString TimelineOutput::Description() +QString TimelineOutput::Description() const { return tr("Node for communicating between a Timeline panel and the node graph."); } -QVector TimelineOutput::Tracks() -{ - return track_cache_; -} - -NodeOutput *TimelineOutput::length_output() -{ - return length_output_; -} - -const rational &TimelineOutput::timeline_length() +const rational &TimelineOutput::length() const { return length_; } -const rational &TimelineOutput::Timebase() +const QVector& TimelineOutput::Tracks() const +{ + return track_cache_; +} + +NodeOutput *TimelineOutput::length_output() const +{ + return length_output_; +} + +const rational &TimelineOutput::timeline_length() const +{ + return length_; +} + +const rational &TimelineOutput::timebase() const { return timebase_; } -QVariant TimelineOutput::Value(NodeOutput *output) +NodeValueTable TimelineOutput::Value(const NodeValueDatabase &value) const { - if (output == length_output_) { - return QVariant::fromValue(length_); - } - - return 0; + NodeValueTable table = value.Merge(); + table.Push(NodeParam::kRational, QVariant::fromValue(length())); + return table; } void TimelineOutput::UpdateTrackCache() @@ -150,12 +152,12 @@ void TimelineOutput::SetTimebase(const rational &timebase) emit TimebaseChanged(timebase_); } -NodeInput *TimelineOutput::track_input(TrackType type) +NodeInput *TimelineOutput::track_input(TrackType type) const { return track_inputs_.at(type); } -TrackList *TimelineOutput::track_list(TrackType type) +TrackList *TimelineOutput::track_list(TrackType type) const { return track_lists_.at(type); } diff --git a/app/node/output/timeline/timeline.h b/app/node/output/timeline/timeline.h index 5f9364709..35fd00184 100644 --- a/app/node/output/timeline/timeline.h +++ b/app/node/output/timeline/timeline.h @@ -37,24 +37,26 @@ class TimelineOutput : public Node public: TimelineOutput(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Category() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Category() const override; + virtual QString Description() const override; - QVector Tracks(); + const rational& length() const; - NodeInput* track_input(TrackType type); + const QVector &Tracks() const; - TrackList* track_list(TrackType type); + NodeInput* track_input(TrackType type) const; - NodeOutput* length_output(); + TrackList* track_list(TrackType type) const; - const rational& timeline_length(); + NodeOutput* length_output() const; - const rational& Timebase(); + const rational& timeline_length() const; + + const rational& timebase() const; void SetTimebase(const rational &timebase); @@ -69,7 +71,7 @@ signals: void TrackRemoved(TrackOutput* track); protected: - virtual QVariant Value(NodeOutput* output) override; + virtual NodeValueTable Value(const NodeValueDatabase& value) const override; private: QVector track_inputs_; diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 6b894f73a..fd742fe5a 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -37,7 +37,6 @@ TrackOutput::TrackOutput() : connect(block_input_, SIGNAL(SizeChanged(int)), this, SLOT(BlockListSizeChanged(int))); track_input_ = new NodeInput("track_in"); - track_input_->set_data_type(NodeParam::kTrack); track_input_->set_dependent(false); AddParameter(track_input_); @@ -55,32 +54,32 @@ const TrackType& TrackOutput::track_type() return track_type_; } -Block::Type TrackOutput::type() +Block::Type TrackOutput::type() const { return kTrack; } -Block *TrackOutput::copy() +Block *TrackOutput::copy() const { return new TrackOutput(); } -QString TrackOutput::Name() +QString TrackOutput::Name() const { return tr("Track"); } -QString TrackOutput::id() +QString TrackOutput::id() const { return "org.olivevideoeditor.Olive.track"; } -QString TrackOutput::Category() +QString TrackOutput::Category() const { return tr("Output"); } -QString TrackOutput::Description() +QString TrackOutput::Description() const { return tr("Node for representing and processing a single array of Blocks sorted by time. Also represents the end of " "a Sequence."); @@ -98,7 +97,8 @@ void TrackOutput::SetIndex(const int &index) TrackOutput *TrackOutput::next_track() { - return ValueToPtr(track_input_->get_realtime_value_of_connected_output()); + // FIXME: Re-do this without dynamic_cast at some point + return dynamic_cast(track_input_->get_connected_node()); } NodeInput *TrackOutput::track_input() @@ -111,7 +111,7 @@ NodeOutput* TrackOutput::track_output() return track_output_; } -Block *TrackOutput::BlockContainingTime(const rational &time) +Block *TrackOutput::BlockContainingTime(const rational &time) const { foreach (Block* block, block_cache_) { if (block->in() < time && block->out() > time) { @@ -124,7 +124,7 @@ Block *TrackOutput::BlockContainingTime(const rational &time) return nullptr; } -Block *TrackOutput::NearestBlockBefore(const rational &time) +Block *TrackOutput::NearestBlockBefore(const rational &time) const { foreach (Block* block, block_cache_) { // Blocks are sorted by time, so the first Block who's out point is at/after this time is the correct Block @@ -133,10 +133,10 @@ Block *TrackOutput::NearestBlockBefore(const rational &time) } } - return this; + return nullptr; } -Block *TrackOutput::NearestBlockAfter(const rational &time) +Block *TrackOutput::NearestBlockAfter(const rational &time) const { foreach (Block* block, block_cache_) { // Blocks are sorted by time, so the first Block after this time is the correct Block @@ -145,10 +145,10 @@ Block *TrackOutput::NearestBlockAfter(const rational &time) } } - return this; + return nullptr; } -const QVector &TrackOutput::Blocks() +const QVector &TrackOutput::Blocks() const { return block_cache_; } @@ -163,17 +163,6 @@ void TrackOutput::InvalidateCache(const rational &start_range, const rational &e Node::InvalidateCache(start_range, end_range, from); } -QVariant TrackOutput::Value(NodeOutput *output) -{ - if (output == track_output_) { - // Set track output correctly - return PtrToValue(this); - } - - // Run default node processing - return Block::Value(output); -} - void TrackOutput::InsertBlockBefore(Block* block, Block* after) { InsertBlockAtIndex(block, block_cache_.indexOf(after)); @@ -301,12 +290,12 @@ TrackOutput *TrackOutput::TrackFromBlock(Block *block) return nullptr; } -const rational &TrackOutput::track_length() +const rational &TrackOutput::track_length() const { return track_length_; } -bool TrackOutput::IsTrack() +bool TrackOutput::IsTrack() const { return true; } diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index b16698007..798c3ef35 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -36,14 +36,14 @@ public: const TrackType& track_type(); void set_track_type(const TrackType& track_type); - virtual Type type() override; + virtual Type type() const override; - virtual Block* copy() override; + virtual Block* copy() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Category() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Category() const override; + virtual QString Description() const override; const int& Index(); void SetIndex(const int& index); @@ -54,13 +54,13 @@ public: NodeOutput* track_output(); - Block* BlockContainingTime(const rational& time); + Block* BlockContainingTime(const rational& time) const; - Block* NearestBlockBefore(const rational& time); + Block* NearestBlockBefore(const rational& time) const; - Block* NearestBlockAfter(const rational& time); + Block* NearestBlockAfter(const rational& time) const; - const QVector& Blocks(); + const QVector& Blocks() const; virtual void InvalidateCache(const rational& start_range, const rational& end_range, NodeInput* from = nullptr) override; @@ -124,9 +124,9 @@ public: static TrackOutput* TrackFromBlock(Block* block); - const rational& track_length(); + const rational& track_length() const; - virtual bool IsTrack() override; + virtual bool IsTrack() const override; signals: /** @@ -145,7 +145,6 @@ signals: void TrackLengthChanged(); protected: - virtual QVariant Value(NodeOutput* output) override; private: void UpdateInOutFrom(int index); diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index f9a8ef6a7..9962fafc9 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -35,27 +35,27 @@ ViewerOutput::ViewerOutput() AddParameter(length_input_); } -Node *ViewerOutput::copy() +Node *ViewerOutput::copy() const { return new ViewerOutput(); } -QString ViewerOutput::Name() +QString ViewerOutput::Name() const { return tr("Viewer"); } -QString ViewerOutput::id() +QString ViewerOutput::id() const { return "org.olivevideoeditor.Olive.vieweroutput"; } -QString ViewerOutput::Category() +QString ViewerOutput::Category() const { return tr("Output"); } -QString ViewerOutput::Description() +QString ViewerOutput::Description() const { return tr("Interface between a Viewer panel and the node system."); } @@ -115,7 +115,8 @@ void ViewerOutput::set_audio_params(const AudioParams &audio) rational ViewerOutput::Length() { - return length_input_->get_realtime_value_of_connected_output().value(); + // FIXME: This is pretty messy, there's probably a better way... + return length_input_->get_connected_node()->Value(NodeValueDatabase()).Get(NodeParam::kRational).value(); } void ViewerOutput::DependentEdgeChanged(NodeInput *from) diff --git a/app/node/output/viewer/viewer.h b/app/node/output/viewer/viewer.h index cc524fec1..3570e7a50 100644 --- a/app/node/output/viewer/viewer.h +++ b/app/node/output/viewer/viewer.h @@ -36,12 +36,12 @@ class ViewerOutput : public Node public: ViewerOutput(); - virtual Node* copy() override; + virtual Node* copy() const override; - virtual QString Name() override; - virtual QString id() override; - virtual QString Category() override; - virtual QString Description() override; + virtual QString Name() const override; + virtual QString id() const override; + virtual QString Category() const override; + virtual QString Description() const override; NodeInput* texture_input(); NodeInput* samples_input(); diff --git a/app/node/value.cpp b/app/node/value.cpp new file mode 100644 index 000000000..8c066cf65 --- /dev/null +++ b/app/node/value.cpp @@ -0,0 +1,153 @@ +#include "value.h" + +NodeValueDatabase::NodeValueDatabase() +{ + +} + +NodeValueTable NodeValueDatabase::operator[](const QString &input_id) const +{ + return tables_.value(input_id); +} + +NodeValueTable NodeValueDatabase::operator[](const NodeInput *input) const +{ + return tables_.value(input->id()); +} + +void NodeValueDatabase::Insert(const QString &key, const NodeValueTable &value) +{ + tables_.insert(key, value); +} + +void NodeValueDatabase::Insert(const NodeInput *key, const NodeValueTable &value) +{ + tables_.insert(key->id(), value); +} + +NodeValueTable NodeValueDatabase::Merge() const +{ + if (tables_.size() == 1) { + return tables_.begin().value(); + } + + int row = 0; + + NodeValueTable merged_table; + + QHash::const_iterator iterator; + + // Slipstreams all tables together + // FIXME: I don't actually know if this is the right approach... + for (iterator = tables_.begin();iterator != tables_.end();iterator++) { + const NodeValueTable& table = iterator.value(); + + if (row >= table.Count()) { + continue; + } + + int row_index = table.Count() - 1 - row; + + merged_table.Prepend(table.At(row_index)); + } + + return merged_table; +} + +NodeValue::NodeValue(const NodeParam::DataType &type, const QVariant &data, const QString &tag) : + type_(type), + data_(data), + tag_(tag) +{ +} + +const NodeParam::DataType &NodeValue::type() const +{ + return type_; +} + +const QString &NodeValue::tag() const +{ + return tag_; +} + +const QVariant &NodeValue::data() const +{ + return data_; +} + +NodeValueTable::NodeValueTable() +{ +} + +QVariant NodeValueTable::Get(const NodeParam::DataType &type, const QString &tag) +{ + return GetInternal(type, tag, false); +} + +QVariant NodeValueTable::Take(const NodeParam::DataType &type, const QString &tag) +{ + return GetInternal(type, tag, true); +} + +void NodeValueTable::Push(const NodeValue &value) +{ + values_.append(value); +} + +void NodeValueTable::Push(const NodeParam::DataType &type, const QVariant &data, const QString &tag) +{ + Push(NodeValue(type, data, tag)); +} + +void NodeValueTable::Prepend(const NodeValue &value) +{ + values_.prepend(value); +} + +void NodeValueTable::Prepend(const NodeParam::DataType &type, const QVariant &data, const QString &tag) +{ + Prepend(NodeValue(type, data, tag)); +} + +const NodeValue &NodeValueTable::At(int index) const +{ + return values_.at(index); +} + +int NodeValueTable::Count() const +{ + return values_.size(); +} + +bool NodeValueTable::isEmpty() const +{ + return values_.isEmpty(); +} + +QVariant NodeValueTable::GetInternal(const NodeParam::DataType &type, const QString &tag, bool remove) +{ + int index = -1; + + for (int i=values_.size() - 1;i>=0;i--) { + const NodeValue& v = values_.at(i); + + if (v.type() & type) { + index = i; + + if (tag.isEmpty() || tag == v.tag()) { + break; + } + } + } + + if (index >= 0) { + if (remove) { + values_.removeAt(index); + } + + return values_.at(index).data(); + } + + return QVariant(); +} diff --git a/app/node/value.h b/app/node/value.h new file mode 100644 index 000000000..f9cafa76a --- /dev/null +++ b/app/node/value.h @@ -0,0 +1,65 @@ +#ifndef VALUE_H +#define VALUE_H + +#include + +#include "input.h" + +class NodeValue +{ +public: + NodeValue(const NodeParam::DataType& type, const QVariant& data, const QString& tag = QString()); + + const NodeParam::DataType& type() const; + const QVariant& data() const; + const QString& tag() const; + +private: + NodeParam::DataType type_; + QVariant data_; + QString tag_; + +}; + +class NodeValueTable +{ +public: + NodeValueTable(); + + QVariant Get(const NodeParam::DataType& type, const QString& tag = QString()); + QVariant Take(const NodeParam::DataType& type, const QString& tag = QString()); + void Push(const NodeValue& value); + void Push(const NodeParam::DataType& type, const QVariant& data, const QString& tag = QString()); + void Prepend(const NodeValue& value); + void Prepend(const NodeParam::DataType& type, const QVariant& data, const QString& tag = QString()); + const NodeValue& At(int index) const; + int Count() const; + + bool isEmpty() const; + +private: + QVariant GetInternal(const NodeParam::DataType& type, const QString& tag, bool remove); + + QList values_; + +}; + +class NodeValueDatabase +{ +public: + NodeValueDatabase(); + + NodeValueTable operator[](const QString& input_id) const; + NodeValueTable operator[](const NodeInput* input) const; + + void Insert(const QString& key, const NodeValueTable &value); + void Insert(const NodeInput* key, const NodeValueTable& value); + + NodeValueTable Merge() const; + +private: + QHash tables_; + +}; + +#endif // VALUE_H