Send to Printer

DSM-tech

Comparing tools, plus spatial relations in MetaEdit

January 15, 2008 17:54:37 +0200 (EET)

Steffen Mazanek writes about an interesting metamodeling practical that he's conducting: students have to implement a cut-down UML Class Diagram editor using MetaEdit+, Eclipse GMF or Microsoft DSL Tools. It reminds me of the "Use Case cartoon" experiment where MetaCase and Microsoft both built very simple Use Case diagram support in their respective tools. Doing it with MetaEdit+ was 6 times faster back then, but hopefully Microsoft have caught up somewhat since then. Mind you, those figures were when the tools were used by their developers: when used by students, I'd expect MetaEdit+ to fare better.

Steffen also wrote a nice mini-review of MetaEdit+ . He especially liked the ease of use, the Symbol Editor and the high level of integration (as opposed to the multiple mapping languages of GMF). He said MetaEdit+ would find it hard to support languages using spatial relations, e.g. VEX, which uses visual containment rather like Venn diagrams. I'm not sure I'd agree with that. Here's a picture of something like VEX: each circular object has its name in bold at the top, and at the bottom a list of the objects that it contains (recursively).

VEX-like diagram in MetaEdit+

To build the metamodel took a couple of minutes. MetaEdit+ already understands containment via the 'do contents' structure in its MERL generator language. However, that calculates contents based on the enclosing rectangle of the symbol, whereas for VEX it should be based on circles. Otherwise 4 above will be considered as completely contained in 1: true if you think of their enclosing rectangles, but not for the circles. The little bit of generator script that produces the text at the bottom of the circles therefore needed to be a bit longer than just "do contents { id }". Here's what it took:

Report '_contents'
  /* report all contents of the current object, flattening any nesting */
  do contents
  { subreport '_calcMargin' run
    if $margin >= '0' NUM then :Name endif
  }
endreport

We go through all the objects contained in this object, using the standard "do contents" rectangular definition of containment. For each little object we calculate the margin between it and this circle. If it's positive, the little object is contained and we print its name.

Calculating the margin is done in the calcMargin sub-generator, which saves it in a variable called margin. The formula is simple enough, but might take a moment's thought if your geometry is as rusty as mine:

Report '_calcMargin'
  variable 'margin' write
    /* big object radius - center difference - little obj radius */
    math 
      width;1 '/2 - '
      '((' centerX '-' centerX;1 ')^2 + (' centerY '-' centerY;1 ')^2)^(1/2)'
      ' - ' width '/2'  
    evaluate
  close
endreport

Basically we want to check that the big object's radius is bigger than the distance from the centre of the big object to the outer edge of the little object. The distance to the outer edge is the distance between the centres, plus the radius of the little circle. The distance between the centres is calculated with Pythagoras' theorem, and the radii are just half of the width of the objects. CenterX and width here refer to the little object, whereas the ;1 suffix in width;1 makes it return the width of the big object, one level further out on the element stack -- i.e. from outside the "do contents" loop.

When drawing the symbols, MetaEdit+ thus calculates and displays this list of contained objects. It's even updated on the fly as you drag and scale objects. This lets you do cool things like show big red error signs if someone drags an object into the wrong kind of container.

Putting _calcMargin in its own sub-generator allows us to reuse it from other generators, e.g. to produce an indented "tree" listing showing the containment hierarchy of all the objects (like the default "Object Nesting" generator in MetaEdit+).

Comments

VEX again

[Steffen Mazanek] January 15, 2008 19:46:04 +0200 (EET)

Hi Steven,

VEX is a VL that makes it especially hard to implement a free-hand editor for. You have only three components, the circle, the line and the arrow, which can be freely arranged on the canvas. Spatial relations like "containment" or even "touching" are heavily used to determine the represented expression. There is no simple mapping like circle=variable... Thus syntax analysis is very difficult.

Maybe this lack of editor support is the reason that the language is not so widely used :-) Nevertheless, I really like it (in particular because variable bindings are explicitly denoted and not hidden behind their names) and plan to post an article about this language in the nearer future.

Regards,

Steffen

Another use of position information

[Steven Kelly] April 02, 2008 00:10:22 +0300 (EEST)

Janne Luoma points out in the new MetaEdit+ Forums that the MetaEdit+ demo repository now contains a new project with an example of using position information as the basis for ordering. It's also a cool example of how symbols can update dynamically: little buttons appear in the symbol for each relationship attached to that object. You can see a similar approach in the watch Model symbols in this Watch Family diagram: they have as many little buttons on their edges as there are buttons specified for that physical watch. E.g. Ace there uses the X334 display, which contains four buttons -- Mode, Set, Up and Down -- and so the symbol for Ace shows four buttons. Compare that to Celestron, which uses the X032 display with just Mode and Set, and so only shows two buttons.