Announcing the Release of SMTK 24.01
It’s been quite a while since the last release of SMTK and we wanted to start off 2024 with a feature packed release which includes the following improvements:
Important SMTK Core Changes
The changes in this section have a widespread impact on SMTK.
Type Hierarchy Reflection
SMTK has long provided introspection functionality for classes such as type-aliases and a typeName() method; this functionality has been key in allowing workflow designers to specify the type of Resources and Resource Components in association rules and in Reference Items. For example, an operation may need to take in a reference to a component of type smtk::myComponent; however, this functionality was somewhat limited when it came to class hierarchy. In the above example, you could not give the operation a reference to a component derived from smtk::myComponent, even though conceptually this should be possible.
This functionality has now been extended to provide (when a Superclass type-alias is present) the entire inheritance hierarchy; thereby, making the above example possible. It is implemented with a set of string tokens so that determining whether an object inherits a type is fast.
Changing Default Observer Priority
Previously, the default observer priority was the smallest negative value of an int. This meant that there was no way to ensure that some SMTK core observers would be called last. For example, core operation observers that release resources from managers need to be called last.
In order to address this, the default priority is now set to 0; thereby, allowing observers to run both before and after the default priority observers are executed.
Operations and Customize Resource Locking
Previously, an operation would lock resources based solely on its parameters. In this release, the base Operation class now provides a virtual method to allow subclasses to customize the default set of resources to be locked and their lock levels (read vs. write). This allows operations that may need to lock components related (say by smtk::resource::Links) to external resources to include those external resources in the operation’s lock set.
API Breaking Changes
We have been forced to remove smtk::task::Adaptor::reconfigureTask() which has been replaced by smtk::task::Adaptor::updateDownstreamTask(State upstreamPrev, State upstreamNext) and is a pure virtual method that must be overridden. Normally we would have deprecated the method but the issue is that derived classes may have overridden reconfigureTask and it would have been difficult to indicate these methods needed to be replaced. By removing this virtual method, the compiler will now see these overridden methods as errors.
Expanding Units Support in Attribute Resource
In the past, you could assign units to information modeled in SMTK’s attribute resource which would indicate to the user, via the generated UI, the units associated with the value they were entering. In SMTK 24.01, unit support is greatly expanded. Now the user can assign units to any value they are entering as long as the units conform to the item’s declared base unit. The value is then converted internally to this base unit the workflow designer specified in the corresponding item’s definition. SMTK will store both the original value with units specified by the user or program along with the converted value.
After the user has entered the numerical value, if they enter no units then the units specified in the corresponding definition are added. If the user begins to enter a unit, the UI will provide auto-completion based on the definition’s units. In the above example, the units associated with the item length is m (meters). The user has entered 0.0 followed by ‘f’. SMTK’s units system then provides all of the units based on length (since meters is a length measurement) and provides the user with the appropriate completions. If the user hovers over the value they have entered, the converted value is displayed as a tooltip.
New units can be easily added to an attribute resource’s Unit System.
New Template Support in Attribute XML Files
Templates are a new feature for SMTK’s XML-based attribute file format (.sbt, .sbi extensions) version 7 and later. Templates are an extension to the existing ItemBlock concept. The main difference between an ItemBlock and a Template is that a Template’s contents can be parameterized. When a Template is instantiated, these parameters can be assigned different values and will thereby change the information being copied. A Template’s parameter can also be given a default value.
Note: All parameters that do not have a default value must be given values when the Template is instanced.
Here is an example:
Here the StringItemDefinition s1 will have a default value of “cat” while s2 will have the default value of dog.
See TemplateTest.sbt and unitTemplates.cxx for examples. You can also read the discourse on the topic here.
Project and Task Related Changes
Project Filtering Changes
Now the SMTK project queryOperation() method supports component type-name and property queries. This can be used to fetch tasks and worklets by type. Note that the inheritance hierarchy of components is also available to the query system, so you can, for example, expect a query on smtk::task::Task to return objects of type smtk::task::FillOutAttributes.
Project Manager Changes
Management is done by Operation Observers
The project manager no longer automatically manages projects as they are created. Instead, the project manager observes operations which create projects and manage any new projects upon completion. This matches the pattern set by the resource manager and avoids observers being fired during operations when the project may not be in a valid state. Adding a project to a project manager will fail If that project is already managed.
In terms of project removal, the project manager’s observers were not being informed when a project was removed from the manager; now they are.
Changes In Project I/O Operations
Previously, reading in the resources of a project used the read() function registered with the resource manager; however, resources loaded in this way may be processed differently than creating a reader via the operation manager. This happens because the operation manager typically has application-specific data in its smtk::common::Managers object and it provides this to operations it creates. In the case of attribute resources loaded by the resource manager, evaluators were not properly set while using the ReadResource Operation approach did not have this issue.
These changes allow the ResourceContainer deserialization function to internally call the ReadResource operation through the use of an operation::Helper which provides an operation::Operation::Key.
Task and Task Adaptors Are Now Project Components
smtk::task::Task and smtk::task::Adaptor classes now inherit smtk::resource::Component. Instances of these classes are still owned by the task manager, but it is now assumed that the task manager is owned by an smtk::project::Project.
This has far-reaching consequences:
- Tasks and Adaptors have unique Ids.
- Tasks and Adaptors may have properties and links (such as associations to attributes).
- Tasks and Adaptors must not be modified outside of operations (for thread-safety).
- The parent resource must provide operations to find, insert, and remove tasks and Adaptors.
The Project class now provides these methods.
Note that this change has resulted in all task Instance observers, adaptor Instance observers, and workflow related event observers to be changed – please see the 24.01 release notes for more details.
New Task and Adaptor for Submitting Operations
There is a new smtk::task::SubmitOperation class for situations where users must prepare an operation to be run (or should run an operation iteratively until satisfied).
Consequently, there is also a new smtk::task::adaptor::ConfigureOperation class for situations where parts of an SMTK operation managed by a smtk::task::SubmitOperation are configured by an upstream smtk::task::FillOutAttributes task.
Introducing Worklets and Galleries to the Task Manager
There are times when a user will need to interactively extend a task workflow by adding a task or a group of related tasks. To provide this functionality, SMTK now provides the concept of a smtk::task::Worklet. A worklet is defined as an object representing a template for a set of tasks that can be instantiated to reuse some portion of a workflow. As in the case of tasks, a worklet is a subclass of smtk::resource::Component.
To manage the worklets, a gallery class has been added called smtk::task::Gallery and is held by a project’s smtk::task::Manager.
Updated Task UI Panel
Here is the latest version of the task panel under 24.01 (renamed to pqSMTKDiagramPanel).
Here you can see support for the new Task Worklet feature. To instantiate a worklet, all a user needs to do is to drag the worklet from the gallery and drop it into the workflow.
We have also added new interactive modes to the panel as shown by the list of icons next to the label called Diagram (note that this label can be modified as part of the panel’s configuration). The current set of interactions (in order) are:
- Panning the viewport
- Selecting task nodes
- Connecting task nodes via arcs
- Removing arcs between task nodes
Run-time Graph-Resource Arcs
Defining new arc types
New in this release is the ability for users to define graph-resource arc types at run time. These arcs may be directed or undirected and make use of the new type-reflection facilities to constrain the types of endpoint nodes. The graph-resource’s JSON serialization code will now serialize and deserialize these arc types along with the arcs themselves.
Operations and Operation Groups
Besides the new CreateArcType operation provided, CreateArc and DeleteArc operations are provided by the smtk::graph::Registrar. These operations can create arcs of any type. Furthermore, they interact with two new groups: the ArcCreator group and the ArcDeleter group. These groups provide user interfaces with a way to find operations that can create (respectively delete) arcs between pairs of components in any resource. This makes it possible for the new diagram panel (described below) to run custom operations to create/delete run-time arcs in addition to the operations provided by SMTK.
The CreateArcType operation, in addition to adding a new run-time arc type to a resource, registers the operations above with the ArcCreator and ArcDeleter groups. Similarly, the JSON deserialization code will do the same when it reads a resource file containing custom arcs.
Other UI Enhancements
Ternary Visibility
Previously, visibility was controlled in UI elements like the Resource Panel by a single badge. It allowed you to set the item’s geometric visibility as well as those of the item’s children (if there were any). The issue was that the item’s visibility was not affected by changing the visibility of its children. If you cleared the visibility badge of an item and its children and then made one of its children visible, the item’s badge still indicated it was not visible. The reverse was also true, setting an item’s visibility to be true and then making one of its children invisible, resulted in the item indicating it was visible.
In this release we have implemented two new visibility badges:
- The GeometricVisibilityBadge controls an item’s geometric visibility and is represented by a single square icon. This badge is binary (visible or invisible).
- The HierarchicalVisibilityBadge controls the visibility of an item’s children and is represented by an icon consisting of 2 squares (the bottom of which indicates the item’s children’s visibility state which can be all visible, all invisible, or mixed.
Diagram Views
SMTK provides a new type of Qt-based view called the diagram view. A diagram view may contain multiple diagram generators, each of which may be configured independently. Two generators are provided: a task-editor and a resource diagram.
The task editor is intended to walk users through a workflow included in a project document; it renders tasks as rounded rectangles attached by arcs indicating dependencies among tasks and the flow of configuration information between tasks. Users may make some tasks active and mark completable tasks as finalized in order to proceed forward in the workflow. The previous image showing the latest version of the Task Workflow Panel is the result of using the task editor.
The resource diagram draws a schematic of all the persistent objects being managed by the application. The objects are laid out in a circle and the class-hierarchy of object types is used to organize the order in which they appear around the circumference as well as specify the shape of each arc connecting any pair of nodes. The figure below shows the diagram panel with a graph-based resource loaded.
Each diagram view may be configured with different interaction modes (the buttons in the panel’s title bar to the right of the word “Diagram”). These are mutually exclusive and define how users may manipulate the nodes and arcs in the diagram. The view also provides a side-bar (at the top-left). The side-bar (known as a “drawer” on macos) may be toggled on/off and contains a legend showing arc types as well as any widgets that generators choose to add. The Task UI figure above shows the use of the drawer mechanism for adding “Worklets” support to a task-editor generator.
Plus Many More Features!
For a complete list of features please see the full release notes for 24.01 which can be found here.