Home » Eclipse Projects » Papyrus for Real Time » Invoke code generator command line(How can I incorporate the code-generator in the build server)
|
Re: Invoke code generator command line [message #1799514 is a reply to message #1799511] |
Fri, 07 December 2018 23:42 |
Ernesto Posse Messages: 438 Registered: March 2011 |
Senior Member |
|
|
I imagine you are trying to use some form of continous-integration (e.g. jenkins/hudson + maven/tycho or buckminster)? To do this you'll need to have Papyrus-RT installed on your build server and you'll need the standalone version of the code generator which can be found under <papyrus-rt-install-folder>/plugins/org.eclipse.papyrusrt.codegen.standalone_1.0.0.201707181457. There is a (bash) shell script there called "umlrtgen.sh". If you are on Windows, you'll have to run it in a Cygwin terminal.
The problem is that I'm not completely sure the script works as I haven't tested it in a very long time, but you can try to give it a go.
The standard usage is
umlrtgen.sh <plugin-dir> <src-dir> <java-vm> [options] <model-file>
where
<plugin-dir> is the root directory of plugin dependencies, i.e. the 'plugins' directory of the target eclipse platform, or just a directory that contains all required Eclipse jar files.
<src-dir> is the root of the development directory containing the binaries of the development version of the code generator. If used in a production (end-user) environment and not in a development environment, it should be the same as <plugin-dir>.
<java-vm> the name of the Java VM to use. Normally should be "java".
<model-file> is the name of the .uml file (including the extension)
The options are:
-h help (lists options)
-q quiet mode: Inhibits printing messages during generation
-l LEVEL log-level: Set the level of logging (OFF, SEVERE, INFO, WARNING, CONFIG, FINE, FINER, FINEST). The default is OFF
-s Print the stack trace for exceptions
-p Specifies the plugins folders of the PapyrusRT installation
-t Specify the name of the top capsule. By default it is "Top".
-o Specifies the output folder. By default it is 'gen' in the same folder as the input model.
-d Development mode: this is to be used only when invoking the generator from a development environment.
-x Translate an input UML2 model into an xtUMLrt model instead of generating code.
So you are most likely to use the -o option, and maybe the -s and -l options for debugging.
If not using the script, you can try calling directly the java class org.eclipse.papyrusrt.codegen.standalone.StandaloneUMLRTCodeGenerator, using the -p option and calling java with -cp to set the class-path to include all the Papyrus-RT jar files (this is actually what the script does).
|
|
| | |
Re: Invoke code generator command line [message #1799602 is a reply to message #1799595] |
Mon, 10 December 2018 23:23 |
Ernesto Posse Messages: 438 Registered: March 2011 |
Senior Member |
|
|
There are several problems with that script. We included it in the distribution but not "officially", as standalone generation was not a required feature for 1.0. Nevertheless I've updated it and I'm attaching a new copy which will hopefully work for you. Use as follows:
./umlrtgen.sh <path-to-papyrus-rt-plugins-folder> <uml-file> -o <output-folder>
As for overriding the target startup, I think the RTS developer meant that you could link alternative implementations of the umlrtmain.hh header. If you look at the source in the git repo, you'll see there is a file called umlrtmaintargetstartup.cc under plugins/umlrt/runtime/rts/umlrt.
Nevertheless, I don't think this is the place to launch new "external" threads. If you need an external thread, you could modify the TopMain.cc and spawn the new threads there. But If I were you, I would deal with it in a more model-oriented approach: create a Capsule which has a simple state machine with only one state and launch new (external) threads in that state's entry action, or the initial transition. If this solution is not satisfactory to you, I'd be very interested in understanding your use-case.
-
Attachment: umlrtgen.sh
(Size: 4.70KB, Downloaded 91 times)
|
|
| |
Re: Invoke code generator command line [message #1799637 is a reply to message #1799604] |
Tue, 11 December 2018 17:49 |
Ernesto Posse Messages: 438 Registered: March 2011 |
Senior Member |
|
|
With respect to threads: are you trying to a) start a new "outside" thread to execute code that is external to the (code generated by) the model, or b) execute some behaviour, which could be part of the model, in a separate thread?
For option a), I would still recommend the idea I described before: create a capsule, say "ExternalThread" with a simple state machine with only one state and in the state's entry action start your "external" thread, e.g. using POSIX threads [1]. Then, in the Top capsule (or wherever you need it), create a part typed by this "ExternalThread" capsule. If the part is a fixed part, it will be created when it's container is created, which in the case of Top, is when you start the application. I would not recommend messing with the runtime or modifying the generated TopMain.cc, as it would be overwritten whenever you re-generate.
Option b) means that any capsule instance can be executed in a separate thread. More precisely, the thread will run a (RTS) controller, which will execute one or more capsule's behaviours. A controller is the central element of the runtime system. It runs in its own thread, and manages the life-cycle of a set of capsule instances. It contains a queue of incoming messages (shared by all capsules managed by the controller). It basically runs a loop where it gets the event from the incoming event queue with the highest priority, looks at the event's recipient (some capsule) and "gives it" to the capsule to process, which means executing a "run-to-completion" step on the capsule's state machine. It is a "run-to-completion" step because the event will be fully processed by that recipient capsule state machine before the next event in the queue is processed by the controller.
Now, you can have more than one controller and you can assign capsule instances to different controllers, and therefore different threads. There are two ways of doing this:
1) Statically by specifying a "Top.controllers" file. This is a simple text file that you place next to the model and has a simple format consisting of lines of the form:
<capsule-part-qualified-name> = <controller-name>
Where the <controller-name> is given by you. Different controller names will result in spawning different threads. For example
Top.pinger = Controller1
Top.ponger = Controller2
Note that the part's name is qualified, starting with the name of the Top capsule. If capsule "Ponger" had a part called, say "leftHand" of type "Hand", you could write a line like this:
Top.ponger.leftHand = Controller3
or if it had a part called "hands" with replication 2, you could write:
Top.ponger.hands[0] = Controller3
Top.ponger.hands[1] = Controller3
Several capsule parts can be assigned to the same controller, as above or to different controllers. If there is a part for which no controller is specified, it will be created and run in its container's controller, e.g, if Ponger had a part called "eyes" and no controller was specified, its instance would run in Controller2 in this example.
2) Dynamically by specifying a controller on the incarnate operation on an optional part. In this case the container capsule must have a port of type "Frame", and in some action in the state machine you invoke the "incarnate" operation on the Frame port providing a reference to the optional part where you are going to instantiate the capsule, and optionally a reference to some controller. If no controller is specified, the capsule is incarnated in the same controller as the part's owner.
<frame-port>.incarnate(<part-name>)
or
<frame-port>.incarnate(<part-name>, <pointer-to-controller>)
These methods return a "UMLRTCapsuleId" that can be checked for validity, to ensure that the incarnation was successful.
So for example, suppose that "ponger" was an optional part and the Top capsule had a "frame" port of type Frame. Then, you could incarnate ponger in some controller named, e.g. "PlayerController" by writing this in some action in Top's state machine:
UMLRTCapsuleId id = frame.incarnate(ponger, PlayerController);
if (!id.valid()) {
// error
}
One catch is that this code will not compile alone if PlayerController doesn't refer to a (pointer to a) UMLRTController. The code generator will create these pointers and controllers based on the names that appear on the Top.controllers file described above, so even in this dynamic case, you would still need to provide the file, but the incarnate operation would allow you to dynamically assign a controller to a part that has not been assigned one in the file.
Anyway, those are approaches of running capsules in separate threads. If you need to run code that is not in the model, in a separate thread, I would still recommend option a) above. If you don't have some element in the model that you know is responsible for launching a thread, you'll have maintenance difficulties, as it will not be visible in the model who is responsible for some behaviour.
[1] https://en.wikipedia.org/wiki/POSIX_Threads
|
|
| |
Goto Forum:
Current Time: Mon Jun 10 12:23:11 GMT 2024
Powered by FUDForum. Page generated in 0.04268 seconds
|