DrMarkusVoss / pumla

pumla - systematic re-use of model elements described with PlantUML
GNU General Public License v3.0
102 stars 10 forks source link

PUMLAParent Usage #43

Closed rob-bc closed 2 years ago

rob-bc commented 2 years ago

$PUMVarShowBodyInternals does not seem to consider PUMLAParent as suggested in the Users Guide.

I have a system and a subsystem, and I would like to create a system architecture diagram which shows the subsystem nested within the system, by defining 'PUMLAPARENT: system in the subsystem .puml file.

system.puml

'PUMLAMR
'PUMLAPARENT: -
@startuml
!include pumla_macros.puml
!include modelrepo_json.puml

PUMLAReUsableAsset("System", system , component)

@enduml

subsystem.puml

'PUMLAMR
'PUMLAPARENT: system

@startuml
!include pumla_macros.puml
!include modelrepo_json.puml

PUMLAReUsableAsset("Subsystem", subsystem , component)
PUMLAReUsableAssetFinalize()

@enduml

systemArchitecture.puml

@startuml
!include pumla_macros.puml
!include modelrepo_json.puml
!$PUMVarShowBodyInternals = %true()

PUMLAPutElement(system)

@enduml

However, the systemArchitecture diagram shows only the system component. Is this not how this functionality was intended to be used?

Full disclosure that I am trying to implement this on Windows 10 with WSL installed. I have had to make two minor changes to the python scripts (changing forward slashes to back slashes) and all other functions seem to be stable.

DrMarkusVoss commented 2 years ago

Cool that you try to make it work on Windows.

In order to make your example work as expected, you have to enhance your "system.puml" a bit:

system.puml

'PUMLAMR
'PUMLAPARENT: -
@startuml
!include pumla_macros.puml
!include modelrepo_json.puml

PUMLAReUsableAsset("System", system , component) {
           PUMLARUAInternals() {
                PUMLAInjectChildElements(system)
        }
}

PUMLAReUsableAssetFinalize()

@enduml

The first added line (PUMLARUAInternals()) allows the following parts to be switched on/off with the global variable $PUMVarShowBodyInternals. The second added line allows elements to be injected into "system". This is kind of a "responsibility/ownership" thing, to prevent that at some point in the git repo someone extends the model of another owner with some internals just by naming "system" the parent. So the "system" owner (as parent) has to explicitly allow the children to come in, so the "PUMLAInjectChildElements(...)" is the kind of door-opener for that.

And just to be "clean", you also have to add the "PUMLAReUsableAssetFinalize()" in the system.puml. This always needs to be called when you use a "ReUsable Asset = RUA" Macro for the element creation. Otherwise unexpected things might happen.

See also the "Weather Station/tempSys.puml" example: https://github.com/DrMarkusVoss/pumla/blob/main/test/examples/WeatherStation/tempSys.puml

I just realized, that the "PUMLAInjectChildElements(...)" function is not in the User's Guide (anymore?). So I will keep this task open until I fixed that.

Hope that helps!

Thanks!

rob-bc commented 2 years ago

Thanks for the quick response and advice!

Ok the rationale makes sense. I did indeed see that usage in the example but following that guidance also leads to some unexpected behaviour from the systemArchitecture.puml file:

  1. When setting !$PUMVarShowBodyInternals = %false(), I would expect to see only the System component, but the diagram is blank.

  2. When setting !$PUMVarShowBodyInternals = %true() and stating PUMLAPutAllElements(), I would expect to see the same diagram as produced by the system.puml file, but the diagram shows only the Subsystem component.

What am I missing?

DrMarkusVoss commented 2 years ago

First, I did a mistake with my updated version of the "system.puml" in the previous comment, I corrected it in the comment above. The "{" has to be in the same line as the macro command (PUMLAReUsableAsset...), same for all these kinds of macros. But I guess you made it right otherwise you wouldn't get the behavior described.

Second: you get the behavior you want when you remove the "PUMLARUAInternals() { ... }" around the "PUMLAInject...". But I actually do not know why ;-). In the tempSys example it still works for me as expected. So this seems to be a bug.

I will investigate this, thanks!

DrMarkusVoss commented 2 years ago

Addition:

The files in which you model the re-usable elements (e.g. system.puml, subsystem.puml) should never include global variable settings, as they will be potentially included in several diagrams and that would mess up your intended global variable settings.

So the recommended way would be to basically see everything (no override with !$PUMVarShowBodyInternals = %false()) in the element definition of system.puml, so that you see it all there. And switching off seeing the internals only in diagrams where you use once modeled elements.

I will check whether this is already reflected in the Modeling Guideline. In the examples it seems I did that right.

Still, the element not showing up in the systemArchitecture.puml when the "PUMLARUAInternals()" is at place is a bug that I need to fix.

DrMarkusVoss commented 2 years ago

It seems to be a bug of PlantUML. I guess it is a quite new bug, as I remember playing heavily with that feature before using it.

For not showing the internals I use the "remove" command of PlantUML to remove the "internal element".

Now this "remove" command seems to have a bug.

If you try this code

@startuml

component "System" as system {

component "Tese" as tese

}

remove tese

@enduml

e.g. here: https://www.planttext.com

then you will also see a blank picture.

Instead the expected behavior would be a diagram like this:

@startuml

component "System" as system {

}

@enduml

It seems to have a problem, when there is no element left inside, because if you have two things inside, and delete just one, you get what you expect:

@startuml

component "System" as system {

component huhu

component "Tese" as tese

}

remove tese

@enduml

I will try to find a workaround for that.

rob-bc commented 2 years ago

Yes I managed to spot the "{" error after a bit of trial and error - I was supposed to mention it but got distracted...

Re. the tip on Global Variables - I will keep that in mind, thanks. I have not been through the Guidelines thoroughly yet, I was saving that for after these initial trials ;)

As for the PlantUML Bug - interesting edge case! Fortunately removing the "PUMLARUAInternals() { ... }" as you suggest does seem to be a workaround for now, and I also don't expect many (if any) instances with a single child component so it should not have much impact.

Thanks a lot for looking into this - really appreciate the support!

DrMarkusVoss commented 2 years ago

@rob-bc I think I found a nice workaround for the problem. In order to be able to switch on/off showing the internals, it is necessary to use the PUMLARUAInternals(). I now also extended the possibilities for showing/not showing dedicated internals. I also documented everything as example, that is basically your example but a little extended, to show how this could now be used:

https://github.com/DrMarkusVoss/pumla/blob/main/test/examples/simple/hierarchicalSystem/ExampleSimpleHierarchicalSystem.md

Hope that does the job for you.

rob-bc commented 2 years ago

Great thank you @DrMarkusVoss ! I have been off work for a couple of days but will give it a try soon and report back