documented new node classes
This commit is contained in:
@@ -2,6 +2,16 @@
|
||||
#define CLAMP_H
|
||||
|
||||
template<typename T>
|
||||
/**
|
||||
* @brief Clamp a value between a minimum and a maximum value
|
||||
*
|
||||
* Similar to using min() and max() functions, but performs both at once. If value is less than minimum, this returns
|
||||
* minimum. If it is more than maximum, this returns maximum. Otherwise it returns value as-is.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Will always return a value between minimum and maximum (inclusive).
|
||||
*/
|
||||
T clamp(T value, T minimum, T maximum) {
|
||||
if (value < minimum) {
|
||||
return minimum;
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#define LERP_H
|
||||
|
||||
template<typename T>
|
||||
/**
|
||||
* @brief Linearly interpolate a value between a and b using t
|
||||
*/
|
||||
T lerp(T a, T b, double t) {
|
||||
return (a * (1.0 - t)) + (b * t);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
#include "decoder/decoder.h"
|
||||
|
||||
/**
|
||||
* @brief A Decoder derivative that wraps FFmpeg functions as on Olive decoder
|
||||
*/
|
||||
class FFmpegDecoder : public Decoder
|
||||
{
|
||||
public:
|
||||
|
||||
+3
-1
@@ -30,7 +30,9 @@ extern "C" {
|
||||
#include "common/rational.h"
|
||||
|
||||
/**
|
||||
* @brief Abstraction from AVFrame. Currently a simple AVFrame wrapper.
|
||||
* @brief Video frame data or audio sample data from a Decoder
|
||||
*
|
||||
* Abstraction from AVFrame. Currently a simple AVFrame wrapper.
|
||||
*
|
||||
* This class does not support copying at this time.
|
||||
*/
|
||||
|
||||
@@ -26,12 +26,28 @@
|
||||
class NodeOutput;
|
||||
class NodeInput;
|
||||
|
||||
/**
|
||||
* @brief A connection between two node parameters (a NodeOutput and a NodeInput)
|
||||
*
|
||||
* To simplify memory management, it's recommended to use NodeEdgePtr instead of raw pointers when working with
|
||||
* NodeEdge.
|
||||
*/
|
||||
class NodeEdge
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a node edge connecting an output to an input
|
||||
*/
|
||||
NodeEdge(NodeOutput* output, NodeInput* input);
|
||||
|
||||
/**
|
||||
* @brief Return the output parameter this edge is connected to
|
||||
*/
|
||||
NodeOutput* output();
|
||||
|
||||
/**
|
||||
* @brief Return the input parameter this edge is connected to
|
||||
*/
|
||||
NodeInput* input();
|
||||
|
||||
private:
|
||||
|
||||
@@ -17,6 +17,11 @@ QString SolidGenerator::Name()
|
||||
return tr("Solid");
|
||||
}
|
||||
|
||||
QString SolidGenerator::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.solidgenerator";
|
||||
}
|
||||
|
||||
QString SolidGenerator::Category()
|
||||
{
|
||||
return tr("Generator");
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
#include "node/node.h"
|
||||
|
||||
/**
|
||||
* @brief A node that generates a solid color
|
||||
*/
|
||||
class SolidGenerator : public Node
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -12,6 +15,7 @@ public:
|
||||
SolidGenerator();
|
||||
|
||||
virtual QString Name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString Category() override;
|
||||
virtual QString Description() override;
|
||||
|
||||
|
||||
@@ -25,21 +25,50 @@
|
||||
|
||||
#include "node/node.h"
|
||||
|
||||
/**
|
||||
* @brief A collection of nodes
|
||||
*/
|
||||
class NodeGraph : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief NodeGraph Constructor
|
||||
*/
|
||||
NodeGraph();
|
||||
|
||||
/**
|
||||
* @brief Add a node to this graph
|
||||
*
|
||||
* The node will get added to this graph. It is not automatically connected to anything, any connections will need to
|
||||
* be made manually after the node is added. The graph takes ownership of the Node.
|
||||
*/
|
||||
void AddNode(Node* node);
|
||||
|
||||
/**
|
||||
* @brief Return the name of this graph (user-defined)
|
||||
*/
|
||||
const QString& name();
|
||||
|
||||
/**
|
||||
* @brief Set the name of this graph (user-defined)
|
||||
*/
|
||||
void set_name(const QString& name);
|
||||
|
||||
/**
|
||||
* @brief Retrieve a complete list of the nodes belonging to this graph
|
||||
*/
|
||||
QList<Node*> nodes();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when a member node of this graph has been connected to another (creating an "edge")
|
||||
*/
|
||||
void EdgeAdded(NodeEdgePtr edge);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when a member node of this graph has been disconnected from another (removing an "edge")
|
||||
*/
|
||||
void EdgeRemoved(NodeEdgePtr edge);
|
||||
|
||||
private:
|
||||
|
||||
@@ -24,34 +24,102 @@
|
||||
#include "keyframe.h"
|
||||
#include "param.h"
|
||||
|
||||
/**
|
||||
* @brief A node parameter designed to take either user input or data from another node
|
||||
*/
|
||||
class NodeInput : public NodeParam
|
||||
{
|
||||
public:
|
||||
NodeInput();
|
||||
|
||||
/**
|
||||
* @brief Returns kInput
|
||||
*/
|
||||
virtual Type type() override;
|
||||
|
||||
/**
|
||||
* @brief Add a data type that this input accepts
|
||||
*
|
||||
* While an input will usually only accept one data type, NodeInput supports several. Use this to add a data type that
|
||||
* this input can accept.
|
||||
*/
|
||||
void add_data_input(const DataType& data_type);
|
||||
|
||||
/**
|
||||
* @brief Return whether an input can accept a certain type based on its list of data types
|
||||
*
|
||||
* The input checks its list of acceptable data types (added by add_data_input()) to determine whether a certain
|
||||
* data type can be connected to this input.
|
||||
*/
|
||||
bool can_accept_type(const DataType& data_type);
|
||||
|
||||
/**
|
||||
* @brief Return whether this parameter accepts multiple inputs (false by default)
|
||||
*
|
||||
* While an input will usually only accept one connection from an output at any given time, NodeInput does support
|
||||
* more than one. By default this is false, but can be set to true on any input object. If this is true, get_value()
|
||||
* returns QList<QVariant> rather than just a QVariant (but casted to QVariant).
|
||||
*/
|
||||
bool can_accept_multiple_inputs();
|
||||
|
||||
/**
|
||||
* @brief \see can_accept_multiple_inputs().
|
||||
*/
|
||||
void set_can_accept_multiple_inputs(bool b);
|
||||
|
||||
/**
|
||||
* @brief Get the value at a given time
|
||||
*
|
||||
* This function will automatically retrieve the correct value for this input at the given time.
|
||||
*
|
||||
* If an output is connected to this input, a request is made to that output for its value at this time. If multiple
|
||||
* outputs are connected (\see can_accept_multiple_inputs()), a QList<QVariant> (casted to a QVariant) is returned
|
||||
* instead, listing all the outputs' values currently connected.
|
||||
*
|
||||
* If no output is connected, this will return a user-defined value, either a static value if this input is not
|
||||
* keyframed, or an interpolated value between the keyframes at this time.
|
||||
*/
|
||||
QVariant get_value(const rational &time);
|
||||
|
||||
/**
|
||||
* @brief Return whether keyframing is enabled on this input or not
|
||||
*/
|
||||
bool keyframing();
|
||||
|
||||
/**
|
||||
* @brief Set whether keyframing is enabled on this input or not
|
||||
*/
|
||||
void set_keyframing(bool k);
|
||||
|
||||
/**
|
||||
* @brief A list of input data types accepted by this parameter
|
||||
*/
|
||||
const QList<DataType>& inputs();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Internal list of accepted data types
|
||||
*
|
||||
* Use can_accept_type() to check if a type is in this list
|
||||
*/
|
||||
QList<DataType> inputs_;
|
||||
|
||||
/**
|
||||
* @brief Internal keyframe array
|
||||
*
|
||||
* All internal/user-defined data is stored in this array. Even if keyframing is not enabled, this array will contain
|
||||
* one entry which will be used, and its time value will be ignored.
|
||||
*/
|
||||
QList<NodeKeyframe> keyframes_;
|
||||
|
||||
/**
|
||||
* @brief Internal keyframing enabled setting
|
||||
*/
|
||||
bool keyframing_;
|
||||
|
||||
/**
|
||||
* @brief Internal multiple inputs accepted setting
|
||||
*/
|
||||
bool can_accept_multiple_inputs_;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,11 @@ QString ImageInput::Name()
|
||||
return tr("Image");
|
||||
}
|
||||
|
||||
QString ImageInput::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.imageinput";
|
||||
}
|
||||
|
||||
QString ImageInput::Category()
|
||||
{
|
||||
return tr("Input");
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
|
||||
#include "node/node.h"
|
||||
|
||||
/**
|
||||
* @brief A node that imports an image
|
||||
*
|
||||
* FIXME: This will likely be replaced by the Media node as the Media node will be set up to pull from various decoders
|
||||
* from the beginning.
|
||||
*/
|
||||
class ImageInput : public Node
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -12,6 +18,7 @@ public:
|
||||
ImageInput();
|
||||
|
||||
virtual QString Name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString Category() override;
|
||||
virtual QString Description() override;
|
||||
|
||||
|
||||
@@ -25,24 +25,42 @@
|
||||
|
||||
#include "common/rational.h"
|
||||
|
||||
/**
|
||||
* @brief A point of data to be used at a certain time and interpolated with other data
|
||||
*/
|
||||
class NodeKeyframe
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Methods of interpolation to use with this keyframe
|
||||
*/
|
||||
enum Type {
|
||||
kLinear,
|
||||
kHold,
|
||||
kBezier
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief NodeKeyframe Constructor
|
||||
*/
|
||||
NodeKeyframe();
|
||||
|
||||
/**
|
||||
* @brief The time this keyframe is set at
|
||||
*/
|
||||
const rational& time();
|
||||
void set_time(const rational& time);
|
||||
|
||||
/**
|
||||
* @brief The value of this keyframe (i.e. the value to use at this keyframe's time)
|
||||
*/
|
||||
const QVariant& value();
|
||||
void set_value(const QVariant &value);
|
||||
|
||||
/**
|
||||
* @brief The method of interpolation to use with this keyframe
|
||||
*/
|
||||
const Type& type();
|
||||
void set_type(const Type& type);
|
||||
|
||||
|
||||
@@ -27,16 +27,68 @@
|
||||
#include "node/input.h"
|
||||
#include "node/output.h"
|
||||
|
||||
/**
|
||||
* @brief A single processing unit that can be connected with others to create intricate processing systems
|
||||
*
|
||||
* A cornerstone of "visual programming", a node is a single "function" that takes input and returns an output that can
|
||||
* be connected to other nodes. Inputs can be either user-set or retrieved from the output of another node. By joining
|
||||
* several nodes together, intricate, highly customizable, and infinitely extensible systems can be made for processing
|
||||
* data. It can also all be exposed to the user without forcing them to write code or compile anything.
|
||||
*
|
||||
* A major example in Olive is the entire rendering workflow. To render a frame, Olive will work through a node graph
|
||||
* that can be infinitely customized by the user to create images.
|
||||
*
|
||||
* This is a simple base class designed to contain all the functionality for this kind of processing connective unit.
|
||||
* It is an abstract class intended to be subclassed to create nodes with actual functionality.
|
||||
*/
|
||||
class Node : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Node();
|
||||
|
||||
/**
|
||||
* @brief Return the name of the node
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @brief Return the unique identifier of the node
|
||||
*
|
||||
* This is used in save files and any other times a specific node must be picked out at runtime. This must be an ID
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @brief Return the category this node is in (optional for subclassing, but recommended)
|
||||
*
|
||||
* In any organized node menus, show the node in this category. If this node should be in a subfolder of a subfolder,
|
||||
* use a "/" to separate categories (e.g. "Distort/Noise"). The string should not start with a "/" as this will be
|
||||
* interpreted as an empty string category. This value should be run through a translator as its largely user
|
||||
* oriented.
|
||||
*/
|
||||
virtual QString Category();
|
||||
|
||||
/**
|
||||
* @brief Return a description of this node's purpose (optional for subclassing, but recommended)
|
||||
*
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* @brief Add a parameter to this node
|
||||
*
|
||||
* The Node takes ownership of this parameter.
|
||||
*
|
||||
* This can be either an output or an input at any time. Parameters will always appear in the order they're added.
|
||||
*/
|
||||
void AddParameter(NodeParam* param);
|
||||
|
||||
/**
|
||||
@@ -72,10 +124,38 @@ public:
|
||||
int IndexOfParameter(NodeParam* param);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief The main processing function
|
||||
*
|
||||
* The node's main purpose is to take values from inputs to set values in outputs. For whatever subclass node you
|
||||
* create, this is where the code for that goes.
|
||||
*
|
||||
* Note that as a video editor, the node graph has to work across time. Depending on the purpose of your node, it may
|
||||
* output different values depending on the time, and even if not, it will likely be receiving different input
|
||||
* depending on the time. Most of the difficult work here is handled by NodeInput::get_value() which you should pass
|
||||
* the `time` parameter to. It will return its value (at that time, if it's keyframed), or pass the time to a
|
||||
* 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 void Process(const rational& time) = 0;
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when a node is connected to another node (creating an "edge")
|
||||
*
|
||||
* @param edge
|
||||
*
|
||||
* The edge that was added
|
||||
*/
|
||||
void EdgeAdded(NodeEdgePtr edge);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when a node is disconnected from another node (removing an "edge")
|
||||
*
|
||||
* @param edge
|
||||
*
|
||||
* The edge that was removed
|
||||
*/
|
||||
void EdgeRemoved(NodeEdgePtr edge);
|
||||
};
|
||||
|
||||
|
||||
@@ -23,17 +23,52 @@
|
||||
|
||||
#include "param.h"
|
||||
|
||||
/**
|
||||
* @brief A node parameter designed to serve data to the input of another node
|
||||
*/
|
||||
class NodeOutput : public NodeParam
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief NodeOutput Constructor
|
||||
*/
|
||||
NodeOutput();
|
||||
|
||||
/**
|
||||
* @brief Returns kOutput
|
||||
*/
|
||||
virtual Type type() override;
|
||||
|
||||
/**
|
||||
* @brief The data type this parameter outputs
|
||||
*
|
||||
* This can be used in conjunction with NodeInput::can_accept_type() to determine whether this parameter can be
|
||||
* connected to it.
|
||||
*/
|
||||
const DataType& data_type();
|
||||
void set_data_type(const DataType& type);
|
||||
|
||||
/**
|
||||
* @brief Get the value of this output at a given tie
|
||||
*
|
||||
* This function is intended to primarily be called by any connected NodeInputs.
|
||||
*
|
||||
* The first thing this function does is request the parent Node object to Process() at this time. The Node should
|
||||
* then perform whatever actions necessary (usually taking data from inputs and creating output data) to set the
|
||||
* correct value that this output should have at this time (the Node should use set_value() for this). This function
|
||||
* will then return the value that was set after Process() returned.
|
||||
*
|
||||
* In many cases for efficiency, the Node can also ignore this request if it knows the output data will not change
|
||||
* (i.e. if the time has not changed from the last Process()).
|
||||
*/
|
||||
virtual const QVariant& get_value(const rational &time);
|
||||
|
||||
/**
|
||||
* @brief Set the current value of this output
|
||||
*
|
||||
* Intended to only be set by parent Node objects in their Node::Process() function. Whatever result data is intended
|
||||
* for use later in the pipeline should be set here (\see get_value()).
|
||||
*/
|
||||
virtual void set_value(const QVariant& value);
|
||||
|
||||
private:
|
||||
|
||||
@@ -15,6 +15,11 @@ QString ViewerOutput::Name()
|
||||
return tr("Viewer");
|
||||
}
|
||||
|
||||
QString ViewerOutput::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.vieweroutput";
|
||||
}
|
||||
|
||||
QString ViewerOutput::Category()
|
||||
{
|
||||
return tr("Output");
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
#include "node/node.h"
|
||||
#include "panel/viewer/viewer.h"
|
||||
|
||||
/**
|
||||
* @brief A bridge between a node system and a ViewerPanel
|
||||
*
|
||||
* Receives update/time change signals from ViewerPanels and responds by sending them a texture of that frame
|
||||
*/
|
||||
class ViewerOutput : public Node
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -11,6 +16,7 @@ public:
|
||||
ViewerOutput();
|
||||
|
||||
virtual QString Name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString Category() override;
|
||||
virtual QString Description() override;
|
||||
|
||||
|
||||
+2
-2
@@ -113,7 +113,7 @@ bool NodeParam::AreDataTypesCompatible(const DataType &output_type, const QList<
|
||||
NodeEdgePtr NodeParam::ConnectEdge(NodeOutput *output, NodeInput *input)
|
||||
{
|
||||
// If the input can only accept one input (the default) and has one already, disconnect it
|
||||
FreeSpaceForEdgeFromInput(input);
|
||||
DisconnectForNewOutput(input);
|
||||
|
||||
// Make sure it's not a duplicate of an edge that already exists
|
||||
foreach (NodeEdgePtr existing, input->edges()) {
|
||||
@@ -155,7 +155,7 @@ void NodeParam::DisconnectEdge(NodeOutput *output, NodeInput *input)
|
||||
}
|
||||
}
|
||||
|
||||
NodeEdgePtr NodeParam::FreeSpaceForEdgeFromInput(NodeInput *input)
|
||||
NodeEdgePtr NodeParam::DisconnectForNewOutput(NodeInput *input)
|
||||
{
|
||||
// If the input can only accept one input (the default) and has one already, disconnect it
|
||||
if (!input->edges_.isEmpty() && !input->can_accept_multiple_inputs()) {
|
||||
|
||||
+132
-3
@@ -29,15 +29,29 @@
|
||||
|
||||
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,
|
||||
kInt,
|
||||
@@ -53,40 +67,155 @@ public:
|
||||
kAny
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief NodeParam Constructor
|
||||
*/
|
||||
NodeParam();
|
||||
|
||||
/**
|
||||
* @brief The type of node paramter 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
|
||||
*/
|
||||
const 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* parent();
|
||||
|
||||
/**
|
||||
* @brief Return the row index of this parameter in the parent node (primarily used for UI drawing functions)
|
||||
*/
|
||||
int index();
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
static bool AreDataTypesCompatible(NodeParam* a, NodeParam* b);
|
||||
/**
|
||||
* @brief Determine whether two DataTypes are compatible and therefore whether two NodeParams can be connected
|
||||
*
|
||||
* Obviously a data type is compatible with itself, but sometimes fundamentally separate data types may still be
|
||||
* allowed to connect (e.g. an integer output to a float input). This static function should be used to determine
|
||||
* whether a data type is compatible with another.
|
||||
*/
|
||||
static bool AreDataTypesCompatible(const DataType& output_type, const DataType& input_type);
|
||||
|
||||
/**
|
||||
* @brief Overload of AreDataTypesCompatible(const DataType& output_type, const DataType& input_type)
|
||||
*
|
||||
* Use this for a list of input data types (which NodeInput uses as it's possible for it to accept multiple types).
|
||||
*/
|
||||
static bool AreDataTypesCompatible(const DataType& output_type, const QList<DataType>& input_types);
|
||||
|
||||
/**
|
||||
* @brief Overload of AreDataTypesCompatible(const DataType& output_type, const DataType& input_type)
|
||||
*
|
||||
* Convenience function for two NodeParams. Determines which is the input/output and determines whether their types
|
||||
* are compatible.
|
||||
*/
|
||||
static bool AreDataTypesCompatible(NodeParam* a, NodeParam* b);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
static NodeEdgePtr FreeSpaceForEdgeFromInput(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 GetDefaultDataTypeName(const DataType &type);
|
||||
|
||||
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_;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Internal name string
|
||||
*/
|
||||
QString name_;
|
||||
|
||||
};
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include "node/node.h"
|
||||
#include "rendererthread.h"
|
||||
|
||||
/**
|
||||
* @brief A multithreaded OpenGL based renderer for node systems
|
||||
*/
|
||||
class RendererProcessor : public Node
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -15,7 +15,7 @@ void NodeEdgeAddCommand::redo()
|
||||
return;
|
||||
}
|
||||
|
||||
old_edge_ = NodeParam::FreeSpaceForEdgeFromInput(input_);
|
||||
old_edge_ = NodeParam::DisconnectForNewOutput(input_);
|
||||
|
||||
NodeParam::ConnectEdge(output_, input_);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user