what's the difference between a mapping and a reference in mps?...
This is an auto-generated question from the MPS Slack community: what's the difference between a mapping and a reference in mps?
16 comments
Sort by
Date
Votes
Sorry, I dont understand that question.
for example:
HashMap<node<>, node<>> map = new hm();
// Listener code (interface has children contents)
a = interface.contents.someContainer.first;
b = interface.contents.someStruct.records.first;
map.put(a, b);
and
a.references.add(b)
Slack user:UA14L80HK> edited
why should they be similar? two different things
Not sure I understand the question either.
One is a variable of type HashMap that you instantiate and where you put key-value pairs in (in your example, the type of both key and value happens to be `node<>` .
In this case (the hashmap), you created a data structure that allows you to map from keys to values. But the key and value in it of themselves are not 'related'.
If you add b to the references collection of a, you introduce a 'connection' from a to b. a now holds a reference to b. It is just something different from the HashMap.
needs more context; there is a concept InterfaceChunk that has children of type MessageInterface and StructDeclaration. MessageInterface, in turn, has children which can be of type Field, Event or Method.
The goal is to get the name of each Field, Event and Merhod, create concepts of type Record and add them to the struct that is the child of InterfaceChunk.
The tricky part is adding the struct; it has to be added whenever a Field, Event or Method has its name changed, or created and added, or removed.
The approach taken was to use listeners (one for the container MessageInterface to listen for creation/deletion events, and one for each entry in the MessageInterface (an entry can be of type Field, Event or Method).
The code as it is works well for the MessageInterface listener.
But, for the Fields, Events and Methods, whenever their name is changed by one character(added/removed), the editor window is scrolled down to the beginning of the struct. Then the user has to scroll back up to the entry they were editing and edit one more character. They will, again, be scrolled down and will have to scroll back up again which is impractical and unusable.
The culprit seems to be the *add()* method of a collection, e.g. StructDeclarationInstance.records.add(newRecord).
If there is focus in a cell and *add()* is called, the editor moves the focus to the added node.
The idea is to use either mappings or references to bind the entries in MessageInterface with their counterparts in the Struct so that no call to *add()* is needed.
There's another bug in the listener code; if a user creates a field, event or method, the creation listener fires and an entry with no name is created. The moment they add a character to the empty name, the edit (MessageInterfaceProperty) listener fires correctly. If they type backspace and the name again becomes empty, the event no longer fires and the name in the struct will be the last character of the name (first in case of pressing backspace multiple times).
The mapping together with a non-empty name constraint should fix this, right?
Slack user:U6K3FGW3U> Slack user:U6K7P5XD3> Slack user:UA14L80HK>
I have very limited experience with listeners, but have you tried debugging why the selection changes? I assume the window scrolls down because the selection is updated somehow. Maybe you can share a screenshot of your editor definition for `StructDeclaration` ?
*IF* I'm correct and the listener somehow changes the selected cell to the newly added/updated one in the struct, the question becomes if this is a bug in listeners and if you can circumvent it by explicitly setting the selection inside of your listener using the editor language like `SelectInEditorOperation`.
More generally speaking, I understand what you are trying to do, and IIRC, you mentioned in another thread that the structs are just read-only projections of those Fields, Events, and Methods. I'm not sure where you want users to define which Fields, Events, and Methods go into which struct, but I would generally try to solve this without redundant properties that you manually need to keep in sync, but instead work with different editors for the same data.
You have been chewing on this issue for quite some time, and asking a lot of questions without really getting anywhere, as it seems. I can offer you to do a call and have a look at your implementation together at some point. Maybe I can provide more specific help that way? Let me know if this is something you would like to try.
Sounds like you are trying to do a model-to-model-to-text generation and displaying the content of the intermediate model in the same editor of the user model which, I guess, is in common cases not ideal. I agree with Robert.
Have you considered using https://jetbrains.github.io/MPS-extensions/extensions/shadowmodels/?
Also, if I am not misleading, listeners are not called if property constraints are not valid. I assume that the name property of your field etc. can not be empty (check your constraints). If so, a empty name is not accepted, listeners are not called, the model is not stored on disk etc. All this only happens if constraints are valid.
Perhaps debugging MPS using IntelliJ could be a good option to understand MPS internals more quickly. It's open source.
Slack user:U8PNCP61Z> looking at shadow models now; thanks for the constraints explanation. It's strange that when a field is created with an empty name (which violates the constraint) the event is still fired
I don't have time to look it up myself but aren't node creation and property update two different events triggered by different rules?
yes, there are two different use cases that depend on one another. Got it to work
This is auto-generated question from the MPS Community Slack Workspace. If you want to comment on the question, do it from the Slack workspace
Post is closed for comments.