Workspace 6.21.5
Classes | Public Member Functions | Static Public Member Functions | Protected Member Functions | List of all members
IOBase Class Referenceabstract

Base class for all inputs and outputs.

#include <Workspace/DataExecution/InputOutput/iobase.h>

Inheritance diagram for IOBase:
[legend]

Classes

class  QueueChangesWhileUpdatingSentry
 

Public Member Functions

 ~IOBase () override
 
void addConnectorThatRequiresQueuing ()
 
void clearWidgetPropertyValues ()
 
virtual bool connected () const =0
 
virtual void disconnect ()=0
 
bool getAllowedToSerialize () const
 
DataObjectgetDataObject ()
 
const DataObjectgetDataObject () const
 
virtual QString getDataPath () const
 
virtual QString getDataPathUsingId (bool scoped=true) const
 
const QString & getDeprecationMessage () const
 
const QString & getDescription () const
 
const DataFactorygetFactory () const
 
IOBasegetFromPath (const QString &path, Workspace &relativeTo, QStringList &errors) const override
 
QString getIdPath (bool scoped=true) const override
 
const QString & getName () const
 
OperationgetOperation ()
 
const OperationgetOperation () const
 
const QString & getPreferredWidget () const
 
const WorkspacegetRootWorkspace () const override
 
WorkspacegetRootWorkspace () override
 
virtual QString getTagName () 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 WorkspacegetWorkspace () const override
 
WorkspacegetWorkspace () 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
 
- Public Member Functions inherited from Updatable
 ~Updatable () override
 
virtual bool comesFromExternal () const
 
QString getEnclosingScope () const
 
virtual UpdatablegetFromPath (const QString &path, Workspace &relativeTo, QStringList &errors) const =0
 
const QString & getGlobalName () const
 
virtual QString getIdPath (bool scoped=true) const =0
 
virtual WorkspacegetRootWorkspace ()
 
virtual const WorkspacegetRootWorkspace () const
 
QString getScopedGlobalName () const
 
virtual bool getUpToDate () const =0
 
virtual const WorkspacegetWorkspace () const =0
 
virtual WorkspacegetWorkspace ()=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
 
- Public Member Functions inherited from Observable
virtual ~Observable ()
 
void attachObserver (Observer &observer)
 
void destroy ()
 
void detachObserver (Observer &observer)
 
void notifyEvent (const ObservableEvent &event)
 
- Public Member Functions inherited from Serialize
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 IOBasegetIOBaseFromDataPath (const QString &dataPath, Operation &relativeTo, QStringList &errors)
 
- Static Public Member Functions inherited from Updatable
static InputScalarfindInputScalarGlobalName (const QString &scopedGlobalName, Workspace &relativeTo)
 
static IOBasefindIOBaseGlobalName (const QString &scopedGlobalName, Workspace &relativeTo)
 
static OperationfindOperationGlobalName (const QString &scopedGlobalName, Workspace &relativeTo)
 

Protected Member Functions

 IOBase (const QString &name, DataObject &obj)
 
virtual void operationChanged (Operation *oldOp)
 
void setVerifiedName (const QString &name)
 
- Protected Member Functions inherited from Updatable
 Updatable ()
 
 Updatable (const Updatable &up)
 
void notifyUpdated ()
 
Updatableoperator= (const Updatable &up)
 
- Protected Member Functions inherited from Observable
 Observable ()
 
 Observable (const Observable &)
 

Constructor & Destructor Documentation

◆ IOBase()

IOBase ( const QString &  name,
DataObject obj 
)
protected
Parameters
nameThe 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.
objThe 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.

◆ ~IOBase()

~IOBase ( )
override

Member Function Documentation

◆ addConnectorThatRequiresQueuing()

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.

◆ clearWidgetPropertyValues()

void clearWidgetPropertyValues ( )

Clear all property values for widgets attached to this IOBase.

◆ connected()

virtual bool connected ( ) const
pure virtual
Returns
True if anything is connected to the IOBase.

Implemented in InputArray, InputScalar, and Output.

◆ disconnect()

virtual void disconnect ( )
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.

◆ getAllowedToSerialize()

bool getAllowedToSerialize ( ) const
Returns
True if this input/output can be serialized (ie saved and/or loaded).

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.

Note
This is not the same as canSerialize(). The canSerialize() function merely says if serialization is possible, whereas getAllowedToSerialize() says whether serialization is allowed, independent of whether it would actually be possible.
See also
setAllowedToSerialize(), getVisible(), setVisible()

◆ getDataObject() [1/2]

DataObject & getDataObject ( )
Returns
The data object for this input or output. Some input or output types do not use this directly, but rather they use it to create other data objects by cloning it.

◆ getDataObject() [2/2]

const DataObject & getDataObject ( ) const
Returns
The data object for this input or output. Some input or output types do not use this directly, but rather they use it to create other data objects by cloning it.

◆ getDataPath()

QString getDataPath ( ) const
virtual
Returns
The full data path for the input/output, or an empty string if the operation this input/output belongs to is not part of a workspace. An empty string can also be returned if the input/output does not support data manipulation (currently only the case for array inputs).

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:

  • output
  • input
  • subinput <index>

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.

◆ getDataPathUsingId()

QString getDataPathUsingId ( bool  scoped = true) const
virtual
Parameters
scopedIf true then return full scope of the item. If false, only return identifier local to its workflow.
Returns
The data path of the input/output using an operation ID path. The default implementation returns an empty string, which means an invalid data path (ie the input/output cannot support data manipulation).

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.

See also
getDataPath()

Reimplemented in InputArray, InputScalar, and Output.

◆ getDeprecationMessage()

const QString & getDeprecationMessage ( ) const
Returns
QString to display to the user if the IO is deprecated and in use.

◆ getDescription()

const QString & getDescription ( ) const
Returns
A description for human users of what this IOBase is (for tooltips etc)

◆ getFactory()

const DataFactory & getFactory ( ) const
Returns
The data factory which specifies what type of data object can be connected to this input or output.

◆ getFromPath()

IOBase * getFromPath ( const QString &  path,
Workspace relativeTo,
QStringList errors 
) const
overridevirtual
Parameters
pathThe global path for which an updatable object should be found.
relativeToThe workspace where the search for path should begin. If path is relative, then it will be treated as relative to relativeTo.
errorsUpon exit, this will hold any errors encountered when trying to find an updatable object that matches path.
Returns
A pointer to the updatable object that matches path, or a null pointer if no such object could be found.

Implements Updatable.

◆ getIdPath()

QString getIdPath ( bool  scoped = true) const
overridevirtual
Parameters
scopedIf true then return full scope of the item. If false, only return identifier local to its workflow.

Implements Updatable.

◆ getIOBaseFromDataPath()

IOBase * getIOBaseFromDataPath ( const QString &  dataPath,
Operation relativeTo,
QStringList errors 
)
static

◆ getName()

const QString & getName ( ) const
Returns
The name of this input or output.
See also
setName()

◆ getOperation() [1/2]

Operation * getOperation ( )
Returns
The operation this input or output is currently associated with. If it has not been assigned to an operation, a null pointer will be returned instead.

◆ getOperation() [2/2]

const Operation * getOperation ( ) const
Returns
The operation this input or output is currently associated with. If it has not been assigned to an operation, a null pointer will be returned instead.

◆ getPreferredWidget()

const QString & getPreferredWidget ( ) const

◆ getRootWorkspace() [1/2]

const Workspace * getRootWorkspace ( ) 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.

◆ getRootWorkspace() [2/2]

Workspace * getRootWorkspace ( )
overridevirtual
Returns
The root workspace this updatable object resides in or a null pointer if it is not part of a workspace.

Reimplemented from Updatable.

◆ getTagName()

virtual QString getTagName ( ) const
pure virtual
Returns
The tag name to use for this object when it is serialized.

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:

  • Must be all lowercase
  • Must start with a letter
  • Must only consist of letters, numbers and underscores

Implemented in Input, and Output.

◆ getUpToDate()

bool getUpToDate ( ) const
overridepure virtual
Returns
True if this input or output is up to date. For array inputs, it must return true only if all connected inputs are up to date.

Implements Updatable.

Implemented in InputArray, InputScalar, and Output.

◆ getVisible()

bool getVisible ( ) const
Returns
True if this input/output should be made visible to users in any graphical interface component.

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.

◆ getWidgetPropertyValueMap()

const QMap< QString, QVariant > & getWidgetPropertyValueMap ( const QString &  widgetClassName) const
Returns
a QMap object that maps property names to values.
Parameters
widgetClassNameUse QObject::metaObject and QMetaObject::className to retrieve the class name of your widget.

◆ getWidgetValidator() [1/2]

QValidator * getWidgetValidator ( )

◆ getWidgetValidator() [2/2]

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.

Returns
The validator currently assigned to this IOBase. If attached widgets are capable of using validators, they will use this to validate user input.

◆ getWorkspace() [1/2]

const Workspace * getWorkspace ( ) const
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.

◆ getWorkspace() [2/2]

Workspace * getWorkspace ( )
overridevirtual
Returns
The workspace this Updatable object belongs to, or a null pointer if it is not currently part of a workspace.

Implements Updatable.

◆ isDeprecated()

bool isDeprecated ( ) const
Returns
true if the IOBase is deprecated, false otherwise. Deprecated inputs and outputs are earmarked for removal in a later release, and should not be used.

◆ markAsDeprecated()

void markAsDeprecated ( bool  b,
const QString &  message = "" 
)
Parameters
bIf true, marks the IOBase as deprecated. Deprecated inputs and outputs are earmarked for removal in a later release, and should not be used.
messageA message to display to the user if the IO is in use.

◆ markUpToDateWhereSafe()

void markUpToDateWhereSafe ( )
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.

◆ operationChanged()

virtual void operationChanged ( Operation oldOp)
inlineprotectedvirtual
Parameters
oldOpThe 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.

◆ removeConnectorThatRequiresQueuing()

void removeConnectorThatRequiresQueuing ( )

Every call to addConnectorThatRequiresQueuing() should be matched with a call to this function.

See also
addConnectorThatRequiresQueuing()

◆ setAllowedToSerialize()

void setAllowedToSerialize ( bool  b)
Parameters
bIf true, the input/output will be allowed to serialize itself.
See also
getAllowedToSerialize()

◆ setDataObject()

void setDataObject ( DataObject obj)
Parameters
objThe 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.

Warning
Unless you are working on the core Workspace code, you would be well advised not to use this function.

◆ setDescription()

void setDescription ( const QString &  description)
Parameters
descriptionA description for human users of what this IOBase is (for tooltips etc)

◆ setName()

void setName ( const QString &  name)
Parameters
nameThe 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.

Postcondition
The name upon exit could potentially be different to name.
See also
getName()

◆ setOperation()

void setOperation ( Operation op)
Parameters
opThe 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.

◆ setPreferredWidget()

void setPreferredWidget ( const QString &  name)

◆ setUpToDate()

void setUpToDate ( bool  b)
overridepure virtual
Parameters
bBoolean value specifying the new up-to-date status of the object.
Precondition
If this object belongs to a workspace and that workspace's execution thread is running, setUpToDate() must only be called from that execution thread. If the execution thread is not running or there is no execution thread (or perhaps not even a workspace), then setUpToDate() may be called from any thread with appropriate thread protection being the responsibility of the caller.

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.

See also
update(), getUpToDate()

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.

◆ setVerifiedName()

void setVerifiedName ( const QString &  name)
protected

◆ setVisible()

void setVisible ( bool  b)
Parameters
bFlag to control the visibility of this input.
See also
getVisible

◆ setWidgetPropertyValue()

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.

Parameters
widgetClassNameUse QObject::metaObject and QMetaObject::className to retrieve the class name of your widget.
propertyNameName of the widget property.
valueValue that will be set for the specified property.

◆ setWidgetValidator()

void setWidgetValidator ( QValidator *  validator)
Parameters
validatorThe 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.

◆ shouldQueueChangesWhileUpdating()

bool shouldQueueChangesWhileUpdating ( ) const
Returns
True if any connectors attached to this IOBase require data changes to queued while it is being updated.
See also
addConnectorThatRequiresQueuing()

◆ update()

bool update ( Updater updater = nullptr)
overridepure virtual
Parameters
updaterThe 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.

Returns
True if the update was successful.
Postcondition
Exactly what "up to date" means is up to the subclass, but if update() returns true, then getUpToDate() must also return true immediately after update() returns.
See also
setUpToDate(), getUpToDate(), isWaitingForAsynchronousUpdate()

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.

See also
notifyUpdated()

Implements Updatable.

Implemented in InputArray, InputScalar, and Output.