Is State pattern the solution?

  • Thread starter Anders Eriksson
  • Start date
A

Anders Eriksson

I have a xml file that is a sequence. in this xml file there are
commands for a laser marking system.
Threre are two kinds of commands
MoveAxis
Document

MoveAxis is used to move the axis of the machine so that the item being
marked is under the laser.

Document is the layout file and it has to be executed(marked)

These command can be in any order and any number, but usually there is a
MoveAxis and then a Document, followed by a MoveAxis, etc

The moveAxis command is an async command so it will return directly.
When the axis has reached its position an ReachPosition event will be
triggered by the hardware.

The Document.execute is also an async command and will also return
directly. When the document has been marked an LaserEnd event will be
triggered by the hardware.

my problem is that I need to "wait" for each event before continuing
with the next command in the xml file.

I feel like this could be solved using a State Pattern or State Machine?
But I don't get how!
All samples are either so simple that I can't rework them for this or so
complicated that I don't understand them.

Is State Pattern/State Machine (are there any differences?) the way to
go or is there a more appropriate way of solving this problem?

// Anders
 
A

Anders Eriksson

Hello Peter,

The idea of a queue is really clever, which is probably why I hadn't
thought of it ;-)

All commands is performed in a COM Server, and as you guessed it only
has async functions.

I have tried, with your help, creating a sync wrapper using
lock(objWait)
{
Monitor.Wait(objWait);
}
when I have called the MoveAxis function and
lock (objWait)
{
Monitor.Pulse(objWait);
}
in the ReachPosition event.

This has worked perfectly, somehow it has stopped working!?
Now everything hangs after Monitor.Wait

Since I don't have the possibility to debug (I need a communication
card, which I don't have). I will go for the queue solution

Thank you very much for your help!

// Anders
[...]
These command can be in any order and any number, but usually there is a
MoveAxis and then a Document, followed by a MoveAxis, etc

The moveAxis command is an async command so it will return directly.
When the axis has reached its position an ReachPosition event will be
triggered by the hardware.

The Document.execute is also an async command and will also return
directly. When the document has been marked an LaserEnd event will be
triggered by the hardware.

my problem is that I need to "wait" for each event before continuing
with the next command in the xml file.

[...]
Is State Pattern/State Machine (are there any differences?) the way to
go or is there a more appropriate way of solving this problem?

The problem does not sound complicated enough to warrant worrying about
specific design patterns at all.

The real issue here (as I understand it) is that you apparently have an
API that provides only async methods, with no synchronous equivalents.
So basically, you need to turn those into synchronous methods.

It's not clear from your post where the events live relative to the
object on which you're calling the method to invoke a command. So I'll
gloss over that bit and not worry about it. I assume you can fill in the
details.

I think one of the easiest ways to address the issue would be to simply
have a queue of the commands. Make the Action delegate references if you
like, whatever…doesn't matter too much.

Then just subscribe to both events, and in the event handler, signal the
consumer of the queue to peek at the next command if present and invoke
it. When queuing a command, if the queue is empty, you can just invoke
the command immediately.

I suggested using peek to get the command; don't dequeue the command
until it's actually been completed. This gives you a way to know whether
a command is in progress when you queue a new one. If you'd prefer to
dequeue the command right away, then just keep a flag around that is set
when there's a command in progress, so you can tell when an empty queue
means you can actually invoke the command immediately or not.

Another way to approach this, of course, would be to just wrap the async
API in something that gives you a synchronous version. In that wrapper,
you'd have synchronous versions of your command methods, which when
called simply wait for the event to be raised signaling the completion
of the command, and only return to the caller when that event is raised.

The wrapper approach might be slightly less efficient, but it does have
the advantage of being a little simpler, and also of having a lower
memory footprint (because it doesn't have to maintain the queue, which
could get quite large if the latency on your hardware is much higher
than your file i/o and the list of commands is itself very large).

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top