# Updaters and worklets

**URL:** https://discourse.kitware.com/t/updaters-and-worklets/1151
**Category:** Design
**Created:** [November 3, 2023, 4:47pm UTC](https://discourse.kitware.com/t/updaters-and-worklets/1151 "2023-11-03T16:47:02Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![dcthomp](https://discourse.kitware.com/user_avatar/discourse.kitware.com/dcthomp/32/10_2.png) [@dcthomp](https://discourse.kitware.com/u/dcthomp)
#### Post date: [November 3, 2023, 4:47pm UTC](https://discourse.kitware.com/t/updaters-and-worklets/1151/1 "2023-11-03T16:47:02Z")

</div>

Hi @Bob_Obara, as I am reviewing the [worklet MR](https://gitlab.kitware.com/cmb/smtk/-/merge_requests/2952), I am becoming more sure that `smtk::resource::Component` should **not** have a schema and version. If components are going to mirror BRep-like model entities, that would be a lot of overhead; the resource’s schema should cover its components. What makes `smtk::project::Project` different is that we are proposing users be allowed to exchange component “definitions” (worklets in the task gallery).

However, if we want to support other components using the same mechanism we do for worklets, we need a way to add support independent of inheritance (we already use inheritance for other purposes).

## Alternative 1: Schema via property

What if we used the property mechanism to annotate components that need a schema+version number? Instead of having `smtk::task::Worklet` provide ivars for a schema and version number, what if we provided

```cpp
namespace smtk { namespace resource {
struct Schema
{
public:
  smtk::string::Token m_name;
  int m_version;
  bool operator <(const Schema& other);
  bool operator <=(const Schema& other);
};
}} // namespaces

```

and added it to the [default property types](https://gitlab.kitware.com/cmb/smtk/-/blob/master/smtk/resource/Properties.h#L529-545) that resources provide? This allows any subset of components to be marked with a schema.

## Alternative 2: Schema as a component

Another alternative would be to create a new component type:

```cpp
namespace smtk { namespace resource {
class Schema : public smtk::resource::Component
{
public:
  Schema();
  Schema(smtk::string::Token name, int version);

  std::string name() const override;
  smtk::string::Token schemaName() const;

  int schemaVersion() const;

protected:
  smtk::string::Token m_name;
  int m_version;
};
}} // namespaces

```

and use links to connect instances of the schema to components. We could then add API to either resources or even persistent objects to provide a `Schema` (or null):

```cpp
namespace smtk { namespace resource {
class PersistentObject
{
public:
  /// Return an indicator of the data format and version of this object.
  /// This may return null.
  virtual Schema* schema() { return nullptr; }
};
}} // namespaces

```

deprecate the `smtk::attribute::Resource::templateType()` and `templateVersion()` API.

---

<div class="post-metadata">

### Author: ![dcthomp](https://discourse.kitware.com/user_avatar/discourse.kitware.com/dcthomp/32/10_2.png) [@dcthomp](https://discourse.kitware.com/u/dcthomp)
#### Post date: [November 3, 2023, 5:10pm UTC](https://discourse.kitware.com/t/updaters-and-worklets/1151/2 "2023-11-03T17:10:37Z")

</div>

I am leaning toward alternative 2 (`Schema` being a component that other objects may reference).

## Implications for Worklet

The Worklet class could override its inherited `PersistentObject::schema()` method to find the schema component in their parent project that has the name and type obtained from their configuration data.

Note that this means ingesting worklets into the gallery would require new Schema components to be created (or destroyed if a worklet is deleted or updated to a newer version and nothing else refers to the older schema) by the operation that imports them. Other than that, the changes seem pretty minimal and give us a uniform way to apply updaters to both resources and (for resources that wish to allow it) components.
