classPiiOperationCompound
#include <PiiOperationCompound.h>
PiiOperationCompound is a class that controls a set of operations.
Inherits PiiOperation
Inherited by PiiEngine, PiiVisualSomClassifier
Description
It can contain any number of other operations, which may also be compounds themselves.
Execution
Starting immediately after any of its children changes state to Starting or Running. The state of the compound will turn to Running when all child operations have changed their state to Running.If the execution of any of a compound's child operations is terminated before all of its siblings have changed their state to Running, the compound itself may never change its state to Running. This can happen, for example, if a data source quickly runs out of data. In such a case the state turns first to Starting and then to Stopping and finally to Stopped, omitting Running, although the operations themself were successfully started.
It is important to note that the start(), pause() and interrupt() functions may not immediately change the state of PiiOperationCompound to Started, Paused, or Stopped but to the corresponding intermediate states Starting, Pausing and Interrupted. The state will change to the final state only after all child operations have changed their state. The thread that creates a PiiOperationCompound must run Qt's event handler every now and then. Otherwise, state change signals from child operations won't get delivered, and the compound itself will never change its state. Typically, one does not need to do anything to accomplish this as operations are created in the main thread, which calls QApplication::exec() at some point. If a PiiOperationCompound is created in another thread, one must either run a thread-specific event loop (QThread::exec()) or call QCoreApplication::processEvents() directly.
Naming
objectName, and name parts are separated by dots.Assume the compound contains a PiiImageViewer sub-operation whose objectName is "imageviewer". The image input of this object can be read as follows:
// PiiOperationCompound *compound; PiiInputSocket* input = compound->input("imageviewer.image");
The parsing recurses to sub-operations. Thus, if one knows the internals of compound operations, any input can be found (e.g. "subop.subop.image"). parent denotes the parent operation. This makes it possible to connect to a socket that is within another compound.
In the example below, Op0 contains Op1. In the context of the root operation that contains both Op0 and Op2 (not drawn), the sockets of the operations are denoted by "Op0.Op1.in1", "Op0.Op1.out", and "Op2.in2". In the context of Op0, in2 is "parent.Op2.in2".

Inputs and Outputs
Let us assume we have a pointer to Op0 in the figure above. We can create an alias, i.e. expose any socket within the compound as follows:
//PiiOperation* op0, *op1; op0->exposeInput("Op1.in1", "input", PiiOperationCompound::AliasConnection); // Analogously: op0->exposeInput(op1.input("in1"), "input", PiiOperationCompound::AliasConnection); // Map the output op0->exposeOutput("Op1.out", "output", PiiOperationCompound::AliasConnection);
The result is that Op0 appears to have an input and an output that actually are redirected to/from Op1.
Proxying is useful if a "virtual" input needs to be redirected to many operations. For this, PiiOperationCompound uses the PiiSocketProxy class. Consider the illustration below. The compound operation Masker creates a binary mask for an input image, and multiplies the input by the mask. For this, the image input must be connected to the operation that creates the mask and to the operation that multiplies the mask and the input. What we need to do is to create a proxy input that is connected to two inputs within the compound. From the outside, the input appears as one:

// We assume that the objectName of PiiThresholdingOperation is // "threshold" and that of PiiArithmeticOperation is "multiplier". masker->exposeInputs(QStringList() << "threshold.image" << "multiplier.input0", "image"); // Alias the output as "image" masker->exposeOutput("multiplier.output", "image", PiiOperationCompound::AliasConnection);
Serialization
class MyOperation : public PiiOperationCompound { // Called by the serialization library. Doesn't create child operations. MyOperation(PiiSerialization::Void); // This ensures that properties and child operations are serialized PII_COMPOUND_SERIALIZATION_FUNCTION public: // Called by everybody else. Creates child operations. MyOperation(); };
When registering an operation compound to a plug-in, use the PII_REGISTER_COMPOUND macro instead of PII_REGISTER_OPERATION.
Classes
| struct |
An action function that interrupts a child operation. |
| struct |
An action function that pauses a child operation. |
| struct |
An action function that starts a child operation. |
| struct |
An action function that stops a child operation. |
Public types
|
enum
|
{
ProxyConnection, AliasConnection
}
Connection types. |
Constructors and destructor
|
Constructs a new operation compound. |
|
|
(
|
|
|
Destroys the compound. |
Public member functions
|
virtual Q_INVOKABLE void
|
Adds an operation to the compound's internal operation list. |
|
virtual void
|
(
Checks all child operations. |
|
Q_INVOKABLE int
|
(
)
Returns the number of child operations. |
|
Q_INVOKABLE QList< PiiOperation * >
|
(
)
Returns all direct child operations of this compound as a list. |
|
Q_INVOKABLE void
|
(
)
Deletes all child operations and exposed inputs. |
|
virtual Q_INVOKABLE PiiOperationCompound *
|
(
)
Creates a clone of this compound. |
|
void
|
Creates an unconnected proxy input. |
|
Q_INVOKABLE PiiOperation *
|
A convenience function that creates an instance of the named class and adds it as a child to this compound. |
|
void
|
Creates an unconnected proxy output. |
|
void
|
(
Exposes an input socket to this compound's interface. |
|
void
|
A convenience function that allows one to expose an input socket with the dot syntax (explained above). |
|
void
|
A convenience function that exposes each named socket in |
|
void
|
(
Exposes on output socket to this compound's interface. |
|
void
|
A convenience function that allows one to expose an output socket with the dot syntax (explained above). |
|
virtual PiiAbstractInputSocket *
|
Returns the named input socket. |
|
virtual int
|
(
)
Returns the number of input sockets. |
|
Returns the proxy whose input is reflected as alias. |
|
|
virtual QList< PiiAbstractInputSocket * >
|
(
)
Returns exposed input sockets. |
|
virtual Q_INVOKABLE void
|
(
)
Interrupts all child operations. |
|
virtual PiiAbstractOutputSocket *
|
Returns the named output socket. |
|
virtual int
|
(
)
Returns the number of output sockets. |
|
Returns the proxy whose output is reflected as alias. |
|
|
virtual QList< PiiAbstractOutputSocket * >
|
(
)
Returns exposed output sockets. |
|
virtual Q_INVOKABLE void
|
(
)
Pauses all child operations. |
|
virtual QVariant
|
(
Returns a property using the "dot syntax". |
|
virtual Q_INVOKABLE void
|
Removes an operation from the compound's internal operation list. |
|
Q_INVOKABLE bool
|
Replaces oldOp with newOp. |
|
virtual bool
|
Sets a property in this compound. |
|
virtual QVariant
|
Returns the value associated with name in socket. |
|
virtual void
|
(
)
Starts all child operations. |
|
virtual State
|
(
)
Returns the current state of the operation. |
|
virtual Q_INVOKABLE void
|
(
)
Stops all child operations. |
|
Q_INVOKABLE void
|
(
)
Removes all exposed input and output sockets from the public interface. |
|
void
|
Removes an aliased input socket from the public interface. |
|
void
|
Removes socket from the public interface. |
|
void
|
Removes socket from the public interface. |
|
void
|
Removes an aliased output socket from the public interface. |
|
Q_INVOKABLE bool
|
Waits for the compound to change state to state. |
|
virtual bool
|
(
Waits for all child operations to terminate their execution. |
Protected member functions
|
virtual void
|
Called by setState() just before the operation changes to a new state. |
|
template<class Action>
void
|
(
)
Send a command to all child operations. |
|
(
|
|
|
void
|
Sets the state of the operation. |
Friends
|
friend struct
|
Enumeration details
-
enum ConnectionType
Connection types.
ProxyConnection- exposed socket is routed through a proxy that remains valid even if the exposed socket is deleted. A proxy can be connected to multiple inputs at once.AliasConnection- the exposed socket is shown in the public interface as such. Aliases work with no processing overhead, but an alias input can be connected to just one internal input.
Function details
-
PiiOperationCompound
()Constructs a new operation compound.
-
PiiOperationCompound
(- Data * data
[protected] -
~PiiOperationCompound
()Destroys the compound.
-
Adds an operation to the compound's internal operation list.
The new operation is placed into the QObject's child list of the PiiOperationCompound object. Therefore, the memory taken up by the operations is automatically released upon the destruction of the compound object.
If the compound is not stopped, this function has no effect.
PiiOperationCompound does its best to ensure that its children do not have duplicate object names. If you don't set the object names manually, addOperation() creates a unique name by concatenating the object's class name and an arbitrary number. If the operation already has a name, it will not be modified.
Parameters
- op
the operation
-
virtual void check
(- bool reset
[virtual]Checks all child operations.
Reimplemented from PiiOperation.
-
Q_INVOKABLE int childCount
()Returns the number of child operations.
Equal to but faster than childOperations.size().
-
Q_INVOKABLE QList< PiiOperation * > childOperations
()Returns all direct child operations of this compound as a list.
-
Q_INVOKABLE void clear
()Deletes all child operations and exposed inputs.
-
Creates a clone of this compound.
This function recursively clones all of its child operations.
Returns
a deep copy of the compound.
Reimplemented from PiiOperation.
-
void createInputProxy
Creates an unconnected proxy input.
This function creates a new PiiSocketProxy and reflects its input socket as alias. If alias already exists, the function does nothing.
-
Q_INVOKABLE PiiOperation * createOperation
A convenience function that creates an instance of the named class and adds it as a child to this compound.
If the operation cannot be created, 0 will be returned.
Parameters
- className
the name of the operation to create.
- objectName
set the objectName property of the newly created operation. This parameter is provided for convenience as it often saves a separate setObjectName() call.
Returns
a pointer to the operation or 0 if the class could not be instantiated.
-
void createOutputProxy
Creates an unconnected proxy output.
This function creates a new PiiSocketProxy and reflects its output socket as alias. If alias already exists, the function does nothing.
-
void exposeInput
(- PiiAbstractInputSocket * socket
- const QString & alias
- ConnectionType connectionType = ProxyConnection
Exposes an input socket to this compound's interface.
This function adds an alias or a proxy to a socket attached to an operation within the compound. After exposing, the socket is available with the given name on the public interface of this compound.
By default, this function always creates a proxy socket, which imposes some overhead to passing objects. To create direct connections to the hidden socket, set connectionType to
AliasConnection.Note that output sockets seldom need to be proxied because any output can directly be connected to many inputs. The need for a proxy output arises if you want to connect an output both internally and externally, or you want to preserve the output even when internal operations are deleted.
This function does its best in preserving existing connections. If an existing alias/proxy is replaced, its external connections will be reconnected to the new exposed socket, be it either an alias or a proxy. If an existing proxy is replaced with an alias, only one internal connection will be retained.
Parameters
- socket
the socket to be exposed. Must be owned by an operation that is a child of this compound. If socket is an input, all previously exposed connections to it will be removed first. Outputs can be aliased with multiple names.
- alias
the alias name for the socket. The input() and output() functions use this alias name to find the named socket.
- connectionType
the connection type. If set to
ProxyConnection(the default), multiple internal inputs can be exposed with the same name. If connectionType isAliasConnection, any existing proxy or alias will be replaced. If connectionType isProxyConnection, existing internal connections will be preserved independent of the ConnectionType of the existing connection.
-
void exposeInput
A convenience function that allows one to expose an input socket with the dot syntax (explained above).
-
void exposeInputs
A convenience function that exposes each named socket in
fullNamesas alias. -
void exposeOutput
(- PiiAbstractOutputSocket * socket
- const QString & alias
- ConnectionType connectionType = ProxyConnection
Exposes on output socket to this compound's interface.
See exposeInput().
-
void exposeOutput
A convenience function that allows one to expose an output socket with the dot syntax (explained above).
-
Returns the named input socket.
The name may be either an alias or it can be specified by explicitly mentioning the sub-operations involved. For example,
input("sub.socket")returns the input called "socket" in a child operation called "sub".Reimplemented from PiiOperation.
-
virtual int inputCount
()[virtual]Returns the number of input sockets.
Equivalent to but faster than inputs().size().
Reimplemented from PiiOperation.
-
PiiProxySocket * inputProxy
Returns the proxy whose input is reflected as alias.
If the input does not exist or it is not a proxy input, 0 will be returned.
-
Returns exposed input sockets.
Reimplemented from PiiOperation.
-
virtual Q_INVOKABLE void interrupt
()[virtual]Interrupts all child operations.
The compound immediately changes its state to
Stoppingand turnsStoppedonce all children have turnedStopped. The call has no effect if the compound isStopped.Calling interrupt terminates all child operations as soon as possible, independent of their current processing state. If your configuration has many parallel processing pipelines, they may exit at different phases. For example, if the configuration has two parallel PiiImageFileWriter operations, the image currently being written may be finished by only one of them.
See also
Reimplemented from PiiOperation.
-
virtual int outputCount
()[virtual]Returns the number of output sockets.
Equivalent to but faster than outputs().size().
Reimplemented from PiiOperation.
-
PiiProxySocket * outputProxy
Returns the proxy whose output is reflected as alias.
If the output does not exist or it is not a proxy output, 0 will be returned.
-
Returns exposed output sockets.
Reimplemented from PiiOperation.
-
virtual Q_INVOKABLE void pause
()[virtual]Pauses all child operations.
The compound immediately changes its state to
Pausingand turnsPausedonce all children have turnedPaused. The call has no effect if the compound is notRunning.Reimplemented from PiiOperation.
-
Returns a property using the "dot syntax".
Reimplemented from PiiOperation.
-
Removes an operation from the compound's internal operation list.
The operation no longer belongs to the children of the compound object.
If the compound is neither stopped nor paused, this function has no effect.
Parameters
- op
the operation to remove. All incoming and outgoing connections will be disconnected.
-
Q_INVOKABLE bool replaceOperation
Replaces oldOp with newOp.
If the compound is neither stopped nor paused, this function has no effect. If oldOp has connected inputs and/or outputs, they will be disconnected and reconnected to newOp to the corresponding sockets.
Parameters
- oldOp
the operation to remove
- newOp
the operation to add in stead. If newOp is zero, the function behaves like removeOperation(
oldOp).
Returns
trueif the operation was successsfully replaced/removed,falseotherwise. -
Sets a property in this compound.
This function supports the "dot syntax" for setting properties. If the compound has a child operation called
child, then the properties of the child can be set withsetProperty("child.property", value).Reimplemented from PiiOperation.
-
Returns the value associated with name in socket.
If the "name" property is requested, this function first checks if the socket is exposed in the interface of this operation, and returns the alias name. If the socket is not exposed, it is recursively searched in all of this operations child operations. If it is found, a dotted name (in the stype childop.childop.socketname) will be returned.
If any other property is requsted, only exposed output sockets will be searched. This is because inputs may be connected to many input sockets, and the property values would not be unique. If a match is found in the output sockets, the query will be passed to the parent of its root output.
If socket is not found or there is no property called name associated with it, an invalid property will be returned.
Reimplemented from PiiOperation.
-
virtual void start
()[virtual]Starts all child operations.
The compound immediately changes its state to
Startingand turnsRunningonce all children have turnedRunning. The call has no effect if the compound is notStoppedorPaused.Reimplemented from PiiOperation.
-
Returns the current state of the operation.
Reimplemented from PiiOperation.
-
virtual Q_INVOKABLE void stop
()[virtual]Stops all child operations.
The compound immediately changes its state to
Stoppingand turnsStoppedonce all children have turnedStopped. The call has no effect if the compound is notRunning.Reimplemented from PiiOperation.
-
Q_INVOKABLE void unexposeAll
()Removes all exposed input and output sockets from the public interface.
-
void unexposeInput
Removes an aliased input socket from the public interface.
This will break connections to all sockets aliased with alias.
-
void unexposeInput
Removes socket from the public interface.
If the socket is directly aliased, the alias will be removed. If the socket is exposed through a proxy, the proxy will remain in effect. If the socket is an output, all of its aliases will be removed.
Parameters
- socket
the socket to be removed from the public interface
-
void unexposeOutput
Removes socket from the public interface.
See unexposeInput().
-
void unexposeOutput
Removes an aliased output socket from the public interface.
-
Q_INVOKABLE bool wait
Waits for the compound to change state to state.
It is in general unsafe not to specify a timeout value. In some cases it may happen that the compound never turns into the state you expect. For example, if an error occurs in one of a compound's sub-operations while start-up, the compound turns into
Stoppedstate. Another unexpected situation may arise if a producer operation quickly runs out of data and spontaneously stops while other operations are stillPausingorStarting. In this case the compound may will turn intoRunningstate and immediately toStopping. Waiting forStoppedafter stop() or interrupt() and waiting forPausedafter pause() is safe with well-behaved operations, but a better convention is to always specify a reasonable timeout and inspect the return value.PiiEngine engine; engine.pause(); // Wait for 2 seconds if (!engine.wait(PiiOperation::Paused, 2000)) { engine.interrupt(); // Handle error here }
This function executes the event loop of the active thread in order to deliver the state change signals of the operations and to keep the application responsive. As a result, any of your application events, including timer events, may get processed during a the wait() call. This may result in unexpected behavior especially if you alter the state of the compound in the slots that will be called.
Parameters
- state
the target state
- time
the maximum time to wait (in milliseconds).
ULONG_MAXcauses the method not to time out.
Returns
trueif the state was reached before the call timed out,falseotherwise. -
virtual bool wait
(- unsigned long time = ULONG_MAX
[virtual]Waits for all child operations to terminate their execution.
All children may not have signalled their state change to
Stoppedyet even if this method returnstrue. They have, however, finished execution. It is unsafe to delete the compound immediately. Use deleteLater() or wait until the state has changed.Parameters
- time
the maximum time to wait (in milliseconds).
ULONG_MAXcauses the function not to time out.
Returns
trueif all child operations exited before the call timed out,falseotherwise.Reimplemented from PiiOperation.
-
Called by setState() just before the operation changes to a new state.
The function will be called independent of the cause of the state change (internal or external). Derived classes may implement this function to perform whatever is needed when a state changes. The default implementation does nothing.
-
template<class Action>
void commandChildren
()[inline, protected]Send a command to all child operations.
Use the action structures to specify the action to be taken. This function loops through the list of child operation and applies the action to each.
commandChildren<Execute>();See also
-
Sets the state of the operation.
If the state changes, the stateChanged() signal will be emitted.
-
void childDestroyed
()[slot] -
void childStateChanged
()[slot] -
void handleError
()[slot] -
void removeInput
()[slot] -
void removeOutput
()[slot]
Add a note
Not a single note added yet. Be the first, add yours.