Jump to content

Use case for reflection


Recommended Posts

[This is a follow-up on my presentation TS 8237 "State Pattern Implementation for Scalable Control Systems" delivered at NI Week.]

Consider the following state machine:

post-6989-0-17582100-1344883614_thumb.pn.

Consider also an implementation of this using the State Pattern, where the different states are objects.

Now examine the desired behavior for exit and entry actions for the transitions D to E and D to F.

D to E: We expect to execute the exit method for D and the entry method for E (but not the entry or exit methods on the parents).

D to F: We expect to execute the exit methods for D and B and the entry methods for C and F (but not the entry and exit methods on A).

In other words, when executing exit and entry actions we want to stop at the least common ancestor (LCA) of the main source and main target states. [There is a good description of this here: http://www.amazon.co...&keywords=samek.]

It is possible to do this in an inelegant fashion by adding specific code for the purpose in various places, but I'm pretty sure the only elegant solution for this (i.e., within the framework) requires reflection (not yet available in LabVIEW).

Comments?

  • Like 1
Link to comment

I'm sorry I missed your session. It was one of the few I had inked into my schedule (as opposed to penciled.)

Hierarchical state machines (HSM) are the next step up in state machine models once you get used to flat state machines with entry, do, exit, and transition actions. I've implemented them on a limited scale... not enough to claim it's a good way to do it, but enough that the relatively simple requirements were satisfied. Unfortunately I don't remember the details at the moment nor do I have documentation or examples suitable for sharing with the community. I *think* my substates differed primarily in their do actions. I don't recall needing the exit and entry actions to execute in the same way you do. I'm travelling on Tuesday but I'll try to take another look at that code sometime this week.

Link to comment

I don't recall needing the exit and entry actions to execute in the same way you do.

Good news!

I found the relevant code and my substates do indeed have entry and exit actions.

Bad news!

My state is used to manage the UI, so it isn't designed to automatically jump from D to F in a single step like you do above. Each transition (D to B, B to A, A to C, and C to F) requires explicit user input each step of the way. I have some thoughts about potential paths to explore to find a solution to your problem, but they are just vague ideas right now. Separating the message handler classes from the state classes is the first thing that comes to mind...

As an aside, suppose you had an action assigned to the D to F transition. When is the right time for that action to execute? In a flat state machine it always executes after leaving the previous state and before entering the next state. Intuitively I would want to execute the transition action after exiting B and before entering C, but I make no claim that is the correct place for it to execute.

Link to comment

Background: We have implemented many hierarchical state machines of varying complexity using the State Pattern. This was the subject of my NI Week presentation, and the method we show is, I think, quite straightforward. The present implementations we have do not have explicit entry and exit methods defined on the states; we opted to defer consideration of this in favor of a very straightforward implementation in which we select the desired behaviors on each transition. This does, however, result in a certain amount of repetition on a few transitions, so in the process of preparing the presentation I looked more carefully into what it would take to implement entry and exit behaviors as explicit entry and exit methods on the states. I address this in the Advanced Topics of the presentation.

Daklu asked, "As an aside, suppose you had an action assigned to the D to F transition. When is the right time for that action to execute?"

I address this in my presentation. The UML Superstructure Specification states that the order should be:

  • Exit source state (lowest-to-highest)
  • Execute actions for transition
  • Enter target state (highest-to-lowest)

I had independently worked out a solution that differed from this somewhat, since we can group the first and third steps inside a single atomic transition method. Samek (see reference linked above--again, this has been a very helpful reference) suggests the following arrangement as more practical (pp. 78-81):

  • Execute actions for transition
  • Exit source state (lowest-to-highest)
  • Enter target state (highest-to-lowest),

where the latter two are in a single atomic method. (I think it doesn't matter much whether the first bullet occurs before or after the other two; it just matters that the exit and entry actions can be atomic.)

Anyway, the larger point I am trying to make in this thread is that determining the Least Common Ancestor of the main source and main target states is necessary for this (rather basic and quite valid) use case, and any elegant solution to find the LCA requires reflection.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.