Closed eckig closed 9 years ago
Yeah this is a good question, and important for us to document better how to do it. It's on my to-do list.
I have never tried to sub-class GNode or other model classes. I'm not sure if such an approach is possible.
The way it typically works is that you have a separate EMF 'domain model' that the graph diagram is illustrating. Let's say you create an EMF model with a 'Car' class and in the graph editor the nodes are representing cars. Maybe in your software you are using these 'car' objects in contexts that have nothing to do with graphs or diagrams, they are part of your core business logic. You would not do
public class Car extends GNode
because it's not an "is a" relationship. At least that's the kind of use-case we have ourselves.
So what you have are 2 EMF models, one for the core business logic (e.g. your own "car.ecore" file, with a Car class with attributes like name, manufacturer, etc) and one for the visual representations of those objects in a graph diagram (the EMF model provided by us, with a GNode class with layout attributes like x, y, width, height, etc).
What you do want is to edit both EMF models in the same EditingDomain. So for example in the "addNode" button handler you do the following:
Then when you press undo, both the car and the node will be removed, and everything will remain in sync. This requires that both the GModel object and the CarModel object are attached to the same editing domain. You do this via:
editingDomain.getResourceSet().getResources().add(...);
Hooks are provided for other operations like adding and removing connections, pasting nodes, deleting nodes, etc. For example:
void setOnConnectionCreated(CommandAppender<GConnection> appender);
This is how we intend to keep our "domain model" in sync with the graph model. We have not fully implemented it yet, but this is how I expect it to work.
I hope this makes things a bit clearer. Like I said, we will be trying to improve the documentation on this soon.
Thanks for taking the time to clarify this.
However it would be nice to make the hooks more general / functional
void setOnConnectionCreated(Consumer<GConnection> consumer);
void setOnNodeCreated(Consumer<GConnection> consumer);
etc.
You may even retrofit your CommandAppender
Another question on how to link the graph model with the domain model:
The GNode has an ID attribute to identify it, but are we supposed to identify GConnectors? I have the following problem: I get notified when a new connection has been created, but I have no way to transport this connection into my domain model because I can not identify the GConnectors of the new connection..
Fair enough. I added ID attributes to the other model elements. The change is pushed to GitHub. The Maven Central artifacts will be updated in the next release.
Thanks!
By the way I just replaced CommandAppender with BiConsumer. You may need to update your project if you made any explicit references to CommandAppender. If you just passed a lambda expression you probably won't need to change anything.
Thanks for the heads-up. But as you have guessed, we are using lambdas, so it does not break :-)
Maybe that is not really an issue but my lack of understanding using the EMF API.
What I am trying to do is add new attributes to the Model, for example to a GNode. I made a subclass of it and added it to the graph. This works but the EMF model does not really incorporate this subclass, best example is trying to copy and paste this node. The EMF copy method creates a new GNode because it does not know my custom node.
What am I missing here? Any hints are appreciated :-)
(I digged deep into the code and currently my best guess would be that I would have to create my own EMF model classes with my own EPackage and EClass?)