Home » Modeling » EMF Parsley » General Approach for Cross-Editing Domains and Parsley
General Approach for Cross-Editing Domains and Parsley [message #1765240] |
Wed, 07 June 2017 18:54 |
|
Hello,
Please assume the following architecture, using EMF Parsley defaults unless otherwise specified:
- A root Parsley project that defines and initializes a resource containing an object with a cross-reference feature [1] to some other model in some other resource, which is managed by some other Parsley project. The root project defines its own view part (based on a SaveableTreeFormView), feature providers, and resource manager. This root project is generally ignorant of other Parsley projects.
- An arbitrary number of leaf Parsley projects that define their own view parts (also based on SaveableTreeFormViews), feature providers, and resource managers. They know about the root project and can obtain its injector.
With the following workflow:
- The root resource is generally updated via an outside mechanism. Via a UI runnable, the mechanism obtains the root injector, and then its editing domain via its subclassed AbstractSaveableView view part. The mechanism then obtains the command stack and adds commands to it.
- Leaf projects receive notifications of interest from the root project, possibly via an EContentAdapter or CommandStackListener). Via these notifications, a leaf project may create a composite command on its command stack: create a new object within the resource the leaf manages and cross-reference the notifier to this newly created object.
And potential issues:
- Since transactional editing domains aren't in use by the root project, the root project is susceptible to dirty reads. (It could be reading whilst commands are being executed in the UI thread.) However, since it's running in the UI thread and using commands, writes should (?) be OK. As a work-around the reads could also occur in the UI thread.
- Since the root project is ignorant of the leaf projects, it'll also be ignorant to changes in the leaf projects resources (like saves, deletes, etc.). So it'll have to employ some mechanism, like unloading / reloading resources, before trying to resolve the cross-reference.
Are the above issues valid? If so, it seems like a single workspace transactional editing domain would mitigate or remedy the issues above, however with possibly the added complexity of integrating the Operation History API calls with the Parsley views and components, in addition to overriding the editing domain provider and editing domain finder.
Are there other issues I'm oblivious to?
Are there other approaches you'd recommend?
Thanks!!
[1]: interface DomainDomain {
refers DomainDomain source opposite destination
refers DomainDomain destination opposite source
}
|
|
| |
Re: General Approach for Cross-Editing Domains and Parsley [message #1765479 is a reply to message #1765365] |
Sat, 10 June 2017 14:34 |
|
Lorenzo Bettini wrote on Thu, 08 June 2017 12:09
If I understand your scenario correctly, then as long as all the views use resources in the same resource set, then all notifications should be delivered correctly.
Via debugger observation:
All views sharing the same editing domain will receive command stack notifications for actions that occur within any other view (or generally, whenever something modifies the command stack for the shared editing domain). For example, given two AbstractSaveableViewerView views, each with their own resource, both resources within the same editing domain, if one view modifies its resource and add an object to its content, that create/add command is seen by the other view via postCommandStackChanged. Furthermore, the other view will change its selection to this added object via postCommandStackChanged, which doesn't really make sense, because it's in some other resource not directly managed by the other view.
Additionally, since all views share the command stack, undo / redo operations are now shared too. For example, given two AbstractSaveableViewerView views view1 and view2, both with separate resources:
- Create an object in view1
- Create an object in view2
- Navigate back to view1 and undo
- Expected: the object created in view1 is undone
- Actual: the object created in view2 is undone
This is observable via the AbstractSaveableView.mostRecentCommandAffectsResource method on the views.
Lorenzo Bettini wrote on Thu, 08 June 2017 12:09Using the same resource set is just a matter of using the same editing domain, which, in Parsley can be achieved at a JVM level (org.eclipse.emf.parsley.edit.domain.GlobalAdapterFactoryEditingDomainProvider) or at injector level (org.eclipse.emf.parsley.edit.domain.SingletonAdapterFactoryEditingDomainProvider).
My examples above are using a GlobalAdapterFactoryEditingDomainProvider. What I'm noting above might be the actual expected results. After reading up on the use case for the workspace transactional editing domain, it seems it's designed to mitigate the above by hooking into IOperationHistory within Eclipse and managing undo / redo stacks. As for postCommandStackChanged being called, that could be modified in the subclass views to ignore non-resource managed changes. I'm just wondering if this is the recommended approach when faced with one editing domain and multiple independent views.
Thank you for your time Lorenzo!
|
|
| |
Re: General Approach for Cross-Editing Domains and Parsley [message #1766201 is a reply to message #1766192] |
Sat, 17 June 2017 16:08 |
|
Lorenzo Bettini wrote on Sat, 17 June 2017 05:28the fact that a view changes its selection due to a change in an unrelated resource looks like a bug to me! Could you please file a bug and I'll try to fix it ASAP. We could even do a minor/bugfix release without problem.
Bug 518421
Lorenzo Bettini wrote on Sat, 17 June 2017 05:28the single stack per editing domain is instead a safe choice, at least that's what it looks like to me... two changes in different resources could be related (a reference to an object in another resource of the same resource set) and they should be undone consistently. Does it make sense?
I don't disagree about having a single stack per editing domain nor am I proposing having multiple stacks. Repeating the same scenario, given three resources: A, B, & C; three viewers: A, B, & C using the previous respective resources; and the following:
- A user creates a new object in resource A via viewer A. Only resource A is affected; resources B and C are not affected.
- A user navigates to viewer B and executes a composite command that creates a new object in resource B with a cross-reference in resource C. Resources B and C are affected; resource A is not.
- A user navigates backs to viewer A.
At this point, say the user wants to undo the operation on resource A in viewer A using viewer A's context menu. If the user undoes the last operation, they'll undo an operation in two different resources unrelated to A. They'll then have to undo yet another operation (which may not be obvious) to revert the addition in resource A.
I'm not proposing EMF Parsley make any changes here by the way. I think this is expected behavior from the perspective of a developer working with a global (non-workspace) editing domain in Eclipse. However, given an Eclipse user who is unfamiliar with EMF, editing domains, etc., I can imagine them not expecting such behavior. If they undo an operation in some editor / viewer, they're probably not expecting the undo to occur in some other unrelated editor / viewer. Going back to the original post:
Jon Passki wrote on Wed, 07 June 2017 11:54If so, it seems like a single workspace transactional editing domain would mitigate or remedy the issues above, however with possibly the added complexity of integrating the Operation History API calls with the Parsley views and components, in addition to overriding the editing domain provider and editing domain finder.
This still seems like the required path to take given a single editing domain shared with multiple (and perhaps independent) viewers / resources.
For my own use case, I'm changing the architecture currently to use one viewer based on a transactional editing domain. Neither of the above issues affect a single-viewer architecture. (All undo / redo operations are applicable; any action on a resource in the editing domain are applicable). However, I do like the idea of having separate viewers for mostly-unrelated resources that happen to be shared in the same editing domain. It just looks like there's a higher tax paid for such a feature. I'll defer paying that tax until needed :)
Thank you for your time on this Lorenzo!
|
|
|
Goto Forum:
Current Time: Sat Nov 09 02:31:32 GMT 2024
Powered by FUDForum. Page generated in 0.03551 seconds
|