|
Hey Michael,
unlike the simplifiers, which perform a model transformation from user to simplified model, the ruleset then applies a model-to-text transformation.
Within Rhapsody, the rules are executed by the RulesPlayer. In order to change the existing ruleset (named RiCWriter), you need the RulesEditor, which in turn is a feature subset of the RulesComposer, that lets you define transformations between any metamodels, not just Rhapsody MM to text.
RulesEditor and RulesComposer are covered by separate licenses. You have to contact Telelogic for prices and whether they provide academic licensing. On top of this, there is yet another license to be allowed to perform custom-code generation in RiC in the first place. It is a bit messy. Tell Telelogic what you want to do and you'll get a quote...
Mike
|
|
|
|
|
Hi Mike,
thanks for your immediate response - I have contacted Telelogic and now I'm waiting for their response
In the meantime, I'm having difficulties with yet another topic. Although this is not directly related to the topic of this article, it is a problem with Rhapsody in C. Maybe you have a hint on that as well, or what would also be much appreciated, if you could point out some forums or newsgroups where I could post such Rhapsody-questions to!?
The problem is following:
I would like to generate events from within my code (for example if I hit a button in my application, and event should be generated and lead to a state-transformation in Rhapsody). According to the documentation, this could be achieved by writing a statement like "GEN(evName);"
Unfortunately, at compile time Rhapsody says it cannot recognize the symbol "GEN".
I did this before in Rhapsody in Java, where it worked perfectly well. Seems that maybe the syntax is different in RiC - do you by chance have ever used this mechanism in RiC and can tell me what is wrong with my try?
Cheers,
Michael
|
|
|
|
|
Hi Michael,
the command is CGEN . If you have an event named evNewData, then you send this event to an object (pointer) pObject by writing:
<br />
CGEN( pObject, evNewData() );<br />
That should do it. Events can have parameters too, which you then access through a struct always called params in the context of the transition belonging to that event.
As for your question regarding a forum. Unfortunately, there is only a closed forum within the Telelogic site, called the client-center. You must be a registered customer (proven by showing your license) to get in there... IMHO, not too smart to keep it a closed area.
Mike
|
|
|
|
|
Hi Mike,
thanks for pointing that out - I was now able to generate events programatically. Also, I obtained the necessary licenses in the meantime. Therefore, I tried to go through your nice tutorial. However, I faced an issue that prevented me from success so far:
After having completed all the steps as you have described, I tried to generate code from Rhapsody. Unfortunately I get following error:
----------------------------------------------
<br />
All Checks Terminated Successfully<br />
<br />
Checker Done<br />
0 Error(s), 0 Warning(s)<br />
<br />
Code generated to directory: E:\Projekte F&E\MobileSysDesign\Development\Mobile_C_Test\Rhapsody\DefaultComponent\DefaultConfig<br />
<br />
CG ERROR: External code generator was not created.Please check your plug-in settings.<br />
<br />
<br />
Code Generation Done<br />
<br />
1 Error(s), 0 Warning(s), 0 Message(s)
------------------------------------------------
Do you by chance have any idea what this error could mean? If necessary, I could provide you with more details about the steps I did for trying to customize the code for my project.
Cheers,
Michael
P.S.: also, when building the C# project that includes your base class CodeGenSimplifier.cs, I got errors at using the method
rpApplication.writeToOutputWindow(...); . So I had to comment that out in the meantime.
|
|
|
|
|
Hey Michael,
the error message is somewhat confusing. Which version of RiC are you running? 7.1.1MR1?
If I recall correctly, by the time this message is printed the simplifiers have already been run. Next RiC will instantiate the RulesPlayer, which is what I think goes wrong here, maybe for license reasons... I am currently not at work but tomorrow I can post the names of the licensed features that are required.
Before running your own simplifier, just try the following:
Create a new model, add a class or so. Make sure the model builds fine. Then, e.g. on project or component level, change the property C_CG.Configuration.CustomizableCG to true and regenerate. Does that work?
What has not been discussed at length in the article is that Rhapsody comes with ways to connect to custom simplifiers through what is called a Rhapsody plugin. However, that method is not documented at all and does not work well with .NET. So here, we use the search and connect way: Find and connect to a running RiC instance. I am wondering whether any sample snippets got you moving towards the plugin-based directions. AFAIK, you can't mix the approaches.
Finally, it is really weird you get compilation errors? What kind of errors do you get? Please post them. Does your rhapsody.RPApplication object in the RCW (interop) provide another method like that? Can you browse the rhapsody namespace in VS2005 in the object browser?
We'll get you generating... I am sure...
Mike
|
|
|
|
|
Hi Mike.
Hm, I guess you are right - the simplifiers may have run correctly, but there might be a license issue. My current version in use is Rhapsody 7.0 in C Development Edition.
So I tried building the "mini model" as you described, and as soon as I set CustomizableCG to true, regeneration failed. However, I asked a friend to try the same "small model" with his version (I think he used the latest trial edition, v7.1), and there it worked.
So tomorrow I will try to install this demo version on another PC as well and see whether it works there or not. If you could post the names of the licensed features it would be greatly appreciated though, since I can contact Telelogix more specifically.
In the meantime, I'd like to point out following points:
Regarding the Rhapsody plugins: I haven't heard of this possiblity before. So far I was just trying to get your class from the tutorial up and running.
And I think this should fit my needs - to give you an idea, this is what I would ultimately like to do:
My project is roughly about modeling a HMI of a cellphone with a statechart. In there, I'd like to specify new stereotypes to some states in my model on my own, e.g. <<simplemenuentry>>, or <<smsinputeditor>>,...), and later on generate code templates for each of the different stereotypes (e.g. write a code template for displaying a simple menu entry, or a code template for smsInputEditor).
To achieve this, I was thinking to simplify the stereotypes in a first step to some C compatible datatype/structures. In the second step I thought generating rules with the RulesComposer should help me generate those templates from the newly simplified model. So I hope I got the possiblities mentioned in your tutorial right? (hope I could describe the requirements of my system clear enough...if not, just tell me again)
Regarding the compilation errors in the class you provided, I get following errors:
------------------------------------------------
<br />
------ Rebuild All started: Project: ConsoleApplication1, Configuration: Debug Any CPU ------<br />
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:obj\Debug\Interop.rhapsody.dll /debug+ /debug:full /optimize- /out:obj\Debug\ConsoleApplication1.exe /target:exe CodeGenSimplifier.cs MySimplifier.cs Program.cs Properties\AssemblyInfo.cs<br />
<br />
e:\temp\SimplificationTest\ConsoleApplication1\CodeGenSimplifier.cs(177,27): error CS0117: 'rhapsody.RPApplication' does not contain a definition for 'writeToOutputWindow'<br />
e:\temp\SimplificationTest\ConsoleApplication1\CodeGenSimplifier.cs(194,31): error CS0117: 'rhapsody.RPApplication' does not contain a definition for 'writeToOutputWindow'<br />
<br />
Compile complete -- 2 errors, 0 warnings<br />
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========<br />
------------------------------------------------
So from my understanding, the method writeToOutputWindow seems not to be a member of
rhapsody.RPApplication . And as to your question: yes, I can browse the RPApplication-object from within Visual Studio. However, I don't see any other method that should do the same thing than our method in question.
So what should be the exact effect of this method? Where does it write this message to - to some output window within Rhapsody during code generation?
And what's the difference between using registry.writeCodeGenMessage - does this one write to a different window to?
Hmm...quite a lot of information so far. More details when I tried the simplifier with the demo version tomorrow
Thanks so far and
Best regards,
Michael
|
|
|
|
|
Hey Michael,
yes try running RiC 7.1 or later (I am using 7.1.1MR1). I think that should also fix the API problem (RPApplication.writeCodeGenMessage). In the meantime, you should be able to use the registry method instead.
However, I am worried that mechanisms changed between 7.0 and 7.1 such that my class may possibly not work correctly in 7.0.
To perform custom code generation the following Rhapsody features must be licensed:
FEATURE RPCustomCG (for any kind of custom code generation)
FEATURE RPExtCodGen (for any kind of custom code generation)
FEATURE RPExtCustCG (for any kind of custom code generation)
FEATURE RPRulePlayer (for RulesPlayer)
FEATURE Sodius_generator_pro (for RulesComposer)
Your approach sounds feasible and is possible with RiC from what I can tell.
Mike
|
|
|
|
|
Hi Mike,
in the meantime I have tried to run your sample code with the latest trial version from the Ilogix homepage (7.1.1 Developer Edition) - but even there I got the same errors as described. However, the workaround (using registry.writeCodeGenMessage ) worked fine for me, so finally I was able to run your sample correctly. If I can try anything else to help you fix this problem just let me know.
During the last days I also played around with the built-in code generator MiaGeneration. I hoped that by opening the project "RicWriter.prj" (from the folder <rhapsody>/Share/CodeGenerator/GenerationRules/LangC/RuleSet) I could see the actual transformation rules, e.g. how to generate C-code for a statechart in my model. But from what I can tell, I could not access that information in detail
So after all, right now I'm not 100 % sure on how to proceed to customize my statechart. Do I have to simplify at all first, or should I better focus on the rules (because stereotypes can also be directly accessed from the UML metamodel)? But as already mentioned, so far I could not find the current model-to-C transformation rules in use (since I only want to extend them, not define all of them from scratch again). Do you know if they are publicly available?
Right now my model consists of a class which has a statechart attached. In this statechart are a couple of states, and I gave some of them the stereotype <<mystereotype>> defined by me. All I want to do in the first place is to generate some code, that adds the code line printf("stateName\n"); (where stateName is being replaced with the actual name of the state) to all states that have the stereotype <<mystereotype>> (so the C code should be the "usual" one for a state (with entry/exit-action and the like), but extended by this printf-line, e.g. as predefined on-entry-action).
If you would have a hint for me on how to proceed best, I would greatly appreciate it. Maybe you have customized statecharts with stereotypes before!? Unfortunately there are practically no discussions in the Ilogix support forum on these topics.
I think these things are what you refer to as "how the actual transformation code should work" in your article - so I would definitely be interested if you would provide a follow-up article on that
Best regards,
Michael
|
|
|
|
|
Hi Michael,
writing another article on this topic is a good idea, unfortunately, I currently don't have the time... So I'll try responding to your questions directly.
The article says something about how to decide where to apply which kind of transformations or adaptations to the generation process. This is meant as a guideline from which you sometimes have to deviate... like in your case. The reason is that Telelogic creates the statechart execution code (like the dispatch methods) in their built-in simplifier. Now, I totally agree that this may not be the ideal location, but that is how its done.
Therefore you won't find the statechart skeleton code in the RiCWriter ruleset. The ruleset does not know about statecharts. One can argue that this is even ok, since statecharts are not available in C...
As a consequence you are required to perform the changes in a simplification step, which you would trigger by changing the property C_CG.Statechart.Simplify . If you set this to ByUserPostDefault you'll receive the statechart as generated by Rhapsody for your perusal. You will be able to change what was created, e.g. by serching for your stereotypes and implement a different behavior for them. If you want to create textual code in a simplifier you will need to do this through string operations the result of which is then assigned to an operation's body attribute. Not elegant, but it works. You could aso not do it that way, and add your stereotype to the RiCWriter ruleset and there create a new code template. While the latter is cleaner in terms of methodology I am not sure it is worth it.
If I find that Telelogic created cludges like that I'll bitch about it but then get back to work and won't try to improve that part of the architecture, since you then start working against the tool, a fight you eventually will loose...
Not sure I told you that by switching on C_CG.Configuration.ShowCgSimplifiedModelPackage you will be able to browse through the output of the built-in (and your own) simplifiers. This is of great help when reverse-engineering what needs to be written, as documentation of all this is, well, not existing.
Best,
Mike
|
|
|
|
|
Hello Mike,
hmm...ok. Since the statechart execution code is created in the simplification step, I really should focus on that.
Indeed I have already tried hanging onto the C_CG.Statechart.Simplify property before, but failed for following reasons:
(for your information: my test model just consists of one class, which has one statechart with one state attached)
- when I set this property on class-level (means in the properties-tab directly of the class) to ByUserPostDefault , regenerating code does just nothing (only OnBeginSimplification is called, but not the method OnPostSimplify of my simplifier)
- when I set this property directly at statechart-level (means in the properties-tab of the statechart-object, that I selected from the model-browser on the left hand side), I get following error when regenerating:
<br />
All Checks Terminated Successfully<br />
<br />
Checker Done<br />
0 Error(s), 0 Warning(s)<br />
<br />
Code generated to directory: E:\temp\RhapsodyProject\deleteMeRhapsodyTest\DefaultComponent\DefaultConfig<br />
<br />
CG ERROR: Activation of external simplifier Post Simplify action failed<br />
<br />
Invoking RulesComposer Generator<br />
Using Generation Scenario : Rhapsody_Generation<br />
...<br />
So up to now I was not able to catch a call to my statechart
Another weird behaviour is that setting the property C_CG:Class:Simplify to ByUser also does nothing (the corresponding method OnSimplify in my simplifier is never called) - whereas setting it to ByUserPostDefault works as expected and my breakpoint at OnPostSimplify fires. (This is also true for other elements - so I could customize classes and relations, but it never fired for events and statecharts for example).
Have you ever experienced anything similar? If so, it would be nice if you could again bring me back on the right track
-----------------------------------------------------------
And about the C_CG.Configuration.ShowCgSimplifiedModelPackage property you mentioned - could you be a little bit more specific on where I am able to browse the simplifier-output? Somewhere in the code during simplification, or did I misunderstand that part?
Muchas gracias,
Michael
|
|
|
|
|
Hi Michael,
since I so far did not need to change the code for statecharts, I have not experienced what you describe. In general what you tried and where you set simplify properties all makes sense. Two things that may be useful to know
(1) Rhapsody sometimes gets into a weird state, where it does not really know whether there are any custom simplifiers registered. That typically results in the Activation of external simplifier ... failed error message. If you see something like that, try restarting RiC, reconnect and regenerate. Does the message reappear?
(2) I have filed a defect regarding differences when using ByUser vs. using ByUserPostDefault . I used it to simplify attributes and some of the steps done in the default case were not done in the post-default case. This will be fixed in the next maintenance release and may be something having an effect on what you are seeing.
A workaround would be to use the class ByUserPostDefault to do stuff to the statechart. On the other hand I am not sure changing the existing statechart code makes much sense, since the result is plain code which is kind of hard to post-process.
Regarding C_CG.Configuration.ShowCgSimplifiedModelPackage : If enable this property and do a (re-) generate, you'll find the following structure in RiC's project browser: MyProject/CGSimplifiedModels/CGSimplifiedModelPackage . This package is what you are looking for. Without looking at it you won't be able to do a lot of simplification...
Mike
|
|
|
|
|
By accident I just found another property that will help you with changing statechart behavior radically: CG.Class.ImplementStatechart . Look at the property description in Rhapsody, it allows you to define your own statechart code.
Mike
|
|
|
|
|
Hi Mike,
just wanted to tell you, that last week I finally managed to adapt the statechart code according to my needs
Especially since you mentioned C_CG.Configuration.ShowCgSimplifiedModelPackage - this property really helps a lot...
So just wanted to thank you for your support!
by Michael
|
|
|
|
|
Hello Mike,
during working with CG, I have encountered following problem. Would be nice if you could post a short note whether you have seen that before or not:
When calling some methods from Rhapsody COM model, e.g. tempState.createNestedStatechart(); (where tempState is of datatype IRPState , I often (but not always) get following exception:
Kein Cache zum Verarbeiten vorhanden. (Exception from HRESULT: 0x80040006 (OLE_E_NOCACHE)) - the English translation would be something like
there's no cache for processing available . Therefore, a lot of my method calls cannot succeed and this is preventing me from doing the things that I intend to do
If you have ever encountered the same hResult and know how to overcome that, I'd greatly appreciate it.
Best regards,
Michael
|
|
|
|
|
Dear Mike,
Let me thanks you first for posting such a wonderful idea.
I tried this procedure to get the generated code from Rhapdody into C#. I am not understanding the "Building your own simplifier" steps clearly.
Can you please describe or give some exact snapshots of the procedure.
About me - I am working on Rhapsody in C, C++ and know UML concepts.
Regards,
Shridhar Dhomne
Shridhar Dhomne,
Honeywell Technology Solutions Lab, Bangalore.
(O): +91-80-26588360 Extn: 4211
|
|
|
|
|
Hey Shridhar,
let me first understand what exactly you are trying to do. As you know, Rhapsody is out of the box able to generate code for C, C++, Java and Ada. Please note that this article is not about generating C# code from a Rhapsody model.
Instead, it explains how Rhapsody internally executes a model transformation from general UML to more C-like modeling concepts and how you can change this transformation, e.g. to implement new modeling features. An example could be to provide stereotypes for a high-level web-service and implement a transformation mapping this concept to the functions and structures availble in C.
The article explains how to build such a custom transformation in C# by deriving from the base class I provided.
Does that meet your needs?
Best,
Mike
|
|
|
|
|
Dear Mike,
Yes i understood it wrongly. I thought your idea is useful for creating c# code from Rhapsody by providing some interface.
Actually i am looking for the code generation based on Stereotypes.
e.g. in rhapsody if i select Singleton as stereotype for some class, it is not generating the exact code for singleton class like private constructor and a handler to get the object instance.
Can your idea will be useful in this case, like if i select the stereotype i can get the exact code which will give the stereotype meaning.
Regards,
Shridhar
|
|
|
|
|
Hi Shridhar,
you are tackling quite a few topics here...
One more question from my end: are you talking about Rhapsody in C? Because the ways to customize code generation are currently limited to the C and Ada versions of Rhapsody. As of today - AFAIK - yuo cannot yet modify which C++ or Java code is generated.
Assuming you are talking about Rhapsody in C, then please note that the <<Singleton>> stereotype must be applied to an object (not a class) to result in correct code generation (no Create/Destroy, just initialization methods are created).
Finally, the RiC code generator has the two generation steps I described in the article: simplification (a model-to-model transformation) and actual file generation (a model-to-text transformation).
What you describe, to specify a new or existing stereotype and generate specific code for it is possible with both approaches and depends on what you want to do for the stereotype. Typically it makes the most sense to try realizing new modeling concepts in the simplification step, and yes, for that approach you can use my base class.
But again, that will work only in Rhapsody in C.
Finally, if you want to generate C# code, that is possible as well. While you can use the simplification step if required at all, you must implement your own C# ruleset for the model-to-text transformation as Rhapsody does not come with C# code generator templates.
Mike
|
|
|
|
|
Hello Mike,
I am very lucky to find your article.
I think you are familiar with Rhapsody tool, and I have some questions about this tool:
Rhapsody in C only generate ANSI C source, If I want to use these code in a special target,such as 8051, how to define the C51 keywords(as xdata,pdata,register,#pragma...)?
example: I want to generate following code, how to define in Rhapsody?
xdata int a;
int b;
pdata int c;
I do not know which step need change, in simplification step or rules-composer step?
In the end, should you recommend some forums about use Rhapsody tool, I am a beginner with UML and Rhapsody.
Thanks very much!
sunlemon
|
|
|
|
|