revised mainEventLoop

Here's my proposed revision to the main event loop.  Remember that enterStates has been modified so that it does not generate a Done event when we enter a top-level final state.  Therefore the main loop has to check for running = false after each transition.    Let me know what you think.  (The indentation looks ok in my email window, but may get messed up in transition, so you may need to do a bit of reconstruction.)


-          Jim

procedure mainEventLoop():
    while running:
        enabledTransitions = null
        macrostepDone = false
        # Here we handle eventless transitions and transitions
        # triggered by internal events until macrostep is complete
        while running and not macrostepDone:
            enabledTransitions = selectEventlessTransitions()
            if enabledTransitions.isEmpty():
                if internalQueue.isEmpty():
                    macrostepDone = true
                else:
                    internalEvent = internalQueue.dequeue()
                    datamodel["_event"] = internalEvent
                    enabledTransitions = selectTransitions(internalEvent)
            if not enabledTransitions.isEmpty():
                microstep(enabledTransitions.toList())
        # either we're in a final state, and we break out of the loop
        if not running:
            break;
        # or we've completed a macrostep, so we start a new macrostep by waiting for an external event
        # Here we invoke whatever needs to be invoked. The implementation of 'invoke' is platform-specific
        for state in statesToInvoke:
            for inv in state.invoke:
                invoke(inv)
        statesToInvoke.clear()
        # Invoking may have raised internal error events and we iterate to handle them
        if not internalQueue.isEmpty():
            continue
       # A blocking wait for an external event.  Alternatively, if we have been invoked
       # our parent session also might cancel us.  The mechanism for this is platform specific,
       # but here we assume it's a special event we receive
       externalEvent = externalQueue.dequeue()
       if isCancelEvent(externalEvent):
           running = false
           continue
       datamodel["_event"] = externalEvent
       for state in configuration:
           for inv in state.invoke:
              if inv.invokeid == externalEvent.invokeid:
                  applyFinalize(inv, externalEvent)
              if inv.autoforward:
                  send(inv.id, externalEvent)
       enabledTransitions = selectTransitions(externalEvent)
       if not enabledTransitions.isEmpty():
           microstep(enabledTransitions.toList())
    # End of outer while running loop.  If we get here, we have reached a top-level final state or have been cancelled
    exitInterpreter()

Received on Thursday, 21 February 2013 15:27:37 UTC