438 lines
10 KiB
C++
438 lines
10 KiB
C++
/***
|
|
|
|
Olive - Non-Linear Video Editor
|
|
Copyright (C) 2019 Olive Team
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
***/
|
|
|
|
#ifndef NODEPARAM_H
|
|
#define NODEPARAM_H
|
|
|
|
#include <QObject>
|
|
#include <QVariant>
|
|
#include <QVector>
|
|
#include <QXmlStreamWriter>
|
|
|
|
#include "common/rational.h"
|
|
#include "common/xmlutils.h"
|
|
#include "node/edge.h"
|
|
|
|
OLIVE_NAMESPACE_ENTER
|
|
|
|
class Node;
|
|
|
|
/**
|
|
* @brief A base parameter of a Node
|
|
*
|
|
* The main data points of a Node. NodeParams are added to Nodes so that Node::Process() can use data acquired either
|
|
* directly as a value set by the user, or through the output of another NodeParam.
|
|
*
|
|
* This is an abstract base class. In most cases you'll want NodeInput or NodeOutput.
|
|
*/
|
|
class NodeParam : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
/**
|
|
* @brief The type of parameter this is
|
|
*/
|
|
enum Type {
|
|
kInput,
|
|
kOutput
|
|
};
|
|
|
|
/**
|
|
* @brief The types of data that can be passed between Nodes
|
|
*/
|
|
enum DataType {
|
|
kNone = 0x0,
|
|
|
|
/**
|
|
****************************** SPECIFIC IDENTIFIERS ******************************
|
|
*/
|
|
|
|
/**
|
|
* Integer type
|
|
*
|
|
* Resolves to int64_t.
|
|
*/
|
|
kInt = 0x1,
|
|
|
|
/**
|
|
* Decimal (floating-point) type
|
|
*
|
|
* Resolves to `double`.
|
|
*/
|
|
kFloat = 0x2,
|
|
|
|
/**
|
|
* Decimal (rational) type
|
|
*
|
|
* Resolves to `double`.
|
|
*/
|
|
kRational = 0x4,
|
|
|
|
/**
|
|
* Boolean type
|
|
*
|
|
* Resolves to `bool`.
|
|
*/
|
|
kBoolean = 0x8,
|
|
|
|
/**
|
|
* Floating-point type
|
|
*
|
|
* Resolves to `Color`.
|
|
*
|
|
* Colors passed around the nodes should always be in reference space and preferably use
|
|
*/
|
|
kColor = 0x10,
|
|
|
|
/**
|
|
* Matrix type
|
|
*
|
|
* Resolves to `QMatrix4x4`.
|
|
*/
|
|
kMatrix = 0x20,
|
|
|
|
/**
|
|
* Text type
|
|
*
|
|
* Resolves to `QString`.
|
|
*/
|
|
kText = 0x40,
|
|
|
|
/**
|
|
* Font type
|
|
*
|
|
* Resolves to `QFont`.
|
|
*/
|
|
kFont = 0x80,
|
|
|
|
/**
|
|
* File type
|
|
*
|
|
* Resolves to a `QString` containing an absolute file path.
|
|
*/
|
|
kFile = 0x100,
|
|
|
|
/**
|
|
* Image buffer type
|
|
*
|
|
* True value type depends on the render engine used.
|
|
*/
|
|
kTexture = 0x200,
|
|
|
|
/**
|
|
* Audio samples type
|
|
*
|
|
* Resolves to `SampleBufferPtr`.
|
|
*/
|
|
kSamples = 0x400,
|
|
|
|
/**
|
|
* Footage stream identifier type
|
|
*
|
|
* Resolves to `StreamPtr`.
|
|
*/
|
|
kFootage = 0x800,
|
|
|
|
/**
|
|
* Two-dimensional vector (XY) type
|
|
*
|
|
* Resolves to `QVector2D`.
|
|
*/
|
|
kVec2 = 0x1000,
|
|
|
|
/**
|
|
* Three-dimensional vector (XYZ) type
|
|
*
|
|
* Resolves to `QVector3D`.
|
|
*/
|
|
kVec3 = 0x2000,
|
|
|
|
/**
|
|
* Four-dimensional vector (XYZW) type
|
|
*
|
|
* Resolves to `QVector4D`.
|
|
*/
|
|
kVec4 = 0x4000,
|
|
|
|
/**
|
|
* ComboBox type
|
|
*
|
|
* Resolves to `int` - the index currently selected
|
|
*/
|
|
kCombo = 0x8000,
|
|
|
|
/**
|
|
* Job type
|
|
*
|
|
* An internal type used to indicate to the renderer that an accelerated shader job needs to
|
|
* run. This value will usually be taken from a table and a kTexture value will be pushed to
|
|
* take its place.
|
|
*/
|
|
kShaderJob = 0x10000,
|
|
|
|
/**
|
|
* Job type
|
|
*
|
|
* An internal type used to indicate to the renderer that an accelerated sample job needs to
|
|
* take place. This value will usually be taken from a table and a kSamples value will be
|
|
* pushed to take its place.
|
|
*/
|
|
kSampleJob = 0x20000,
|
|
|
|
/**
|
|
* Job type
|
|
*
|
|
* An internal type used to indicate to the renderer that an accelerated sample job needs to
|
|
* take place. This value will usually be taken from a table and a kSamples value will be
|
|
* pushed to take its place.
|
|
*/
|
|
kGenerateJob = 0x40000,
|
|
|
|
/**
|
|
****************************** BROAD IDENTIFIERS ******************************
|
|
*/
|
|
|
|
/**
|
|
* Identifier for type that contains a decimal number
|
|
*
|
|
* Includes kFloat and kRational.
|
|
*/
|
|
kDecimal = 0x6,
|
|
|
|
/**
|
|
* Identifier for type that contains a number of any kind (whole or decimal)
|
|
*
|
|
* Includes kInt, kFloat, and kRational.
|
|
*/
|
|
kNumber = 0x7,
|
|
|
|
/**
|
|
* Identifier for type that contains a text string of any kind.
|
|
*
|
|
* Includes kText and kFile.
|
|
*/
|
|
kString = 0x140,
|
|
|
|
/**
|
|
* Identifier for type that contains a either an image or audio buffer
|
|
*
|
|
* Includes kTexture and kSamples.
|
|
*/
|
|
kBuffer = 0x600,
|
|
|
|
/**
|
|
* Identifier for type that contains a vector (two- to four-dimensional)
|
|
*
|
|
* Includes kVec2, kVec3, kVec4, and kColor.
|
|
*/
|
|
kVector = 0x7010,
|
|
|
|
/**
|
|
* Identifier for any type
|
|
*
|
|
* Matches with all types except for kNone
|
|
*/
|
|
kAny = 0xFFFFFFFF
|
|
};
|
|
|
|
/**
|
|
* @brief NodeParam Constructor
|
|
*/
|
|
NodeParam(const QString& id);
|
|
|
|
virtual ~NodeParam() override;
|
|
|
|
/**
|
|
* @brief Load function
|
|
*/
|
|
virtual void Load(QXmlStreamReader* reader, XMLNodeData& xml_node_data, const QAtomicInt* cancelled) = 0;
|
|
|
|
/**
|
|
* @brief Save function
|
|
*/
|
|
virtual void Save(QXmlStreamWriter* writer) const = 0;
|
|
|
|
/**
|
|
* @brief Return ID of this parameter
|
|
*/
|
|
const QString id() const;
|
|
|
|
/**
|
|
* @brief The type of node parameter this is
|
|
*
|
|
* This must be set in subclasses, but most of the time you should probably subclass from NodeInput and NodeOutput
|
|
* anyway.
|
|
*/
|
|
virtual Type type() = 0;
|
|
|
|
/**
|
|
* @brief Name of this parameter to be shown to the user
|
|
*/
|
|
virtual QString name();
|
|
void set_name(const QString& name);
|
|
|
|
/**
|
|
* @brief Node parent object
|
|
*
|
|
* Nodes and NodeParams use the QObject parent-child system. This function is a convenience function for
|
|
* static_cast<Node*>(QObject::parent())
|
|
*/
|
|
Node* parentNode() const;
|
|
|
|
/**
|
|
* @brief Return the row index of this parameter in the parent node (primarily used for UI drawing functions)
|
|
*/
|
|
int index();
|
|
|
|
/**
|
|
* @brief Returns whether anything is connected to this parameter or not
|
|
*/
|
|
bool is_connected() const;
|
|
|
|
bool is_connectable() const;
|
|
void set_connectable(bool connectable);
|
|
|
|
/**
|
|
* @brief Return a list of edges (aka connections to other nodes)
|
|
*
|
|
* This list can't be modified directly. Use ConnectEdge() and DisconnectEdge() instead for that.
|
|
*/
|
|
const QVector<NodeEdgePtr>& edges();
|
|
|
|
/**
|
|
* @brief Disconnect any edges connecting this parameter to other parameters
|
|
*/
|
|
virtual void DisconnectAll();
|
|
|
|
/**
|
|
* @brief Connect an output parameter to an input parameter
|
|
*
|
|
* This function makes no attempt to check whether the two NodeParams have compatible data types. This should be done
|
|
* beforehand or behavior is undefined.
|
|
*
|
|
* If the input already has an edge connected and can't accept multiple edges, that edge is disconnected before an
|
|
* attempt at a new connection is made. This function returns the new NodeEdge created by this connection.
|
|
*
|
|
* If the input *can* accept multiple edges but is already connected to this output, no new connection is made (since
|
|
* the connection already exists). In this situation, nullptr is returned.
|
|
*
|
|
* This function emits EdgeAdded().
|
|
*/
|
|
static NodeEdgePtr ConnectEdge(NodeOutput *output, NodeInput *input);
|
|
|
|
/**
|
|
* @brief Disconnect an edge
|
|
*
|
|
* This function emits EdgeRemoved(NodeEdgePtr edge).
|
|
*
|
|
* @param edge
|
|
*
|
|
* Edge to disconnect.
|
|
*/
|
|
static void DisconnectEdge(NodeEdgePtr edge);
|
|
|
|
/**
|
|
* @brief Disconnect an edge
|
|
*
|
|
* Sometimes this function is preferable if you don't know what the edge object is (or with undo commands where the
|
|
* edge object may change despite the connection being between the same parameters).
|
|
*
|
|
* This function emits EdgeRemoved(NodeEdgePtr edge).
|
|
*
|
|
* @param edge
|
|
*
|
|
* Edge to disconnect.
|
|
*/
|
|
static void DisconnectEdge(NodeOutput* output, NodeInput* input);
|
|
|
|
/**
|
|
* @brief If an input has an edge and can't take multiple, this function disconnects them and returns the edge object
|
|
*
|
|
* This is used just before a connection is about to be made. If an input is already connected to an output, but
|
|
* can't take multiple inputs, that connection will need to be removed before the new connection can be made.
|
|
* This function check if it's necessary to remove the edge from an input before connecting a new edge, and removes
|
|
* and returns it if so.
|
|
*
|
|
* If the input does NOT have anything connected, or it does but the input CAN accept multiple connections, nothing
|
|
* is disconnected and nullptr is returned.
|
|
*/
|
|
static NodeEdgePtr DisconnectForNewOutput(NodeInput* input);
|
|
|
|
/**
|
|
* @brief Get a human-readable translated name for a certain data type
|
|
*/
|
|
static QString GetPrettyDataTypeName(const DataType &type);
|
|
|
|
/**
|
|
* @brief Convert a value from a NodeParam into bytes
|
|
*/
|
|
static QByteArray ValueToBytes(const DataType &type, const QVariant& value);
|
|
|
|
signals:
|
|
/**
|
|
* @brief Signal emitted when an edge is added to this parameter
|
|
*
|
|
* See ConnectEdge() for usage. Only one of the two parameters needs to emit this signal when a connection is made,
|
|
* because otherwise two of exactly the same signal will be emitted.
|
|
*/
|
|
void EdgeAdded(NodeEdgePtr edge);
|
|
|
|
/**
|
|
* @brief Signal emitted when an edge is removed from this parameter
|
|
*
|
|
* See DisconnectEdge() for usage. Only one of the two parameters needs to emit this signal when a connection is
|
|
* removed, because otherwise two of exactly the same signal will be emitted.
|
|
*/
|
|
void EdgeRemoved(NodeEdgePtr edge);
|
|
|
|
protected:
|
|
/**
|
|
* @brief Internal list of edges
|
|
*/
|
|
QVector<NodeEdgePtr> edges_;
|
|
|
|
/**
|
|
* @brief Internal name string
|
|
*/
|
|
QString name_;
|
|
|
|
private:
|
|
/**
|
|
* @brief Internal function for returning a value in the form of bytes
|
|
*/
|
|
template<typename T>
|
|
static QByteArray ValueToBytesInternal(const QVariant& v);
|
|
|
|
/**
|
|
* @brief Internal ID string
|
|
*/
|
|
QString id_;
|
|
|
|
/**
|
|
* @brief Internal connectable value
|
|
*/
|
|
bool connectable_;
|
|
|
|
};
|
|
|
|
OLIVE_NAMESPACE_EXIT
|
|
|
|
#endif // NODEPARAM_H
|