![]() |
Workspace 7.0.2
|
Base class for all inputs and outputs.
#include <Workspace/DataExecution/InputOutput/iobase.h>
Classes | |
class | QueueChangesWhileUpdatingSentry |
Public Types | |
enum class | IOBaseType { InputScalarType , InputArrayType , OutputType } |
Public Member Functions | |
~IOBase () override | |
void | addConnectorThatRequiresQueuing () |
void | clearWidgetPropertyValues () |
virtual bool | connected () const =0 |
virtual void | disconnect ()=0 |
bool | getAllowedToSerialize () const |
DataObject & | getDataObject () |
const DataObject & | getDataObject () const |
virtual QString | getDataPath () const |
virtual QString | getDataPathUsingId (bool scoped=true) const |
const QString & | getDeprecationMessage () const |
const QString & | getDescription () const |
const DataFactory & | getFactory () const |
IOBase * | getFromPath (const QString &path, Workspace &relativeTo, QStringList &errors) const override |
QString | getIdPath (bool scoped=true) const override |
const QString & | getName () const |
Operation * | getOperation () |
const Operation * | getOperation () const |
const QString & | getPreferredWidget () const |
const Workspace * | getRootWorkspace () const override |
Workspace * | getRootWorkspace () override |
virtual QString | getTagName () const =0 |
virtual IOBaseType | getType () const =0 |
bool | getUpToDate () const override=0 |
bool | getVisible () const |
const QMap< QString, QVariant > & | getWidgetPropertyValueMap (const QString &widgetClassName) const |
QValidator * | getWidgetValidator () |
const QValidator * | getWidgetValidator () const |
const Workspace * | getWorkspace () const override |
Workspace * | getWorkspace () override |
bool | isDeprecated () const |
void | markAsDeprecated (bool b, const QString &message="") |
virtual void | markUpToDateWhereSafe () |
void | removeConnectorThatRequiresQueuing () |
void | setAllowedToSerialize (bool b) |
void | setDataObject (DataObject &obj) |
void | setDescription (const QString &description) |
void | setName (const QString &name) |
void | setOperation (Operation *op) |
void | setPreferredWidget (const QString &name) |
void | setUpToDate (bool b) override=0 |
void | setVisible (bool b) |
void | setWidgetPropertyValue (const QString &widgetClassName, const QString &propertyName, const QVariant &value) |
void | setWidgetValidator (QValidator *validator) |
bool | shouldQueueChangesWhileUpdating () const |
bool | update (Updater *updater=nullptr) override=0 |
![]() | |
~Updatable () override | |
virtual bool | comesFromExternal () const |
QString | getEnclosingScope () const |
virtual Updatable * | getFromPath (const QString &path, Workspace &relativeTo, QStringList &errors) const =0 |
const QString & | getGlobalName () const |
virtual QString | getIdPath (bool scoped=true) const =0 |
virtual Workspace * | getRootWorkspace () |
virtual const Workspace * | getRootWorkspace () const |
QString | getScopedGlobalName () const |
virtual bool | getUpToDate () const =0 |
virtual const Workspace * | getWorkspace () const =0 |
virtual Workspace * | getWorkspace ()=0 |
virtual void | idPathChanged () |
virtual bool | isConnectedToAsynchronous () const =0 |
virtual bool | isWaitingForAsynchronousUpdate () const =0 |
void | setGlobalName (const QString &name) |
virtual void | setUpToDate (bool b)=0 |
virtual bool | update (Updater *updater=nullptr)=0 |
![]() | |
virtual | ~Observable () |
void | attachObserver (Observer &observer) |
void | destroy () |
void | detachObserver (Observer &observer) |
void | notifyEvent (const ObservableEvent &event) |
![]() | |
virtual | ~Serialize ()=default |
virtual bool | canSerialize () const =0 |
virtual bool | load (const SerializedItem &item)=0 |
virtual bool | save (SerializedItem &item) const =0 |
Static Public Member Functions | |
static IOBase * | getIOBaseFromDataPath (const QString &dataPath, Operation &relativeTo, QStringList &errors) |
![]() | |
static InputScalar * | findInputScalarGlobalName (const QString &scopedGlobalName, Workspace &relativeTo) |
static IOBase * | findIOBaseGlobalName (const QString &scopedGlobalName, Workspace &relativeTo) |
static Operation * | findOperationGlobalName (const QString &scopedGlobalName, Workspace &relativeTo) |
Protected Member Functions | |
IOBase (const QString &name, DataObject &obj) | |
virtual void | operationChanged (Operation *oldOp) |
void | setVerifiedName (const QString &name) |
![]() | |
Updatable () | |
Updatable (const Updatable &up) | |
void | notifyUpdated () |
Updatable & | operator= (const Updatable &up) |
![]() | |
Observable () | |
Observable (const Observable &) | |
|
strong |
|
protected |
name | The name to give to the input/output. When the input/output is added to an operation, this name might get changed to ensure the name is unique among its siblings in the operation. |
obj | The data object the input/output should be associated with. |
The constructor makes the object visible and allowed to be serialized. Note that some subclass constructors override these defaults.
|
override |
void addConnectorThatRequiresQueuing | ( | ) |
If a WidgetConnector is attached to this IOBase it may wish for any data changes to the workspace hierarchy to be queued while this object is being brought up to date. Doing this guarantees that this IOBase will be updated without any of its dependencies being dirtied while the update is taking place.
This is not the case usually as PauseUpdateEvents are fired throughout the process of updating the tree of dependencies for this IOBase. During any of those events a Widget has the ability to change data in the network which may be in this tree of dependencies.
During the lifetime of this IOBase multiple widgets may be attached or detached so these calls are counted. Therefore every call addConnectorThatRequiresQueuing() should be matched with a call removeConnectorThatRequiresQueuing() when the attached object is disconnected.
void clearWidgetPropertyValues | ( | ) |
Clear all property values for widgets attached to this IOBase.
|
pure virtual |
Implemented in InputArray, InputScalar, and Output.
|
pure virtual |
If any connection exists to this input or output, this function is responsible for destroying it. For some subclasses (notably InputArray), this may mean forwarding the call to other objects eg the InputScalar elements of an InputArray).
Implemented in InputArray, InputScalar, and Output.
bool getAllowedToSerialize | ( | ) | const |
An input/output that can be serialized will be automatically loaded and saved along with the operation it belongs to (as long as the underlying data type for the input/output also supports serialization). The purpose of this flag is to allow operation implementors to decide whether it makes sense for an input/output to be serialized. In most cases, this function will return true for disconnected inputs and false for outputs or connected inputs. This provides the greatest robustness for workspace execution updates.
DataObject & getDataObject | ( | ) |
const DataObject & getDataObject | ( | ) | const |
|
virtual |
The data path for an input or output is a string that identifies it in its workspace hierarchy. If the input/output has a global name, that global name is returned as part of a string in the following colon-separated format:
globalName:iobaseGlobalName
The iobaseGlobalName
part will be the string returned from getGlobalName(). If the input/output has no global name, the string returned from getDataPath() is based on the operation id path of the owning operation plus some additional information to identify the input/output within that operation. In this case, the string has the following colon-separated format:
wsDataPath:opIdPath:iobaseID:iobaseName
The globalName
and wsDataPath
components are fixed strings that allow the type of data path to be determined. They should always be included exactly as shown (including upper/lowercase).
The opIdPath
component is usually obtained from a call to getIdPathFromOperation(). It identifies a specific operation within a workspace (possibly nested below other workspaces). It is always taken as being relative to a particular workspace, and this function must use the root workspace obtained from getRootWorkspace(). This implies that getDataPath() should only ever be called when the operation the input/output belongs to resides in a workspace.
The iobaseID
component must be one of the following:
where <index> is an integer identifying a particular element of an input array.
The iobaseName
must always be the result returned from getName().
Authors of subclasses should note that if the global name is empty, getDataPath() calls getDataPathUsingId() to return the data path in operation ID form. Since that function can return an empty string to indicate that no data path is possible, clients should also be aware that getDataPath() can also return an empty string for the same reason.
|
virtual |
scoped | If true then return full scope of the item. If false, only return identifier local to its workflow. |
Client code would not normally call this function, but rather would call getDataPath() instead because that function prefers to return the global name form of data path. A global name data path is more flexible than an operation ID data path, but it also has potential non-uniqueness issues if a global name is used more than once. A data path based on an operation ID path, on the other hand, is always unique, but it is broken by operations being moved to a different workspace or by them (or any parent workspace) being renumbered.
Reimplemented in InputArray, InputScalar, and Output.
const QString & getDeprecationMessage | ( | ) | const |
const QString & getDescription | ( | ) | const |
const DataFactory & getFactory | ( | ) | const |
|
overridevirtual |
path | The global path for which an updatable object should be found. |
relativeTo | The workspace where the search for path should begin. If path is relative, then it will be treated as relative to relativeTo. |
errors | Upon exit, this will hold any errors encountered when trying to find an updatable object that matches path. |
Implements Updatable.
|
overridevirtual |
scoped | If true then return full scope of the item. If false, only return identifier local to its workflow. |
Implements Updatable.
|
static |
const QString & getName | ( | ) | const |
Operation * getOperation | ( | ) |
const Operation * getOperation | ( | ) | const |
const QString & getPreferredWidget | ( | ) | const |
|
overridevirtual |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Reimplemented from Updatable.
|
overridevirtual |
Reimplemented from Updatable.
|
pure virtual |
The main usage of tag names is for XML tags, so essentially anything which is illegal for an XML tag name is also illegal here. There are slightly more restrictions on tag names as used here though. Subclasses must implement this function to return a non-empty string which obeys the following three rules:
|
pure virtual |
Implemented in InputArray, InputScalar, and Output.
|
overridepure virtual |
Implements Updatable.
Implemented in InputArray, InputScalar, and Output.
bool getVisible | ( | ) | const |
An input/output that is not visible should not appear in any user interface. It is up to the interface implementation to ensure this and it is expected that this visibility flag be honoured.
const QMap< QString, QVariant > & getWidgetPropertyValueMap | ( | const QString & | widgetClassName | ) | const |
widgetClassName | Use QObject::metaObject and QMetaObject::className to retrieve the class name of your widget. |
QValidator * getWidgetValidator | ( | ) |
const QValidator * getWidgetValidator | ( | ) | const |
If a widget used to visualise an IOBase can make use of validators, it's possible to assign a custom validator to streamline the user experience without having to create a new custom widget specifically for this data type.
Note that it's not possible to know in advance exactly which widget may be attached to a particular IOBase, so assigning a validator may have no effect in some cases.
|
overridevirtual |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Implements Updatable.
|
overridevirtual |
bool isDeprecated | ( | ) | const |
void markAsDeprecated | ( | bool | b, |
const QString & | message = "" |
||
) |
b | If true, marks the IOBase as deprecated. Deprecated inputs and outputs are earmarked for removal in a later release, and should not be used. |
message | A message to display to the user if the IO is in use. |
|
virtual |
This function can be called after client code modifies the data of this input/output. It's purpose is to try to mark the input/output as up to date if it can be determined that it is safe to do so. This allows the input/output to potentially be brought up to date sooner than would otherwise occur, such as having to wait until an execution thread is started. One of the cases where this proves useful is when loading in data while a workspace is not executing and wanting widgets attached to the inputs/outputs to immediately show the modified values. Without this feature, the values would still be changed but the widgets would not reflect the change until after the execution thread is started and gets around to bringing the inputs and outputs up to date.
The default implementation of this function is to do nothing. Subclasses should only mark themselves as up to date if they do not depend on anything, such as an Operation or a connection with the input as its destination. They must also handle the execution thread correctly by ensuring that the up to date state is only modified directly if no execution thread is running.
Reimplemented in InputScalar.
|
inlineprotectedvirtual |
oldOp | The previous operation assigned to this input/output. |
This function is called by setOperation() if the operation being set is different to the one that was previously assigned. Subclasses can reimplement operationChanged() to do any further processing that might be necessary, such as raising event notifications. The new operation is available by calling getOperation(). The default implementation does nothing.
Reimplemented in InputArray.
void removeConnectorThatRequiresQueuing | ( | ) |
Every call to addConnectorThatRequiresQueuing() should be matched with a call to this function.
void setAllowedToSerialize | ( | bool | b | ) |
b | If true, the input/output will be allowed to serialize itself. |
void setDataObject | ( | DataObject & | obj | ) |
obj | The data object this input or output should use. |
The data object previously held by this IOBase object is not deleted. All this function does is make the IOBase object use obj instead of the data object it was previously using. The owner of the previous data object still needs to manage that object's lifetime.
If the new data object is different from the old one, then an IOBaseDataObjectChangedEvent notification is raised. This allows interested clients to respond after the data object has been changed to the new one but before the old one is potentially destroyed. A typical example of such clients would be a widget connected to the input/output, since it wants the input/output to already be in the new state when it tries to potentially recreate itself if the data types of the old and new object are not the same.
Use this function with care. Once an input/output has been created, most will never re-assign their data object. The main exceptions to this are the inputs/outputs of a polymorphic operation, since those inputs/outputs are typically tied to the data type the operation is associated with. A Workspace object is another common example.
Also note that whenever the data type of an input/output changes, any connection to it will typically need to be rebuilt in case the connection is no longer a valid one (ie the source cannot be assigned to the destination). Thus, the Connection class always rebuilds itself any time the data type of its source or destination changes.
void setDescription | ( | const QString & | description | ) |
description | A description for human users of what this IOBase is (for tooltips etc) |
void setName | ( | const QString & | name | ) |
name | The new name for the input/output. |
This function calls setUnverifiedName() to allow the subclass to ensure that the name being set is valid. Since an input/output normally belongs to an operation, the new name must be unique among the input/output's siblings. The subclass is responsible for verifying that the name is indeed unique, or else coming up with an alternative unique name. In either case, once a name has been verified as unique, the subclass must call setVerifiedName() to effect the name change. A IOBaseRenamedEvent notification is then raised before the function returns.
void setOperation | ( | Operation * | op | ) |
op | The operation this input or output is to be associated with. |
Assign this input or output to the specified operation, op. This function is used internally by the Operation class to associate itself with the object when it is added to or removed from the operation. Clients should not generally call this function directly.
void setPreferredWidget | ( | const QString & | name | ) |
|
overridepure virtual |
b | Boolean value specifying the new up-to-date status of the object. |
If b is false, the call must also try to propagate forward the not up-to-date status through the workspace. The forward propagation must continue until it reaches something already not up to date. Note that for container-type objects (eg array inputs), the up-to-date status is controlled by all items in the container, so calling setUpToDate() doesn't actually change the status for a container as a whole. In that case, all it does is propagate forward the status as necessary.
Note that when is true, some subclasses may choose to raise some kind of event notification to let clients know that they have been brought up to date. Since this will have an impact on performance even if nothing is observing the event, subclasses should avoid making such notifications if it is not necessary.
Inputs and outputs do generate event notifications when setUpToDate() is called with a true parameter. In such cases, subclasses will normally call notifyUpdated() in their implementation of setUpToDate().
Implements Updatable.
Implemented in InputArray, InputScalar, and Output.
|
protected |
void setVisible | ( | bool | b | ) |
b | Flag to control the visibility of this input. |
void setWidgetPropertyValue | ( | const QString & | widgetClassName, |
const QString & | propertyName, | ||
const QVariant & | value | ||
) |
Use this function to specify property values for widgets attached to this IOBase. These properties will only be set on widgets that a instantiated within the Workspace editor.
widgetClassName | Use QObject::metaObject and QMetaObject::className to retrieve the class name of your widget. |
propertyName | Name of the widget property. |
value | Value that will be set for the specified property. |
void setWidgetValidator | ( | QValidator * | validator | ) |
validator | The validator to use to validate this IOBase's data if a widget is attached to it and that widget accepts validators. The iobase will take ownership of this validator on assignment and is responsible for its cleanup. |
If a widget used to visualise an IOBase can make use of validators, it's possible to assign a custom validator to streamline the user experience without having to create a new custom widget specifically for this data type.
Note that it's not possible to know in advance exactly which widget may be attached to a particular IOBase, so assigning a validator may have no effect in some cases.
bool shouldQueueChangesWhileUpdating | ( | ) | const |
|
overridepure virtual |
updater | The execution thread that is calling the function. When the object is being updated from within a workspace, this parameter will normally hold the execution thread that is calling this function. If the object is not part of a workspace or is being updated from client code directly in some other way, this parameter should be a null pointer to indicate that execution is not under the control of an Updater object. This is crucial for robust handling of things like logging messages. |
Calling this function attempts to bring the object up to date. For objects connected in a workspace, this must first bring all upstream dependencies up to date as required. Some updatables can update themselves asynchronously. In such instances update() will return false if an updatable is still being updated (asynchronously). In order to determine if an update() returned false because of a genuine failure or because the update is asynchronous (and still in progress) the isWaitingForAsynchronousUpdate() method should be queried to help determine the cause of the update failure.
Calling this function ensures that the input or output holds a valid, up to date data object. If this is an input with a connection, that connection will be updated as required. If this is an input with no connection and the input is not an array, a valid data object must still be created which can be assigned to or read from. For outputs, this will essentially just forward the request to the operation it is associated with.
Implements Updatable.
Implemented in InputArray, InputScalar, and Output.