Assigning Properties When Setting qtReferenceItems

We are beginning to see use cases where the designer would like the act of assigning a SMTK Persistent Object to a Reference Item to also attach a Property to the Persistent Object as well.

For example say you have a Reference Item that represent all of the objects that belong to concept “A” so that the act of adding/removing an Object from the Item represented adding/removing the Object from Concept “A”.

In another attribute you wanted to restrict its association to only Objects that belong to Concept “A”.

If a Reference Item was Resource Component, we could simply refer to the Item; unfortunately it is not.

An alternative approach would be to have the qtReferenceItem UI class have an option to assign a specific Property (type and value) to a Persistent Object when it is assigned to the Item and have that Property removed when unassigned.

Since the act of assigning/removing Properties changes the resource the Object belongs to, the class would use an Operation to set/unset the Property as shown below:

If the Persistent Object is itself an Attribute from the same Resource as the ReferenceItem, then the Property could be directly assigned (since the assumption that the Attribute Resource itself is safe to be modified. Instead of the Property Operation being called, a simple Signal Operation would be used to make sure the rest of the UI is up to date.

Setting the Property Mechanism would be done using an ItemView Configuration.

<ItemViews>
  <View Item="myRef" PropertyType="long" PropertyName="foo"  PropertyValue="5" Role="12"/>
</ItemViews>

Restrictions

  • The Role must be unique if there can be more than one Attributes from the Definition containing the above Reference Item. If the role isn’t unique, then one Reference Item could remove the Property even though the Object is assigned to another.
  • The Property also needs to be unique since you could run into a similar problem if two ItemViews used the same Property name and type.

Trying to make this part of SMTK Core

The main issue here is the need to run an Operation. As of today the Attribute API is not operation-based and to have the implementation of ReferenceItem::SetValue(…) to schedule an Operation could have unforeseen consequences. Prior to doing this, it might be better in the long run to make Item a Resource Component and directly refer to the Item instead of using a Property.

@dcthomp @chart3388 @amuhsin @johnt FYI

My preference is to make Item subclass Component. However, even if Item was a Component, it sounds like we are talking about extending the Resource::queryOperation() grammar to accommodate this. I’m curious what that would look like and how efficient the query would be.

I am not as concerned about setting properties being an asynchronous Operation:

  1. Many modern user interfaces, especially web-based ones, adopt a similar pattern: input from the user causes an asynchronous request to some (remote) service. The UI monitors the service for events and updates itself when the service notifies the UI the of the results of the request.
  2. There are several alternatives for handling membership and property pairing:
    a. We could have an operation that updated membership in the attribute item and set the property on the member components at once. This would likely require the other Qt attribute views to lock the attribute resource during their edits (since operations run in separate threads). There doesn’t seem to be anything preventing Qt views from grabbing an attribute::Resource's write-lock; the qtBaseAttributeView just needs to be a friend of smtk::resource::Key and offer a method to construct a ScopedLockGuard for its attribute resource.
    b. We could have the qtReferenceItem observe the operation manager and only modify their membership once the property assignment/erasure operation completed.
  3. We are already allowing attributes to enter invalid states in response to user input (which I believe is the correct approach), so even if property and membership are temporarily out of sync, it should be detectable and correctable.