Glulx Input Loops

version 1/101121 by Erik Temple

  • Home page
  • Beginning
  • Previous
  • Next



  • Chapter - Input loops

    To decide whether a primary loop is in progress:
        if the reading a command activity is going on, decide yes;
        if the input looping activity is going on, decide yes.

    Input looping something is an activity on objects.

    To process/invoke/initiate (loop - an input-loop) loop/--:
        if loop is main input:
            say "***Warning: Attempted to invoke the 'main input' loop from source text. This is not allowed. While we can refer to and change the parameters of the main input loop, only the Inform library can specify when it is to run. The main input loop is the Inform 6 routine VM_ReadKeyboard(), and is intimately embedded in other library routines, so it would not make sense to invoke it separately.";
            rule fails;
        now the current input loop is the loop;
        if a primary loop is in progress:
            #if utilizing input loop debugging;
            if the stored loop context of the loop is g-primary, say "[line break]-->Note: The input loop [italic type][loop][roman type] is defined as a primary input loop, but it is being run as a secondary one. That is, it is being run while another input loop is already running. [currently running input loops][line break]";
            #end if;
            now loop context of loop is g-secondary;
        otherwise:
            #if utilizing input loop debugging;
            if the stored loop context of the loop is g-secondary, say "[line break]-->Note: The input loop [italic type][loop][roman type] is defined as a secondary input loop, but it is being run as a primary one. [currently running input loops][line break]";
            #end if;
            now loop context of loop is g-primary;
        #if utilizing input loop debugging;
        say "[line break]-->Starting the [italic type][loop][roman type] input loop as a [if loop context of loop is g-primary]primary[else]secondary[end if] loop.[line break]";
        #end if;
        begin the input looping activity with the loop;
        update the status line;
        if handling the input looping activity with the loop:
            let done be false;
            while done is false:
                follow the input loop setup rules for the focal event type of the loop;[input request, for example, can be put in the input loop setup rules.]
                if the focal event type of the loop is line-event:
                    now line event pending is true;
                #if utilizing input loop debugging;
                say "-->Input requested ([italic type][loop][roman type]); focal event type of loop is [focal event type of loop].[line break]";
                #end if;
                wait for glk input;
                now the current loop context is the loop context of the loop;
                #if utilizing input loop debugging;
                say "-->Input received: [current glk event]; consulting the input loop event-handling rules.[line break]";
                #end if;
                follow the input loop event-handling rules for the current glk event;
                now the current input loop is the loop;[Just in case we've invoked another loop in the input loop event-handling rules, we need to register that we've returned to this loop again.]
                let don't handle event be false;
                if the rule succeeded and the loop context of the loop is g-secondary:
                    now done is true;
                    now the current child loop is loop;
                    now delegate event handling to parent loop is true;
                otherwise:
                    if rule succeeded:
                        now done is true;
                    if the outcome of the rulebook is the delay input handling outcome:
                        now delegate event handling to parent loop is true;
                        let don't handle event be true;
                    if rule failed:
                        let don't handle event be true;
                if loop context of loop is g-primary and don't handle event is false:[We run HandleGlkEvent from here only if the loop is primary]
                    set JUMP POINT HandleGlkEvent;[a special jump point—the code will resume here if the JUMP TO line below is reached.]
                    #if utilizing input loop debugging;
                    if delegate event handling to parent loop is false, say "-->Consulting HandleGlkEvent from the primary loop [italic type][loop][roman type].[line break]";
                    #end if;
                    now delegate event handling to parent loop is false;
                    let event-outcome be glk event handled in (focal event type of the loop) context;
                    if delegate event handling to parent loop is true:[This will be true only for a secondary input loop that was run as the result of input that occurred during this loop's call to HandleGlkEvent.]
                        #if utilizing input loop debugging;
                        say "-->Consulting HandleGlkEvent from within the primary loop [italic type][loop][roman type] on behalf of the secondary loop [italic type][current child loop][roman type].[line break]";
                        #end if;
                        JUMP TO HandleGlkEvent;[Check HandleGlkEvent again, this time using the input from the secondary loop.]
                    if event-outcome is 2:[HandleGlkEvent has decided that the player's input is to be replaced]
                        now done is true;
                    if event-outcome is -1[HandleGlkEvent has decided that the input loop should continue, regardless of having received valid input]:
                        now done is false;[This will cancel any decision by the input loop event-handling rules that the loop should end.]
                    if the focal event type of the loop is line-event and line event pending is false:
                        follow the input loop setup rules for the focal event type of the loop;
                        now line event pending is true;
        end the input looping activity with the loop;
        #if utilizing input loop debugging;
        say "-->End [italic type][loop][roman type] input loop ([if loop context of loop is g-primary]primary[else]secondary[end if]).[line break]";
        #end if.