![]() |
Telelogic Rhapsody (steve huntington) | ![]() |
Topic Title: Condition connector Topic Summary: Created On: 17-Dec-2006 10:07 Status: Read Only |
Linear : Threading : Single : Branch |
![]() |
![]()
|
![]() |
|||
Hi,
I've just discovered that Rhapsody generates code for condition connectors in quite an unexpected (counter-intuitive?) way. For example, the attached statechart was intended to call the doSomething() method upon exit from the s1 state and then, depending on the return value, enter either s2 or s3. Here is the code that Rhapsody generated for this fragment: [CODE] if(ret==true) { popNullTransition(); //#[ transition ROOT.running.disable_adapter.ROOT.disable_adapter.free_rx_pool.0 ret=doSomething(); //#] free_rx_pool_subState = s2; rootState_active = s2; res = eventConsumed; } else { popNullTransition(); //#[ transition ROOT.running.disable_adapter.ROOT.disable_adapter.free_rx_pool.0 ret=doSomething(); //#] free_rx_pool_subState = s3; rootState_active = s3; res = eventConsumed; } [/CODE] This code checks the value of ret first and _then_ invokes doSomething()! In other words, Rhapsody assumes that the _incoming_ transition of the condition connector has no side effects. Could anyone advise if this is a bug or a restriction dictated by some important correctness concerns? And in the latter case, what would be an alternative way to express this statechart in Rhapsody? Thanks Leonid |
|||
![]() |
|||
![]() |
|||
Hi Leonid.
I believe that Rhapsody generates code as the statechart semantics in the UML dictates: First all guards are evaluated to find a way through and first then the actions are executed along that path. This is purely a dump of my own memory, so please correct me if I'm wrong ![]() A way to accomplish what you are trying to do, is to place a "dummy" state after your /ret = doSomething() transition and then use your current transitions on the other side of this dummy state, but of course without the doSomething action. There might be a more clever way to do it, but I don't see way it shouldn't work. Regards ------------------------- Jesper Gissel Johnson Controls Denmark, Marine Controls |
|||
![]() |
|||
![]() |
|||
Hi Jesper,
[QUOTE=jegissel@yorkref.com] I believe that Rhapsody generates code as the statechart semantics in the UML dictates: First all guards are evaluated to find a way through and first then the actions are executed along that path. This is purely a dump of my own memory, so please correct me if I'm wrong ![]() [/QUOTE] Thanks for pointing that out! You're right, a conditional pseudostate state is simply a shorthand for several transitions with the same trigger and different guards, which means that any triggered actions will only be executed after the guards are evaluated. [QUOTE=jegissel@yorkref.com] A way to accomplish what you are trying to do, is to place a "dummy" state after your /ret = doSomething() transition and then use your current transitions on the other side of this dummy state, but of course without the doSomething action. There might be a more clever way to do it, but I don't see way it shouldn't work. [/QUOTE] Or I could just replace the conditional pseudostate with a real state. However, I wanted to avoid this for two reasons. First, I'd prefer not to clutter the statechart with additional states. Second, I'd like to avoid the performance impact of the additional state. Leonid |
|||
![]() |
|||
![]() |
|||
I believe that if you double click on the state that you're trying to leave, it has an area to enter code upon exit of that state. So if I were you, I'd just put the doSomething code there, which guarantees that it'll run before you check the conditionals.
|
|||
![]() |
|||
![]() |
|||
You could use the doSomething() call as the guard on the transition into S2, and leave the 'else' guard into S3 as is. This will force the call to doSomething() as part of the condition evaluation process. Trying to call doSomething() as an exit action on S1 won't work because it's the condition evaluation process that determines whether or not you should leave the state in the first place.
|
|||
![]() |
|||
![]() |
|||
[QUOTE=gary_ceely@agilent.com]You could use the doSomething() call as the guard on the transition into S2, and leave the 'else' guard into S3 as is. This will force the call to doSomething() as part of the condition evaluation process. Trying to call doSomething() as an exit action on S1 won't work because it's the condition evaluation process that determines whether or not you should leave the state in the first place.[/QUOTE]
Thanks, this is my current solution, but probably not a good one, as Rhapsody documentation does not recommend using guards that have side effects.
|
|||
![]() |
|||
![]() |
|||
[QUOTE=jan.diep@novatel.ca]I believe that if you double click on the state that you're trying to leave, it has an area to enter code upon exit of that state. So if I were you, I'd just put the doSomething code there, which guarantees that it'll run before you check the conditionals.[/QUOTE]
Thanks. This would work in some cases, but not for states that have several outgoing transitions labelled with different actions. |
|||
![]() |
Telelogic Rhapsody
» Rhapsody Category » Rhapsody
»
Condition connector
|
![]() |
FuseTalk Standard Edition v3.2 - © 1999-2009 FuseTalk Inc. All rights reserved.