Many people did it with a secondary list (attached with a secondary workflow). It works but is quite complex. My solution is different.
Let's say we need a state machine workflow as below:
|Previous State||Event||New State|
What we need to do is simple: store the "Previous State" and the "New State" in current list or form library, so we can figure out which event is fired. These "States" is changed by InfoPath form or Web form or other workflow attached with Tasks list.
This workflow needs to be triggered when the list data (or form data) is changed (or submitted), and it doesn't need to wait to collect any further user input. Below is an example.
It's not as intuitive as visual studio workflow diagram, but, it can be built without coding!