As part of making simulation projects more customizable, I would like to make some changes to SMTK so that smtk::project::Project can be a subclass of our PersistentObject class. The motivation is so that I can assign it to a smtk::attribute::ReferenceItem as part of an export-operator specification (attribute). That will let me configure the export operator to the specific project and simulation code before displaying the operator panel.
A summary of the basic changes I plan to make are:
Remove the pure virtual links() methods from PersistentObject. There is a possibility I will instead have to put placeholder methods in there, but I have not seen any case where I hit the wall by just removing them.
Move smtk::resource::PersistentObject to the common folder (changing its namespace to smtk::common).
Change smtk::project::Project to be a subclass of smtk::common::PersistentObject.
Update ReferenceItem::setObjectValue() to accept any persistent object if its item definition has no “accept” rules.
Also need to add python bindings for smtk::operator::Operator::configure()
I might consider updating smtk::attribute::ReferenceItem to write out the UUID of persisent objects that are not Resource or Component entities, depending on how complicated the read-operator side of things has to be. Technically, my use case does not require persistence from ReferenceItem, but serializing and deserializing would seem to be desirable.
+1 to all of these changes. I think that the last point will require that smtk::resource::Links learn how to deal with smtk::common::PersistentObjects since it can’t know about projects.
I’m happy to have Project inherit PersistentObject. However, there are a couple things I would like to see addressed before making these changes:
Why move PersistentObject out of the smtk::resource namespace? Or do you mean to have both smtk::common::PersistentObject and smtk::resource::PersistentObject? The resource namespace makes sense to me as the “origin” of the class hierarchy related to persistence; this seems to weaken the reason for having it at all.
Why remove links? And if they are removed, where are they reintroduced? The GUI code is greatly simplified by being able to treat both components and resources as objects with a common base class. Links are used for a lot of that. It feels like removing links will cause future headaches in the GUI classes.
One option is to have smtk::resource::PersistentObject maintain its pure virtual methods to a Links instance as @dcthomp suggested, implement it in Project (as it is done for ResourceLinks and ComponentLinks) with another smtk::common::Links datastructure, and modify the smtk::resource::Links API to avoid the need for direct casts to children of smtk::resource::PersistentObject. I suspect it will not be long before someone will want to link some piece of information to a Project instance.
FWIW, if this seems like a fair bit of infrastructure change, it is because the original design was designed around Resources and Components; their common base class was added after the fact. The addition of a third, distinct entity and its need to interoperate with tools that were designed to handle the original use case is not a small change. I think the generalization of smtk::resource::Links to handle any subclass of smtk::resource::PersistentObject would result in a nice, extensible pattern that we could use to easily handle the next persistent object.
If we decide to generalize smtk::resource::Links to deal with arbitrary subclasses of smtk::resource::PersistentObject, I see no reason why both class descriptions couldn’t migrate up to the smtk::common namespace.
But I still don’t understand why these classes need to move out of the resource namespace. If your reasoning is that resource is too specific to resource::Resource, I would rather rename the namespace+directory object (or persistence but please not persistent-object) than move these things to common. Because that’s really what the resource namespace seems to do: introduce a base object used for persistent storage. Why keep the namespace around if everything it exists for already exists in common?
That’s fair. I think the issue was that resource is too specific to resource::Resource. But you’re right, common is specific to nothing and we should avoid treating it like a catchall. If smtk::resource::PersistentObject and smtk::resource::Links links are going to become more complicated, perhaps we should consider moving them to their own namespace (along with smtk::common::Links) as you suggested.
I also hate the name persistent-object for a namespace. Perhaps smtk::asset? Is vtkObject taken ?
Not sure I follow all of the discussion points so far, but I’ll add my own responses anyway. My interest in putting a base class in smtk::common is motivated by 2 things:
Because projects are not specializations of resources, I really don’t think they should subclass from that namespace.
One of the main Project functions is to be a container for smtk resources and, in the near future, other “persistent” data such as simulation input and output decks. I would like a base class outside of smtk::resource for some new class(es) to represent those other simulation assets, so that they can be assigned to ReferenceItem objects.
As for the class name PersistentObject, I don’t have a clear understanding of what makes it “persistent”. Looking at the header file, my impression is that the UUID is its persistent feature. That is the part I propose moving to smtk::common. As for an alternative class name, my current fav is smtk::common::SimulationAsset.
Regarding a common base class for Resource and Component, I didn’t see the need, but maybe I didn’t look very carefully. Whenever I saw resource links being accessed, the code first casts the persistent object to its concrete type. But if keeping a common base class for Resource and Component still make sense, I am cool with that.
Most of the infrastructure for Resources and Components predates the existence of smtk::resource::PersistentObject. Its necessity notwithstanding, its integration into the link infrastructure could provide a more unified relationship between persistent things and links between persistent things.
Currently, a PersistentObject is “something with a UUID and persistent linkage”.
If you don’t want PersistentObject to be in your design for projects, that’s ok. However, if you wish to redefine what a PersistentObject is in SMTK, you will likely get a lot more feedback (not sure if positive or negative; I’m neutral). One alternative is to simply construct a new attribute item that holds projects.
To reiterate, I think we could benefit from generalizing links to PersistentObjects to make PersistentObject more flexible. Persistent things will keep being added to SMTK (and its plugins), and we’ll want to push them all into attribute items and link to them and have them magically come back when we open a file that refers to them. This would likely solve your issue, albeit in a much more labor-intensive way.
The seem that way to me. They are persistent across processes and they are containers. If it is the API on resources that bothers you, then we should split Resource into BaseResource that doesn’t specify what it contains and which both Resource and Project could inherit.
Thanks guys. I think I am coming around to what you are saying/suggesting. To see how much our thinking overlaps, let me throw out a strawman and see if anyone reacts violently.
I (now) like the idea of creating a new namespace and directory for persistent object base classes. As for its moniker, I would vote for smtk::asset.
I would move the current smtk::resource::PersistentObject class to the new namespace, along with smtk::common::Links.
I would also like to rename smtk::resource::PersistentObject to smtk::asset::Asset.
I would also add a default implementation for PersistentObject links (turning the pure virtual methods into plain virtual methods). The default implementation would provide a generic behavior, which wouldn’t know about components, so Resource and Component would still overload links as they do now.
If this is close to a reasonable approach, I have a couple more wrinkles to inject. I don’t know whether their impact on the rest of SMTK is minimal or major.
I would also update the attribute read operator to add an option whether to load reference items or not. This is so that projects, for example, can control which of their persistent objects get loaded into memory at each particular point in the user’s workflow.
The notion of a PersistentObject implies to me a requirement to both serialize and deserialize. When we get to simulation assets, we will only support one direction for some of them. For example, SMTK will only generate simulation input decks – there is no plan to import them back in (although some customers would like that). Conversely, we will only import simulation output decks, of course. My current thinking is that these cases are no big deal, just specializations of PersistentObject,
FYI about to make one change to the strawman – will change my preferred renaming of PersistentObject. I am changing smtk::asset::SimulationAsset to just smtk::asset::Asset, based on the reasoning that “smtk” already implies “simulation”.