home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-08 | 15.8 KB | 466 lines | [TEXT/MPS ] |
-
- // ---- End Project Data ----
-
-
- // ---- File IRTimeSync.t ----
-
- // Before Script for "vIRTimeSync"
- // ===========================================================================================
- // IRTimeSync
- //
- // Copyright © 1994 Apple Computer, Inc.
- // All rights reserved.
- //
- // Modification Status
- // YY/MM/DD Name Comments
- // 94/05/20 Jim Schram Initial Development during World Wide Developers Conference
- // 94/05/25 Jim Schram Released as |IRTimeSync:PIEDTS| version 2 sample code
- // -------------------------------------------------------------------------------------------------------------
- // NOTE: Time synchronization is accurate +/- one second and currently does not account for beam time.
- // ===========================================================================================
-
- constant kDebugShowPhases := nil; // true to show phase codes in vTitle area
- constant kIdleFrequency := 135; // number of milliseconds between idles
- constant kTimeoutTicks := 900; // number of ticks to wait before timing out a connection
-
- constant kPhase_Idle := 0; // phase codes for the vTimeMachine state machine
- constant kPhase_CountDown := 1;
- constant kPhase_Send := 2;
- constant kPhase_Connecting := 3;
- constant kPhase_Receive := 5;
- constant kPhase_Listening := 6;
- constant kPhase_Abort := 7;
- constant kPhase_AbortQuiet := 8;
- constant kPhase_Disconnect := 9;
- constant kPhase_Disconnecting := 10;
- constant kPhase_Disconnected := 11;
-
- // -------------------------------------------------------------------------------------------------------------
-
- constant kTitle := "Newton Time Synchronization Via IR Beam"; // title of the application
-
- constant kMessage_Send := "Looking for receiver..."; // progress/status messages
- constant kMessage_Receive := "Looking for sender...";
- constant kMessage_Stopping := "Stopping...";
- constant kMessage_Timeout := "No response.";
- constant kMessage_TimeHasBeenSet := "Time has been set.";
- constant kMessage_PortInUse := "IR port in use?";
- constant kMessage_GenericError := "An error occured!";
- DefConst('kMessage_BadTime, "Bad time value received." & unicodeCR & "Please try again.");
-
- DefConst('kMessage_CountDownFunc, // progress/status message constructor functions
- func(pendingSeconds)
- return "Time will be set in"
- && NumberStr(pendingSeconds)
- && if pendingSeconds = 1 then "second."
- else "seconds." & unicodeCR & "Please wait...");
-
- DefConst('kMessage_IdleFunc,
- func()
- begin
- local t := TimeInSeconds() mod 60;
- return DateNTime(Time()) & " and " & NumberStr(t) & if t = 1 then " second" else " seconds";
- end);
-
- constant kButton_Send := "Send Time"; // button names
- constant kButton_Receive := "Receive Time";
- constant kButton_Stop := "Stop";
-
- // -------------------------------------------------------------------------------------------------------------
-
- DefConst('kSysBeepSyncFunc, // replaces GetRoot():SysBeep() with a similar SYNCHRONOUS version
- func()
- if userConfiguration.beepSound <> 'none and userConfiguration.soundVolume > 0 then
- PlaySoundSync(ROM_soundoff.(userConfiguration.beepSound)));
-
- // -------------------------------------------------------------------------------------------------------------
-
- OpenResFile(HOME & "IRTimeSync.rsrc"); // load our attention sound (played when the time has been set)
- DefConst('kAlarmSound, GetSound11("IRTimeSyncAlarmSound")); // keep the size of this sample app down by using an 11Khz sample rate
- CloseResFile();
-
- // ===========================================================================================
-
-
- vIRTimeSync :=
- {
- viewSetupDoneScript:
- func()
- begin
- GetRoot().extrasDrawer:Close();
- :MSetPhase(nil);
- :SetUpIdle(135);
- end,
- viewQuitScript:
- func()
- begin
- if fEndPoint then
- fEndPoint:MDisconnect();
- end,
- viewFlags: 576,
- viewIdleScript:
- func()
- begin
- if kDebugShowPhases then begin
- local xT := NumberStr(TimeInSeconds() mod 60);
- local xPh := if fPhase then NumberStr(fPhase) else "NIL";
- local xCon := if fEndPoint and fEndPoint.fIsConnected then "TRUE" else "FALSE";
- local xSt := if fEndPoint then NumberStr(fEndPoint:State()) else "NIL";
- SetValue(vTitle, 'text, "T: " & xT & " Ph: " & xPh & " Con: " & xCon & " St: " & xSt );
- RefreshViews();
- end;
-
- if not fPhase or fPhase = kPhase_Idle then begin
- :MSetMessage(call kMessage_IdleFunc with ());
- end
-
- else if fPhase = kPhase_CountDown then begin
- local elapsedTime := Abs(timeinseconds() - fStartTime);
- local secondsToWait := 60 - fSeconds;
- if elapsedTime >= secondsToWait then begin
- SetTime(fMinutes + 1);
- :MSetMessage(kMessage_TimeHasBeenSet);
- PlaySound(kAlarmSound);
- fMinutes := nil;
- fSeconds := nil;
- :MSetPhase(kPhase_Disconnect);
- end
- else
- :MSetMessage(call kMessage_CountDownFunc with (secondsToWait - elapsedTime));
- end
-
- else if fPhase = kPhase_Send then begin
- fEndPoint := { _proto: fEndPointConfig,
- _parent: self };
- local err := fEndPoint:Instantiate(fEndPoint, nil);
- if err then begin
- :MSetError(kMessage_PortInUse, err);
- :MSetPhase(nil);
- end
- else begin
- vReceiveTime:Hide();
- SetValue(vSendTime, 'text, kButton_Stop);
- :MSetMessage(kMessage_Send);
- fEndPoint:MConnect();
- fTimeoutTicks := Ticks();
- :MSetPhase(kPhase_Connecting);
- end;
- end
-
- else if fPhase = kPhase_Connecting then begin
- if Abs(Ticks() - fTimeoutTicks) > kTimeoutTicks then begin
- :MSetMessage(kMessage_Timeout);
- call kSysBeepSyncFunc with ();
- call kSysBeepSyncFunc with ();
- :MSetPhase(kPhase_AbortQuiet);
- end
- else if fEndPoint.fIsConnected then begin
- fEndPoint:MSendTime();
- :MSetPhase(kPhase_Disconnect);
- end;
- end
-
- else if fPhase = kPhase_Disconnect then begin
- if fEndPoint then begin
- fEndPoint:MDisconnect();
- :MSetPhase(kPhase_Disconnecting);
- end
- else
- :MSetPhase(kPhase_Disconnected);
- end
-
- else if fPhase = kPhase_Disconnecting then begin
- end
-
- else if fPhase = kPhase_Disconnected then begin
- SetValue(vReceiveTime, 'text, kButton_Receive);
- SetValue(vSendTime, 'text, kButton_Send);
- vReceiveTime:Show();
- vSendTime:Show();
- :MSetPhase(nil);
- end
-
- else if fPhase = kPhase_Abort then begin
- :MSetMessage(kMessage_Stopping);
- :MSetPhase(kPhase_AbortQuiet);
- end
-
- else if fPhase = kPhase_AbortQuiet then begin
- :MSetPhase(kPhase_Disconnect);
- end
-
- else if fPhase = kPhase_Receive then begin
- fEndPoint := { _proto: fEndPointConfig,
- _parent: self };
- local err := fEndPoint:Instantiate(fEndPoint, nil);
- if err then begin
- :MSetError(kMessage_PortInUse, err);
- :MSetPhase(nil);
- end
- else begin
- vSendTime:Hide();
- SetValue(vReceiveTime, 'text, kButton_Stop);
- :MSetMessage(kMessage_Receive);
- fEndPoint:MListen();
- fTimeoutTicks := Ticks();
- :MSetPhase(kPhase_Listening);
- end;
- end
-
- else if fPhase = kPhase_Listening then begin
- if Abs(Ticks() - fTimeoutTicks) > kTimeoutTicks then begin
- :MSetMessage(kMessage_Timeout);
- call kSysBeepSyncFunc with ();
- call kSysBeepSyncFunc with ();
- :MSetPhase(kPhase_AbortQuiet);
- end
- else if fEndPoint.fIsConnected and fMinutes and fSeconds then begin
- if fMinutes > 0 and fSeconds >=0 and fSeconds <= 59 then
- :MSetPhase(kPhase_CountDown)
- else begin
- :MSetMessage(kMessage_BadTime);
- call kSysBeepSyncFunc with ();
- call kSysBeepSyncFunc with ();
- :MSetPhase(kPhase_AbortQuiet);
- end;
- end;
- end;
-
- return kIdleFrequency;
- end,
- fPhase: nil // holds the next phase to be executed for the idle machine,
- fEndPointConfig:
- {
- _proto: protoEndpoint,
-
- fIsConnected: nil,
-
- receiveFlags: kFrame,
-
- configOptions: [
- { label: kCMSSlowIR,
- type: 'service,
- opCode: opSetRequired, },
- ],
-
- exceptionHandler: func(exception) // deferred actions exception context is LAME -- the only action we dare take is to say we've handled the exception
- begin
- if HasSlot(exception, 'data)
- and exception.data <> nil
- and exception.data <> -16005 // cancelled (not really an error)
- and exception.data <> -16013 then begin // cancelled (not really an error)
- :MSetError(kMessage_GenericError, exception.data);
- call kSysBeepSyncFunc with ();
- call kSysBeepSyncFunc with ();
- call kSysBeepSyncFunc with ();
- if fPhase then
- if fPhase = kPhase_Connecting
- or fPhase = kPhase_Listening
- or fPhase = kPhase_CountDown then
- :MSetPhase(kPhase_Abort);
- end;
-
- return true;
- end,
-
- FReceiveTime: { inputForm: 'string, // data is a string of this format: IRTimeSyncVersion1X123456Y123456Z
- endCharacter: $Z,
- inputScript: func(ep, data)
- begin
- ep._parent.fStartTime := TimeInSeconds(); // note the time we received the beam
- ep:SetInputSpec(nil); // don't want to be retriggered
-
- ep._parent.fMinutes := 0;
- ep._parent.fSeconds := 0;
-
- local p1 := StrPos(data, "X", 0); // suck out the version info
- if p1 then begin
- if StrEqual(SubStr(data, 0, p1), "IRTimeSyncVersion1") then begin
- local p2 := StrPos(data, "Y", p1); // suck out the time in minutes (since midnight January 1, 1904)
- if p2 then begin
- local p3 := StrPos(data, "Z", p2); // suck out the time in seconds (0-59)
- if p3 then begin
- ep._parent.fMinutes := RintToL(StringToNumber(SubStr(data, p1 + 1, p2 - p1 - 1)));
- ep._parent.fSeconds := RintToL(StringToNumber(SubStr(data, p2 + 1, p3 - p2 - 1)));
- end;
- end;
- end
- else
- ep._parent:MSetError(kMessage_BadTime, -666);
- end;
- end, },
-
- MSendTime: func()
- begin
- local s := "IRTimeSyncVersion1X" // IR Time Sync Version ID
- & NumberStr(Time()) & "Y" // minutes since midnight January 1, 1904
- & NumberStr(TimeInSeconds() mod 60) & "Z"; // seconds past the minute (0-59)
- :Output(s, kFrame);
- :FlushOutput();
- end,
-
- MListen: func()
- begin
- fMinutes := nil;
- fSeconds := nil;
- AddDeferredAction( func(ep)
- begin
- ep.fIsConnected := ep:Listen(nil) = nil;
- if ep.fIsConnected then
- ep:SetInputSpec(ep.FReceiveTime);
- end,
- [self]);
- end,
-
- MConnect: func()
- begin
- AddDeferredAction( func(ep)
- begin
- ep.fIsConnected := ep:Connect(nil, nil) = nil;
- end,
- [self]);
- end,
-
- MDisconnect: func()
- begin
- self.nextInputSpec := nil;
- :SetInputSpec(nil);
- if fIsConnected and :State() = kDataXfer then
- :Release()
- else
- :Abort();
- AddDelayedAction(func(ep)
- begin
- if ep.fIsConnected then
- ep:Disconnect();
- ep:Dispose();
- ep._parent.fEndPoint := nil;
- if ep._parent.fPhase then
- ep._parent:MSetPhase(kPhase_Disconnected);
- end,
- [self], 666);
- end,
- },
- viewBounds: {left: 0, top: 0, right: 228, bottom: 110},
- _proto: protoFloater,
- MSetPhase:
- func(phase)
- begin
- fPhase := phase;
- end,
- fStartTime: 0,
- viewJustify: 80,
- fMinutes:
- nil // nil until we receive ANY value, 0 = illegal value, other = number of minutes since midnight January 1, 1904
- ,
- fEndPoint: nil,
- declareSelf: 'base,
- viewClickScript:
- func(unit)
- begin
- :Drag(unit, nil);
- end,
- debug: "vIRTimeSync",
- fTimeoutTicks: 0,
- MSetError:
- func(message, error)
- begin
- :MSetMessage(message & unicodeCR & NumberStr(error));
- call kSysBeepSyncFunc with ();
- end,
- fSeconds:
- nil // nil until we receive ANY value, 0 to 59 (inclusive) are legal values, other = illegal values
- ,
- MSetMessage:
- func(message)
- begin
- SetValue(vMessage, 'text, Clone(message));
- RefreshViews();
- end
- };
-
- vTitle := /* child of vIRTimeSync */
- {text: "",
- viewBounds: {left: 0, top: 4, right: 0, bottom: 20},
- viewJustify: 8388658,
- _proto: protoStaticText,
- debug: "vTitle"
- };
- // View vTitle is declared to vIRTimeSync
-
- // After Script for "vTitle"
- thisView := vTitle;
- thisView.text := kTitle;
-
-
-
- vMessage := /* child of vIRTimeSync */
- {text: "",
- viewBounds: {left: 16, top: 24, right: 208, bottom: 55},
- viewJustify: 2,
- viewFont: simpleFont9,
- _proto: protoStaticText,
- debug: "vMessage"
- };
- // View vMessage is declared to vIRTimeSync
-
-
-
- vReceiveTime := /* child of vIRTimeSync */
- {text: "",
- buttonClickScript:
- func()
- begin
- if not fPhase then
- :MSetPhase(kPhase_Receive)
-
- else if fPhase = kPhase_Listening or fPhase = kPhase_CountDown then
- :MSetPhase(kPhase_Abort);
- end,
- viewBounds: {left: 18, top: 57, right: 102, bottom: 77},
- _proto: protoTextButton,
- debug: "vReceiveTime"
- };
- // View vReceiveTime is declared to vIRTimeSync
-
- // After Script for "vReceiveTime"
- thisView := vReceiveTime;
- thisView.text := kButton_Receive;
-
-
-
- vSendTime := /* child of vIRTimeSync */
- {text: "",
- buttonClickScript:
- func()
- begin
- if not fPhase then
- :MSetPhase(kPhase_Send)
-
- else if fPhase = kPhase_Connecting then
- :MSetPhase(kPhase_Abort);
- end,
- viewBounds: {left: 122, top: 57, right: 206, bottom: 77},
- _proto: protoTextButton,
- debug: "vSendTime"
- };
- // View vSendTime is declared to vIRTimeSync
-
- // After Script for "vSendTime"
- thisView := vSendTime;
- thisView.text := kButton_Send;
-
-
-
- vStatusBar := /* child of vIRTimeSync */
- {_proto: protoStatus, debug: "vStatusBar"};
-
-
-
-
-
-
-
- // ---- Beginning of section for non used Layout files ----
-
- // End of output