@tjcorona I am working on this issue which I initially misunderstood. Now I understand but have some questions.
qtComponentItem can be used for (a) simulation attributes and (b) operation parameters. For (a), there will clearly be links that I can fetch from the attribute resource. For (b), I don't think links will be present. What should I do for (b)?
How do I detect when links for an attribute resource have changed? Is there an observer? If not, I know there's an operation to link resources... do I have to watch operation results?
Underneath the hood, qtComponentItem uses ComponentPhraseModel. I can provide a set of whitelisted resources to the phrase model... is that what I should be doing? (i.e., Should whatever uses ComponentPhraseModel be responsible for observing link changes and updating the list of "active" resources the PhraseModel pulls from?)
@dcthomp I don't have answers to these questions, but here are my opinions:
We could have an "unfiltered" mode and/or have the first component selected implicitly construct the association. I think that having unfiltered access to the components would be the most intuitive choice, though.
There is currently no observing changes in link status. As you mentioned, there are definitely other signals you can listen to for this behavior.
If I understand correctly, you are asking whether filtering should happen at the Qt layer or at the smtk::view layer. I think view narrowing should happen at the Qt layer, since (to me) it is a UX effect.
@tjcorona I think we are going to have several places where the same logic will be used; given:
a resource manager,
a map of "acceptable entries" (i.e., tuples of (resource name, component filter) strings),
a resource for "context" (i.e., the resource whose links should limit the acceptable entries), and
a role (maybe it should default to smtk::resource::Resource::AssociationRole)
we want to iterate/visit all matching persistent objects. Rather than repeat the implementation, should we make it a method in the resource::Manager or resource::Links class?
@dcthomp I think much of the parsing logic may already be in place as a consequence of using multi-index arrays for link storage. We should chat about the specific functionality you want.
@dcthomp Ah, I read your bulleted list as a set of independent conditions when we would want to visit objects. Instead, you mean that all four of those conditions are present and we wish to perform visitation, right? If that is the case, I believe the correct place for that method could be in the resource::Links class. I would be happy to add this feature if you like.
... I believe the correct place for that method could be in the resource::Links class.
That would prevent us from providing the default role, which is OK with me. However, I see that both smtk/model/Resource.h and smtk/attribute/Resource.h provide AssociationRole = -1. Would you mind moving AssociationRole to somwhere in smtk/resource and just defining it once? I don't like coincidentally-equivalent numbers.
@dcthomp they are only equivalent by coincidence. I did not think the concept of association existed at resource scope, but rather at attribute and model scope. For instance, for meshes there’s classification. Either way works for me though.
I would prefer either they be declared separately but with different values or to have the declaration be once and common. Having a coincidental value could make debugging a royal pain.
@dcthomp I am having a bit of trouble understanding the method you want (namely the role of the "context" resource). Can you give me a concrete example?
@tjcorona Sure. Let's say I have a simulation attribute linked to 2 out of 4 model resources registered to a resource manager. The attribute has a ReferenceItem with <Accepts> entries that would allow faces from all 4 model resources but because of the links, it should only accept faces from those 2 resources. I want a method to populate the qtReferenceItem's ComponentPhraseModel with just the acceptable faces from those 2 resources, not the acceptable faces from all 4 resources. The resource owning the simulation attribute is the "context" resource. The ReferenceItem provides the multimap<string,string> of acceptable entry filters.
You might try to argue that the ReferenceItem should just ask its attribute's resource for acceptable components. But the problem is that that's not the only use case for ComponentPhraseModel: the GUI for an operation will have an attribute resource that is not linked to model systems. However, the GUI that owns the ComponentPhraseModel may be able to infer (say, through a workflow) the "contextual" resource whose links should be used in place of the operator's specification.
That's why I want this generic method for obtaining entries. I can see several GUI elements that all might benefit from it in similar circumstances.
@dcthomp Is the "context" resource always an attribute resource? The "acceptable entries" multimap is currently a feature of the ReferenceItem, and there is currently no concept of filtering what is "linkable" to a resource. Also, filtering by the "association" role is (I think) also an attribute resource concept (models have associations, but no filtering for them). My hope is that we could add this functionality to the attribute resource, rather than push several of the above mentioned constructs up to the resource API.
@tjcorona No, I'm not sure the context is always an attribute resource. Nor do I think this will always be limited to associations; other roles might need the same GUI and want to provide the context separately. The acceptable entries multimap is not limited to the ReferenceItem.. they are also held by some GUI elements. Those elements may provide an interface to attributes at the moment but I can imagine wanting to use them for other purposes.
For example, say I want to present mesh sets linked to the same geometric model as another mesh set so users can choose from among mesh resolutions. The context in that case would be the model system.
... say I want to present mesh sets linked to the same geometric model as another mesh set so users can choose from among mesh resolutions. The context in that case would be the model system.
The presentation need not be part of an attribute selection; for instance, it could be part of a user-initiated search in the resource panel.
My hope is that we could add this functionality to the attribute resource, rather than push several of the above mentioned constructs up to the resource API.
What construct are you thinking of? The multimap<string, string> is a natural consequence of smtk::resource::Resource::queryOperation(const std::string&) and smtk::resource::Manager::find(const std::string&). Links with roles are already present in the resource system. I don't understand the opposition to an API that just tries to find things using the system we have set up to organize things.
smtk::resource::Resource::queryOperation(const std::string&) is definitely part of the resource API.
smtk::resource::Manager::find(const std::string&) is 1/3 of the triplet of the resource manager's API (the other two being one with a type id and one with a template parameter). If the API were to go in resource, I would need to support an API that referred to resource types using all three mechanisms.
Links with roles are already present in the resource system
True, but roles have not been involved in queries. Links have an API, the resource manager has an API, and never the twain shall meet, as it were.
How would you feel about a free function or a functor in resource that performs this query? That way, the query can be seen as more of a convenience method and less of a tethering of the APIs of the different sections of resource.
smtk::resource::Manager::find(const std::string&) is 1/3 of the triplet of the resource manager's API (the other two being one with a type id and one with a template parameter). If the API were to go in resource, I would need to support an API that referred to resource types using all three mechanisms.
However, we have already talked about making find() take strings that are more than just type names but instead queries (like queryOperation()) that subset resources based on concepts (e.g., find("smtk::attribute::resource[link=smtk::session::vtk::resource]") to locate attributes linked to VTK models).
Even if you want to name that method something else (i.e., find() searches only by type name while queryOperation searches by "filter string"), the camel's nose is in the tent: we have search strings for resources and search strings for components in a resources. Tuples of those strings is a natural consequence.
Links with roles are already present in the resource system
True, but roles have not been involved in queries. Links have an API, the resource manager has an API, and never the twain shall meet, as it were.
So... it hasn't been done thus it shouldn't be done? :-) My argument is that links are an organizational principle for resources; we are trying to present that organization to users. We have done a hackish (or at least incomplete) job in the past, knowing that we could do better. The time is coming and now is when we should do better.
How would you feel about a free function or a functor in resource that performs this query? ...
Sorry I’ve been mia in the conversation. I agree that having the acceptableObject() method be in once place makes sense. Right now it’s in qtAssociationWidget and qtModelEntityAttributeView (and I’m assuming it would be in the qtComponentItem class as well).
The problem with having it in the links code is that when there is no explicit associations between the attribute resource and other resources, the behavior is to go to the resource manager and pull the info from it. Maybe it should be a method on ReferenceItemDefinition (as well as having a static method that qtModelEntityAttributeView could call (since it doesn’t explicitly has a reference item definition associated with its).
Does that make sense? If it does then the code could be directly lifted from one of the existing classes and moved into the definition class.
I agree that having the acceptableObject() method be in once place makes sense. Right now it’s in qtAssociationWidget and qtModelEntityAttributeView (and I’m assuming it would be in the qtComponentItem class as well).
It's not in qtComponentItem directly; it's in smtk::view::ComponentPhraseModel , which is not necessarily tied to a view of an attribute — it could be a view of components related to a mesh or model by some role other than association. That's why I think it should live in smtk/resource.
The problem with having it in the links code is that when there is no explicit associations between the attribute resource and other resources, the behavior is to go to the resource manager and pull the info from it.
I'm not sure I understand... do you mean that behavior (fetching all acceptable matches from the resource manager) is undesirable or that it is unattainable somehow?