home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / Newton Platform Info / Newton 2.0 Sample Code / Endpoints / Altered States-2 / Altered States.text < prev    next >
Encoding:
Text File  |  1996-03-20  |  30.6 KB  |  924 lines  |  [TEXT/MPS ]

  1. // Text of project Altered States written on 3/20/96 at 1:02 PM
  2. // Beginning of file protoEvent
  3.  
  4. // Before Script for "_userproto000"
  5. //    Newton Developer Technical Support Sample Code
  6. //    protoEvent - An NTK Finite State Machine User Proto
  7. //    by Jim Schram, Newton Developer Technical Support
  8. //    Copyright ©1996 Apple Computer, Inc.  All rights reserved.
  9. //    
  10. //    You may incorporate this sample code into your applications without
  11. //    restriction.  This sample code has been provided "AS IS" and the
  12. //    responsibility for its operation is 100% yours.  You are not
  13. //    permitted to modify and redistribute the source as "DTS Sample Code."
  14. //    If you are going to re-distribute the source, we require that you
  15. //    make it clear in the source that the code was descended from
  16. //    Apple-provided sample code, but that you've made changes.
  17.  
  18.  
  19. _userproto000 :=
  20.     {viewBounds: {left: 8, top: 16, right: 96, bottom: 32}, _proto: @218};
  21.  
  22.  
  23. constant |layout_protoEvent| := _userproto000;
  24. // End of file protoEvent
  25. // Beginning of file protoState
  26.  
  27. // Before Script for "_userproto001"
  28. //    Newton Developer Technical Support Sample Code
  29. //    protoState - An NTK Finite State Machine User Proto
  30. //    by Jim Schram, Newton Developer Technical Support
  31. //    Copyright ©1996 Apple Computer, Inc.  All rights reserved.
  32. //    
  33. //    You may incorporate this sample code into your applications without
  34. //    restriction.  This sample code has been provided "AS IS" and the
  35. //    responsibility for its operation is 100% yours.  You are not
  36. //    permitted to modify and redistribute the source as "DTS Sample Code."
  37. //    If you are going to re-distribute the source, we require that you
  38. //    make it clear in the source that the code was descended from
  39. //    Apple-provided sample code, but that you've made changes.
  40.  
  41.  
  42. _userproto001 :=
  43.     {viewBounds: {left: 8, top: 16, right: 112, bottom: 56}, _proto: @473};
  44.  
  45.  
  46. constant |layout_protoState| := _userproto001;
  47. // End of file protoState
  48. // Beginning of file protoFSM
  49.  
  50. // Before Script for "_userproto002"
  51. //    Newton Developer Technical Support Sample Code
  52. //    protoFSM - An NTK Finite State Machine User Proto
  53. //    by Jim Schram, Newton Developer Technical Support
  54. //    Copyright ©1996 Apple Computer, Inc.  All rights reserved.
  55. //    
  56. //    You may incorporate this sample code into your applications without
  57. //    restriction.  This sample code has been provided "AS IS" and the
  58. //    responsibility for its operation is 100% yours.  You are not
  59. //    permitted to modify and redistribute the source as "DTS Sample Code."
  60. //    If you are going to re-distribute the source, we require that you
  61. //    make it clear in the source that the code was descended from
  62. //    Apple-provided sample code, but that you've made changes.
  63.  
  64. kFSMCleanUpFunc := func(fsmFrame)
  65. begin
  66.     local fsmSymbol, stateSymbol, eventSymbol, hasGenesisState;
  67.     
  68.     RemoveSlot(fsmFrame._proto, '_proto);
  69.     RemoveSlot(fsmFrame._proto, 'viewBounds);
  70.     RemoveSlot(fsmFrame, 'viewBounds);
  71.     
  72.     fsmFrame.fsm_private_states := {    };
  73.     
  74.     if not fsmSymbol := GetSlot(fsmFrame, 'declareSelf) then
  75.         begin
  76.             fsmSymbol := 'unknown;
  77.             print("A protoFSM implementation is unnamed (you forgot the declareSelf slot).");
  78.         end;
  79.     
  80.     if fsmFrame.stepChildren then
  81.         foreach stateFrame in fsmFrame.stepChildren do
  82.             begin
  83.                 RemoveSlot(stateFrame, '_proto);
  84.                 RemoveSlot(stateFrame, 'viewBounds);
  85.                 
  86.                 if not stateSymbol := GetSlot(stateFrame, 'declareSelf) then
  87.                     begin
  88.                         stateSymbol := 'unknown;
  89.                         print("A protoState in the '|" & fsmSymbol & "| protoFSM implementation is unnamed (you forgot the declareSelf slot).");
  90.                     end;
  91.                 if fsmFrame.fsm_private_states.(stateSymbol) then
  92.                     print("The '|" & stateSymbol & "| protoState in the '|" & fsmSymbol & "| protoFSM implementation already exists (duplicate declareSelf slot value).");
  93.                 else
  94.                     fsmFrame.fsm_private_states.(stateSymbol) := stateFrame;
  95.                 
  96.                 if stateFrame.stepChildren then
  97.                     foreach eventFrame in stateFrame.stepChildren do
  98.                         begin
  99.                             RemoveSlot(eventFrame, '_proto);
  100.                             RemoveSlot(eventFrame, 'viewBounds);
  101.                             
  102.                             if not eventSymbol := GetSlot(eventFrame, 'declareSelf) then
  103.                                 begin
  104.                                     eventSymbol := 'unknown;
  105.                                     print("A protoEvent in the '|" & stateSymbol & "| state of the '|" & fsmSymbol & "| protoFSM implementation is unnamed (you forgot the declareSelf slot).");
  106.                                 end;
  107.                             if stateFrame.(eventSymbol) then
  108.                                 print("The '|" & eventSymbol & "| protoEvent in the '|" & stateSymbol & "| protoState in the '|" & fsmSymbol & "| protoFSM implementation already exists (duplicate declareSelf slot value).");
  109.                             else
  110.                                 stateFrame.(eventSymbol) := eventFrame;
  111.                             
  112.                             RemoveSlot(eventFrame, 'declareSelf);
  113.                         end;
  114.                 
  115.                 RemoveSlot(stateFrame, 'declareSelf);
  116.                 RemoveSlot(stateFrame, 'stepChildren);
  117.                 
  118.                 hasGenesisState := hasGenesisState or stateSymbol = 'Genesis;
  119.             end;
  120.     
  121.     if not hasGenesisState then
  122.         print("The '|" & fsmSymbol & "| protoFSM implementation is missing the required '|Genesis| state.");
  123.     
  124.     if not kDebugOn then        // GoToState is a debug-only function!
  125.         begin
  126.             RemoveSlot(fsmFrame._proto, 'GoToState);
  127.             RemoveSlot(fsmFrame, 'GoToState);
  128.         end;
  129.     RemoveSlot(fsmFrame, 'stepChildren);
  130. end
  131.  
  132. _userproto002 :=
  133.     {viewBounds: {left: 8, top: 8, right: 128, bottom: 72},
  134.      DoEvent:
  135.        func(eventSymbol, paramArray)    // SELF can be anything that inherits to the finite state machine instance frame
  136.        begin
  137.            local x := fsm_private_context;
  138.            if not x then        // this catches the situation where the FSM is disposed before a pending delayed action/call/send executes
  139.                return;
  140.            
  141.            if kDebugOn then
  142.                if paramArray and PrimClassOf(paramArray) <> 'Array then
  143.                    Throw('|evt.ex.msg|, "protoFSM:DoEvent 2nd argument must be Nil or Array");
  144.            
  145.            x.pendingEventQueue:EnQueue(eventSymbol);
  146.            x.pendingParamsQueue:EnQueue(paramArray);
  147.            
  148.            if not x.busy then
  149.                begin
  150.                    x.busy := true;
  151.                    AddDelayedSend(x.fsm, 'DoEvent_Loop, nil, x.turtle);
  152.                end;
  153.            
  154.            nil;
  155.        end,
  156.      instantiate:
  157.        //    SELF is the finite state machine template frame, e.g.:
  158.        //
  159.        //    local fsm := GetLayout("myFSM"):Instantiate();
  160.        //
  161.        //    "myFSM" is assumed to be a layout based on protoFSM,
  162.        
  163.        func()
  164.        begin
  165.            local obj := {    _proto:                            self,
  166.                                fsm:                                nil,
  167.                                currentStateFrame:        nil,
  168.                                currentEventFrame:        nil,
  169.                                fsm_private_context:    {    fsm:                                nil,
  170.                                                                        turtle:                            1,
  171.                                                                        level:                            0,
  172.                                                                        busy:                            nil,
  173.                                                                        waitView:                        nil,
  174.                                                                        waitAborted:                nil,
  175.                                                                        pendingState:                'Genesis,
  176.                                                                        pendingEventQueue:        QueueTemplate:Instantiate(),
  177.                                                                        pendingParamsQueue:    QueueTemplate:Instantiate(),
  178.                                                                        currentState:                nil,
  179.                                                                        currentEvent:                nil,
  180.                                                                        currentParams:            nil,    },    };
  181.            obj.currentStateFrame := {    _proto:        obj.fsm_private_states.Genesis,
  182.                                                        _parent:    obj,    };
  183.            obj.fsm := obj.fsm_private_context.fsm := obj;
  184.        end,
  185.      dispose:
  186.        func()    // SELF is the finite state machine instance frame
  187.        begin
  188.            fsm_private_context.pendingEventQueue:Reset();
  189.            fsm_private_context.pendingParamsQueue:Reset();
  190.            foreach slot in fsm_private_context do fsm_private_context.slot := nil;
  191.            currentStateFrame := currentEventFrame := fsm_private_context := nil;        // guaranteed to return nil so that the caller can conveniently nil out the FSM container variable
  192.        end,
  193.      DoEvent_Loop:
  194.        func()    // SELF is the finite state machine instance frame
  195.        begin
  196.            local x := fsm_private_context;
  197.            if not x then        // this catches the situation where the FSM is disposed before a pending delayed action/call/send executes
  198.                return;
  199.            
  200.            local ok;
  201.            local pendingStateFrame;
  202.            
  203.            if x.pendingState then
  204.                if fsm_private_states.(x.pendingState) then
  205.                    if fsm_private_states.(x.pendingState).(x.pendingEventQueue:Peek()) then
  206.                        ok := true;
  207.                    else
  208.                        begin
  209.                            if kDebugOn then :?DebugFSM('UnknownEvent, x.pendingState, x.pendingEventQueue:Peek(), x.pendingParamsQueue:Peek());            // ignore if event not programmed
  210.                        end;
  211.                else
  212.                    begin
  213.                        if kDebugOn then :?DebugFSM('UnknownState, x.pendingState, x.pendingEventQueue:Peek(), x.pendingParamsQueue:Peek());            // error --> remain in current state
  214.                    end;
  215.            else
  216.                begin
  217.                    if kDebugOn then :?DebugFSM('NilState, x.pendingState, x.pendingEventQueue:Peek(), x.pendingParamsQueue:Peek());                    // machine halted
  218.                end;
  219.            
  220.            if not ok then
  221.                begin
  222.                    currentStateFrame := nil;
  223.                    currentEventFrame := nil;
  224.                    
  225.                    x.pendingEventQueue:DeQueue();        // there is a problem with this state or event
  226.                    x.pendingParamsQueue:DeQueue();        // so remove the offending pending queue elements
  227.                end;
  228.            else
  229.                begin
  230.                    x.currentState := x.pendingState;
  231.                    x.currentEvent := x.pendingEventQueue:DeQueue();
  232.                    x.currentParams := x.pendingParamsQueue:DeQueue();
  233.                    
  234.                    currentStateFrame :=    {    _proto:        fsm_private_states.(x.currentState),
  235.                                                            _parent:    self,    };
  236.                    
  237.                    currentEventFrame :=    {    _proto:        fsm_private_states.(x.currentState).(x.currentEvent),
  238.                                                            _parent:    currentStateFrame,    };
  239.                    
  240.                    if currentEventFrame.Action then
  241.                        begin
  242.                            if kDebugOn then :?TraceFSM('PreAction, x.currentState, x.currentEvent, x.currentParams);
  243.                            
  244.                            x.level := x.level + 1;
  245.                            try
  246.                                Perform(currentEventFrame, 'Action, x.currentParams);
  247.                            onexception |evt.ex| do
  248.                                begin
  249.                                    try
  250.                                        :?ExceptionHandler(CurrentException());
  251.                                    onexception |evt.ex| do
  252.                                        nil;
  253.                                end;
  254.                            x.level := x.level - 1;
  255.                            
  256.                            if kDebugOn then :?TraceFSM('PostAction, x.currentState, x.currentEvent, x.currentParams);
  257.                        end;
  258.                    
  259.                    if currentEventFrame.nextState exists then
  260.                        if not x.pendingState := currentEventFrame.nextState then
  261.                            if kDebugOn then :?DebugFSM('NilNextState, x.currentState, x.currentEvent, x.currentParams);        // machine halted
  262.                    
  263.                    if kDebugOn then :?TraceFSM('NextState, x.pendingState, x.pendingEventQueue:Peek(), x.pendingParamsQueue:Peek());
  264.                end;
  265.            
  266.            if x.waitView                                                // check for terminal state & exit waitView if necessary
  267.            and x.pendingState
  268.            and pendingStateFrame := fsm_private_states.(x.pendingState) then
  269.                if pendingStateFrame.terminal then
  270.                    begin
  271.                        x.pendingEventQueue:Reset();
  272.                        x.pendingParamsQueue:Reset();
  273.                        AddDelayedCall(    func()
  274.                                                    if x.waitView then
  275.                                                        x.waitView:Close(), nil, 1    );
  276.                    end;
  277.        
  278.            if x.pendingEventQueue:IsEmpty() then
  279.                x.busy := nil;
  280.            else
  281.                AddDelayedSend(self, 'DoEvent_Loop, nil, x.turtle);
  282.            
  283.            nil;
  284.        end,
  285.      SetSpeed:
  286.        func(newSpeed)        // SELF is the finite state machine instance frame
  287.        begin
  288.            fsm_private_context.turtle := newSpeed;
  289.        end,
  290.      IsBusy:
  291.        func()    // SELF is the finite state machine instance frame
  292.        begin
  293.            fsm_private_context.busy;
  294.        end,
  295.      GetSpeed:
  296.        func()    // SELF is the finite state machine instance frame
  297.        begin
  298.            fsm_private_context.turtle;
  299.        end,
  300.      GoToState:
  301.        // SELF is the finite state machine instance frame
  302.        // This function is for DEBUGGING USE ONLY ! ! !
  303.        // It is STRIPPED from the resulting package when kDebugOn = nil
  304.        
  305.        func(newState)
  306.        begin
  307.            local x := fsm_private_context;
  308.            
  309.            x.pendingState := newState;
  310.            x.pendingEventQueue:Reset();
  311.            x.pendingParamsQueue:Reset();
  312.            
  313.            nil;
  314.        end,
  315.      QueueTemplate:
  316.        {
  317.            Instantiate:            func()                                    // This is a very simple First-In-First-Out queue
  318.                                        {    _proto:        self,
  319.                                            queue:        [],    },
  320.            
  321.            Reset:                    func() SetLength(queue, 0),
  322.            
  323.            Peek:                    func() if Length(queue) > 0 then queue[0],        // else nil
  324.            
  325.            DeQueue:                func()
  326.                                        if Length(queue) > 0 then        // else nil
  327.                                            begin
  328.                                                local data := queue[0];
  329.                                                RemoveSlot(queue, 0);
  330.                                                data;
  331.                                            end,
  332.            
  333.            EnQueue:                func(data)
  334.                                        begin
  335.                                            AddArraySlot(queue, data);
  336.                                            nil;
  337.                                        end,
  338.            
  339.            GetQueueSize:        func() Length(queue),
  340.            
  341.            IsEmpty:                func() Length(queue) = 0,
  342.        },
  343.      ProtoClone:
  344.        func(object)
  345.        begin
  346.            local f := 
  347.                func native(obj)
  348.                begin
  349.                    if not IsFrame(obj) or IsFunction(obj) then
  350.                        Throw('|evt.ex.msg|, "ProtoClone only works with frames.");
  351.                    
  352.                    local new := {_proto: obj};
  353.                    foreach slot, value in obj do
  354.                        if IsFrame(value) and not IsFunction(value) then
  355.                            new.(slot) := call f with (value);
  356.                    new;
  357.                end;
  358.            
  359.            call f with (object);
  360.        end,
  361.      WaitForTerminal:
  362.        func(options)
  363.        begin
  364.            local x := fsm_private_context;
  365.            
  366.            if x.waitView
  367.            or x.level <> 0
  368.            or x.pendingEventQueue:IsEmpty() then
  369.                return;
  370.            
  371.            x.waitView := BuildContext(waitViewTemplate);
  372.            x.waitView:SetOwnerContext(x, options);
  373.            x.waitView:ModalDialog();
  374.            x.waitAborted;        // return the value of waitAborted (true = user aborted via the status slip, nil = FSM terminal state was reached normally)
  375.        end,
  376.      waitViewTemplate:
  377.        {    viewClass:                    clView,
  378.            viewFlags:                    vVisible,
  379.            viewFormat:                    vfNone,
  380.            viewBounds:                    {    left:            0,
  381.                                                    top:            0,
  382.                                                    right:        0,
  383.                                                    bottom:        0,    },
  384.            
  385.            statusView:                    nil,
  386.            statusViewOptions:        nil,
  387.             fsmContext:                    nil,
  388.             aborted:                        nil,
  389.             
  390.            SetOwnerContext:            func(owner, options)
  391.                                                begin
  392.                                                    self.statusView := nil;
  393.                                                    self.statusViewOptions := options;        // frame of options the caller of WaitForTerminal is passing us (e.g.  progress messages, etc.)
  394.                                                    self.fsmContext := owner;                // the fsm_private_context slot of the FSM
  395.                                                    self.aborted := nil;
  396.                                                end,
  397.            
  398.            viewIdleScript:                func()
  399.                                                begin
  400.                                                    statusView := BuildContext(statusViewTemplate);
  401.                                                    statusView:SetOwnerContext(self, statusViewOptions);
  402.                                                    statusView:ModalDialog();
  403.                                                    nil;
  404.                                                end,
  405.            
  406.            viewSetupDoneScript:    func()
  407.                                                begin
  408.                                                    inherited:?ViewSetupDoneScript();
  409.                                                    if not statusViewOptions then
  410.                                                        :SetUpIdle(2000);
  411.                                                    else if statusViewOptions.delayUntilStatusVisible then
  412.                                                        :SetUpIdle(if statusViewOptions.delayUntilStatusVisible <= 0 then 1 else statusViewOptions.delayUntilStatusVisible);
  413.                                                end,
  414.            
  415.            viewQuitScript:            func()
  416.                                                begin
  417.                                                    if statusView then
  418.                                                        statusView:Close();
  419.                                                    fsmContext.waitAborted := aborted;
  420.                                                    fsmContext.waitView := nil;
  421.                                                end,
  422.            
  423.            statusViewTemplate:        {    _proto:                                protoStatusTemplate,
  424.                                                    initialSetup:                        nil,
  425.                                                    waitView:                            nil,
  426.                                                    delayUntilAbortTimer:        nil,
  427.                                                    delayUntilAbortVisible:        nil,
  428.                                                    abortButtonText:                nil,
  429.                                                    
  430.                                                    viewIdleScript:                    func()
  431.                                                                                            begin
  432.                                                                                                inherited:?viewIdleScript();
  433.                                                                                                local contents :=    {    name:        'vBarber,
  434.                                                                                                                                values:        {    barber:        true,    },    };
  435.                                                                                                
  436.                                                                                                if delayUntilAbortVisible then
  437.                                                                                                    begin
  438.                                                                                                        delayUntilAbortTimer := delayUntilAbortTimer + 300;
  439.                                                                                                        if delayUntilAbortTimer > delayUntilAbortVisible then
  440.                                                                                                            begin
  441.                                                                                                                delayUntilAbortVisible := nil;
  442.                                                                                                                contents.values.primary := {    text:            abortButtonText,
  443.                                                                                                                                                            script:        func()
  444.                                                                                                                                                                            begin
  445.                                                                                                                                                                                waitView.aborted := true;
  446.                                                                                                                                                                                waitView:Close();
  447.                                                                                                                                                                            end,    };
  448.                                                                                                                base:ViewSet(contents);
  449.                                                                                                                return 300;
  450.                                                                                                            end;
  451.                                                                                                    end;
  452.                                                                                                
  453.                                                                                                base:UpdateIndicator(contents);
  454.                                                                                                300;
  455.                                                                                            end,
  456.                                                    
  457.                                                    viewSetupDoneScript:        func()
  458.                                                                                            begin
  459.                                                                                                inherited:?ViewSetupDoneScript();
  460.                                                                                                :SetUpIdle(100);
  461.                                                                                                self.delayUntilAbortTimer := 0;
  462.                                                                                            end,
  463.                                                    
  464.                                                    SetOwnerContext:                func(owner, options)
  465.                                                                                            begin
  466.                                                                                                self.waitView := owner;
  467.                                                                                                self.delayUntilAbortVisible := if options then options.delayUntilAbortVisible else 8000;
  468.                                                                                                self.abortButtonText := if options and options.abortButtonText then options.abortButtonText else "Abort";
  469.                                                                                                 self.initialSetup := {    name:        'vBarber, 
  470.                                                                                                                                values:        {    icon:                    ROM_routeUpdateBitmap,
  471.                                                                                                                                                    statusText:        if options then options.statusText else "Please wait...",
  472.                                                                                                                                                    titleText:            if options then options.titleText else nil,
  473.                                                                                                                                                    barber:                true,
  474.                                                                                                                                                    primary:            nil,
  475.                                                                                                                                                    closeBox:            nil,    },    };
  476.                                                                                             end,
  477.                                                },
  478.        },
  479.      ExceptionHandler:
  480.        func(exception)
  481.        begin
  482.            local x := fsm_private_context;
  483.            local message :=    if x then
  484.                                            "The following exception occured in event ("
  485.                                            & x.currentEvent
  486.                                            & ") of state ("
  487.                                            & x.currentState
  488.                                            & ") of finite state machine ("
  489.                                            & x.fsm.declareSelf
  490.                                            & "):  "
  491.                                        else
  492.                                            "The following exception occured:  ";
  493.            
  494.            local exceptionStr := "<unable to create string representation of exception frame>";
  495.            try
  496.                exceptionStr := :ObjectToString(exception);
  497.            onexception |evt.ex| do
  498.                nil;
  499.            
  500.            GetRoot():Notify(kNotifyAlert, kAppName, message & exceptionStr);
  501.            
  502.            print(message);
  503.            print(exception);
  504.            if GetGlobalVar('BreakOnThrows) then
  505.                BreakLoop();
  506.            
  507.            nil;
  508.        end,
  509.      ObjectToString:
  510.        // Converts almost any NewtonScript data type into a string representation.
  511.        // Does NOT handle recursive/self-referencing frames.
  512.        // Does NOT follow _proto & _parent pointers.
  513.        // Does NOT check for out-of-memory conditions, bad object refs, et cetera.
  514.        
  515.        func(obj)
  516.        begin
  517.            local separator := ", ";
  518.            local separatorLen := StrLen(separator);
  519.            
  520.            local p :=
  521.                func(s)
  522.                if EndsWith(s, separator) then
  523.                    StrMunger(s, StrLen(s) - separatorLen, nil, nil, 0, nil)
  524.                else
  525.                    s;
  526.            
  527.            local f :=
  528.                func(obj)
  529.                begin
  530.                    (    if IsFunction(obj) then
  531.                            "func(" & NumberStr(GetFunctionArgCount(obj)) & (if GetFunctionArgCount(obj) = 1 then " arg)" else " args)")
  532.                        
  533.                        else if IsFrame(obj) then
  534.                            begin
  535.                                local s := "{";
  536.                                foreach slot, item in obj do
  537.                                    s := s & SPrintObject(slot) & ": " & 
  538.                                        if slot = '_parent or slot = '_proto then
  539.                                            "<ignored>" & separator
  540.                                        else
  541.                                            call f with (item);
  542.                                call p with (s) & "}";
  543.                            end
  544.                        
  545.                        else if IsArray(obj) then
  546.                            begin
  547.                                local s := "[";
  548.                                foreach item in obj do
  549.                                    s := s & call f with (item);
  550.                                call p with (s) & "]";
  551.                            end
  552.                        
  553.                        else if IsString(obj) then
  554.                            $" & obj & $"
  555.                        
  556.                        else if IsSymbol(obj) then
  557.                            $' & obj
  558.                        
  559.                        else if IsNumber(obj) or IsInteger(obj) then
  560.                            NumberStr(obj)
  561.                        
  562.                        else if IsImmediate(obj) then
  563.                            if not obj then
  564.                                "nil"
  565.                            else if obj = true then
  566.                                "true"
  567.                            else
  568.                                SPrintObject(obj)
  569.                        
  570.                        else
  571.                            SPrintObject(obj)
  572.                    
  573.                    ) & separator;
  574.                end;
  575.            
  576.            call p with (call f with (obj));
  577.        end,
  578.      _proto: @218
  579.     };
  580.  
  581.  
  582. constant |layout_protoFSM| := _userproto002;
  583. // End of file protoFSM
  584. // Beginning of file ExampleFSM
  585.  
  586. // Before Script for "Example FSM"
  587. //    Newton Developer Technical Support Sample Code
  588. //    ExampleFSM - An NTK Finite State Machine User Proto Implementation
  589. //    by Jim Schram, Newton Developer Technical Support
  590. //    Copyright ©1996 Apple Computer, Inc.  All rights reserved.
  591. //    
  592. //    You may incorporate this sample code into your applications without
  593. //    restriction.  This sample code has been provided "AS IS" and the
  594. //    responsibility for its operation is 100% yours.  You are not
  595. //    permitted to modify and redistribute the source as "DTS Sample Code."
  596. //    If you are going to re-distribute the source, we require that you
  597. //    make it clear in the source that the code was descended from
  598. //    Apple-provided sample code, but that you've made changes.
  599.  
  600.  
  601. Example FSM :=
  602.     {viewBounds: {left: 8, top: 8, right: 152, bottom: 272},
  603.      DebugFSM:
  604.        // If this method is defined it will be called as an aid in debugging your finite state machine.
  605.        // 
  606.        // reason = one of 'UnknownState, 'UnknownEvent, 'NilState, 'NilNextState
  607.        // state = the current state symbol
  608.        // event = the current event symbol
  609.        // params = the parameter array for the event Action function
  610.        
  611.        func(reason, state, event, params)
  612.        begin
  613.            local s :=    "Reason = " & :ObjectToString(reason)
  614.                            & "\nState = " & :ObjectToString(state)
  615.                            & "\nEvent = " & :ObjectToString(event)
  616.                            & "\nParams = " & :ObjectToString(params);
  617.            
  618.            :MTrace(s);
  619.            print(SubstituteChars(s, "\n", "\t"));
  620.        end,
  621.      TraceFSM:
  622.        // If this method is defined it will be called as an aid in debugging your finite state machine.
  623.        // 
  624.        // when = one of 'PreAction, 'PostAction, 'NextState
  625.        // state = the current state symbol
  626.        // event = the current event symbol
  627.        // params = the parameter array for the event Action function
  628.        
  629.        func(when, state, event, params)
  630.        begin
  631.            local s :=    "When = " & :ObjectToString(when)
  632.                            & "\nState = " & :ObjectToString(state)
  633.                            & "\nEvent = " & :ObjectToString(event)
  634.                            & "\nParams = " & :ObjectToString(params);
  635.            
  636.            :MTrace(s);
  637.            print(SubstituteChars(s, "\n", "\t"));
  638.        end,
  639.      declareSelf: 'ExampleFSM,
  640.      ExceptionHandler:
  641.        func(exception)
  642.        begin
  643.            inherited:?ExceptionHandler(exception);        // Implement your own exception handler here, or use the cheesy default one provided by protoFSM.
  644.        end,
  645.      MTrace:
  646.        func(s)
  647.        begin
  648.            SetValue(GetRoot().(kAppSymbol).vTraceBox, 'text, s);
  649.            RefreshViews();
  650.        end,
  651.      fTheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything: nil,
  652.      debug: "Example FSM",
  653.      _proto: _userproto002
  654.     };
  655.  
  656. Genesis :=
  657.     {declareSelf: 'Genesis,
  658.      viewBounds: {left: 8, top: 16, right: 136, bottom: 56},
  659.      terminal: true,
  660.      debug: "Genesis",
  661.      _proto: _userproto001
  662.     };
  663. AddStepForm(Example FSM, Genesis);
  664.  
  665. Create :=
  666.     {viewBounds: {left: 8, top: 16, right: 120, bottom: 32},
  667.      nextState: 'StateStart,
  668.      declareSelf: 'Create,
  669.      Action:
  670.        func(answer)
  671.        begin
  672.            fTheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything := answer;
  673.            print(answer);
  674.        end,
  675.      debug: "Create",
  676.      _proto: _userproto000
  677.     };
  678. AddStepForm(Genesis, Create);
  679.  
  680.  
  681.  
  682.  
  683.  
  684. State Start :=
  685.     {viewBounds: {left: 8, top: 64, right: 136, bottom: 128},
  686.      declareSelf: 'StateStart,
  687.      debug: "State Start",
  688.      _proto: _userproto001
  689.     };
  690. AddStepForm(Example FSM, State Start);
  691.  
  692. Event 1 Action 1 :=
  693.     {viewBounds: {left: 8, top: 16, right: 120, bottom: 32},
  694.      Action:
  695.        func()
  696.        begin
  697.            :DoEvent('Event2, nil);
  698.        end,
  699.      nextState: 'State1,
  700.      declareSelf: 'Event1,
  701.      debug: "Event 1 Action 1",
  702.      _proto: _userproto000
  703.     };
  704. AddStepForm(State Start, Event 1 Action 1);
  705.  
  706.  
  707.  
  708. Event 2 Action 3 :=
  709.     {viewBounds: {left: 8, top: 40, right: 120, bottom: 56},
  710.      Action:
  711.        func()
  712.        begin
  713.            :DoEvent('Event1, nil);
  714.        end,
  715.      nextState: 'State2,
  716.      declareSelf: 'Event2,
  717.      debug: "Event 2 Action 3",
  718.      _proto: _userproto000
  719.     };
  720. AddStepForm(State Start, Event 2 Action 3);
  721.  
  722.  
  723.  
  724.  
  725.  
  726. State 1 :=
  727.     {viewBounds: {left: 8, top: 136, right: 136, bottom: 176},
  728.      declareSelf: 'State1,
  729.      debug: "State 1",
  730.      _proto: _userproto001
  731.     };
  732. AddStepForm(Example FSM, State 1);
  733.  
  734. Event 2 Action 2 :=
  735.     {viewBounds: {left: 8, top: 16, right: 120, bottom: 32},
  736.      nextState: 'StateEnd,
  737.      declareSelf: 'Event2,
  738.      Action:
  739.        func()
  740.        begin
  741.            // If there is nothing to do in an Action function, there's really no need to supply the slot.
  742.            // See "State 2 / Event 1 Action 4" for an example of this.
  743.        end,
  744.      debug: "Event 2 Action 2",
  745.      _proto: _userproto000
  746.     };
  747. AddStepForm(State 1, Event 2 Action 2);
  748.  
  749.  
  750.  
  751.  
  752.  
  753. State 2 :=
  754.     {viewBounds: {left: 8, top: 184, right: 136, bottom: 224},
  755.      declareSelf: 'State2,
  756.      debug: "State 2",
  757.      _proto: _userproto001
  758.     };
  759. AddStepForm(Example FSM, State 2);
  760.  
  761. Event 1 Action 4 :=
  762.     {viewBounds: {left: 8, top: 16, right: 120, bottom: 32},
  763.      nextState: 'StateEnd,
  764.      declareSelf: 'Event1,
  765.      debug: "Event 1 Action 4",
  766.      _proto: _userproto000
  767.     };
  768. AddStepForm(State 2, Event 1 Action 4);
  769.  
  770.  
  771.  
  772.  
  773.  
  774. State End :=
  775.     {viewBounds: {left: 8, top: 232, right: 136, bottom: 256},
  776.      declareSelf: 'StateEnd,
  777.      terminal: true,
  778.      debug: "State End",
  779.      _proto: _userproto001
  780.     };
  781. AddStepForm(Example FSM, State End);
  782.  
  783.  
  784.  
  785. // After Script for "Example FSM"
  786. thisView := Example FSM;
  787. call kFSMCleanUpFunc with (thisView);
  788.  
  789.  
  790. constant |layout_ExampleFSM| := Example FSM;
  791. // End of file ExampleFSM
  792. // Beginning of file Main.t
  793.  
  794. // Before Script for "Example FSM"
  795. //    Newton Developer Technical Support Sample Code
  796. //    Maint.t - An NTK Finite State Machine Example Implementation
  797. //    by Jim Schram, Newton Developer Technical Support
  798. //    Copyright ©1996 Apple Computer, Inc.  All rights reserved.
  799. //    
  800. //    You may incorporate this sample code into your applications without
  801. //    restriction.  This sample code has been provided "AS IS" and the
  802. //    responsibility for its operation is 100% yours.  You are not
  803. //    permitted to modify and redistribute the source as "DTS Sample Code."
  804. //    If you are going to re-distribute the source, we require that you
  805. //    make it clear in the source that the code was descended from
  806. //    Apple-provided sample code, but that you've made changes.
  807.  
  808.  
  809. Example FSM :=
  810.     {title: kAppName,
  811.      viewBounds: {left: 0, top: 10, right: 219, bottom: 205},
  812.      viewFormat: 83952209,
  813.      viewSetupDoneScript:
  814.        func()
  815.        begin
  816.            :ResetFSM();
  817.        end,
  818.      FSM: nil,
  819.      viewQuitScript:
  820.        // must return the value of inherited:?viewQuitScript();
  821.        func()
  822.        begin
  823.            FSM := FSM:Dispose();
  824.            inherited:?viewQuitScript();        // this method is defined internally
  825.        end,
  826.      ResetFSM:
  827.        func()
  828.        begin
  829.            if FSM then
  830.                FSM := FSM:Dispose();
  831.            FSM := GetLayout("ExampleFSM"):Instantiate();
  832.            FSM:DoEvent('Create, ["The answer to the ultimate question of life the universe and everything is 42."]);
  833.        end,
  834.      reorienttoscreen: ROM_DefRotateFunc,
  835.      viewSetupFormScript:
  836.        func()
  837.        begin
  838.            // resize to fit on all "small" newtons.
  839.            constant kMaxWidth := 240;
  840.            constant kMaxHeight := 336;
  841.            
  842.            local b := GetAppParams();
  843.            self.viewBounds := RelBounds(b.appAreaLeft, b.appAreaTop,
  844.                                                  MIN(b.appAreaWidth, kMaxWidth),
  845.                                                  MIN(b.appAreaHeight, kMaxHeight));
  846.        end,
  847.      debug: "Example FSM",
  848.      _proto: @157
  849.     };
  850.  
  851. Reset :=
  852.     {
  853.      buttonClickScript:
  854.        func()
  855.        begin
  856.            :ResetFSM();
  857.        end,
  858.      text: "Reset",
  859.      viewBounds: {left: 82, top: 26, right: 142, bottom: 46},
  860.      debug: "Reset",
  861.      _proto: @226
  862.     };
  863. AddStepForm(Example FSM, Reset);
  864.  
  865.  
  866.  
  867. Event 1 :=
  868.     {
  869.      buttonClickScript:
  870.        func()
  871.        begin
  872.            if FSM:IsBusy() then
  873.                GetRoot():Notify(kNotifyAlert, kAppName, "The state machine is busy.  Please try again later.");
  874.            else
  875.                FSM:DoEvent('Event1, nil);
  876.        end,
  877.      text: "Event 1",
  878.      viewBounds: {left: 34, top: 58, right: 102, bottom: 78},
  879.      debug: "Event 1",
  880.      _proto: @226
  881.     };
  882. AddStepForm(Example FSM, Event 1);
  883.  
  884.  
  885.  
  886. Event 2 :=
  887.     {
  888.      buttonClickScript:
  889.        func()
  890.        begin
  891.            if FSM:IsBusy() then
  892.                GetRoot():Notify(kNotifyAlert, kAppName, "The state machine is busy.  Please try again later.");
  893.            else
  894.                FSM:DoEvent('Event2, nil);
  895.        end,
  896.      text: "Event 2",
  897.      viewBounds: {left: 122, top: 58, right: 190, bottom: 78},
  898.      debug: "Event 2",
  899.      _proto: @226
  900.     };
  901. AddStepForm(Example FSM, Event 2);
  902.  
  903.  
  904.  
  905. vTraceBox :=
  906.     {text: "",
  907.      viewBounds: {left: 9, top: 89, right: 218, bottom: 170},
  908.      viewJustify: 0,
  909.      viewFont: simpleFont9,
  910.      debug: "vTraceBox",
  911.      _proto: @218
  912.     };
  913. AddStepForm(Example FSM, vTraceBox);
  914. StepDeclare(Example FSM, vTraceBox, 'vTraceBox);
  915.  
  916.  
  917.  
  918.  
  919. constant |layout_Main.t| := Example FSM;
  920. // End of file Main.t
  921.  
  922.  
  923.  
  924.