📄 telephone.sm
字号:
// -*- tab-width: 4; -*-%{//// The contents of this file are subject to the Mozilla Public// License Version 1.1 (the "License"); you may not use this file// except in compliance with the License. You may obtain a copy// of the License at http://www.mozilla.org/MPL/// // Software distributed under the License is distributed on an// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or// implied. See the License for the specific language governing// rights and limitations under the License.// // The Original Code is State Machine Compiler (SMC).// // The Initial Developer of the Original Code is Charles W. Rapp.// Portions created by Charles W. Rapp are// Copyright (C) 2007. Charles W. Rapp.// All Rights Reserved.// // Contributor(s): // Chris Liscio//// Name// Telephone.sm//// Description// Runs a plain old telphone. That means the proper sounds at// the proper time.//// RCS ID// $Id$//// CHANGE LOG// $Log$%}%class Telephone%start CallMap::OnHook%include "Telephone.h"%map CallMap%%OnHookEntry{ updateClock(); startClockTimer();}Exit{ stopTimer(@"ClockTimer");}{ // We are handling the caller's side of the connection. OffHook Dialing/push(PhoneNumber::DialTone) { clearDisplay(); setReceiver(@selector(onHookPressed:), @"Put down receiver"); } // Time to update the clock's display. ClockTimer nil { updateClock(); startClockTimer(); }}// The number is being dialed.Dialing{ // Dialing successfully completed. DialingDone(callType: int, areaCode: NSString*, exchange: NSString*, local: NSString*) Routing { routeCall(callType, areaCode, exchange, local); } // Dialing errors. LeftOffHook LeftOffHook {} InvalidDigit InvalidDigit {}}// The call is now being routed.Routing{ Emergency PlayingMessage { playEmergency(); } NYCTemp NYCTemp {} Time Time {} DepositMoney DepositMoney {} LineBusy BusySignal {} InvalidNumber PlayingMessage { playInvalidNumber(); }}NYCTempEntry{ loop(@"ring"); startTimer(@"RingTimer", 10000);}Exit{ stopTimer(@"RingTimer"); stopLoop(@"ring");}{ RingTimer PlayingMessage { playNYCTemp(); }}TimeEntry{ loop(@"ring"); startTimer(@"RingTimer", 10000);}Exit{ stopTimer(@"RingTimer"); stopLoop(@"ring");}{ RingTimer PlayingMessage { playTime(); }}DepositMoneyEntry{ loop(@"ring"); startTimer(@"RingTimer", 5000);}Exit{ stopTimer(@"RingTimer"); stopLoop(@"ring");}{ RingTimer PlayingMessage { playDepositMoney(); }}BusySignalEntry{ loop(@"busy_signal");}Exit{ stopLoop(@"busy_signal");}{ // Wait for on hook only.}PlayingMessage{ // If caller hangs up while a message is being played, // be sure to stop the playback. OnHook OnHook { stopPlayback(); setReceiver(@selector(offHookPressed:), @"Pick up receiver"); clearDisplay(); } PlaybackDone MessagePlayed {}}MessagePlayedEntry{ startTimer(@"OffHookTimer", 10000);}Exit{ stopTimer(@"OffHookTimer");}{ OffHookTimer LeftOffHook {}}//---------------------------------------------------------------// Error States.//// Let someone know the phone has been left off the hook.LeftOffHookEntry{ startTimer(@"LoopTimer", 10000); loop(@"phone_off_hook");}Exit{ stopTimer(@"LoopTimer"); stopLoop(@"phone_off_hook");}{ LoopTimer WaitForOnHook {} Default nil {}}InvalidDigitEntry{ startTimer(@"LoopTimer", 10000); loop(@"fast_busy_signal");}Exit{ stopTimer(@"LoopTimer"); stopLoop(@"fast_busy_signal");}{ LoopTimer WaitForOnHook {} Default nil {}}// Stay in this state until the telephone is on hook.WaitForOnHook{ Default nil {}}Default{ // Ignore any dialings after a phone number has been // collected. Digit(n : NSString*) nil {} DialingDone nil {} InvalidDigit nil {} // No matter when it happens, when the phone is hung // up, this call is OVER! OnHook OnHook { setReceiver(@selector(offHookPressed:), @"Pick up receiver"); clearDisplay(); } // Ignore the clock timer outside of the OnHook state. ClockTimer nil {}}%%// This map processes dialed digits. It either returns success// when %map PhoneNumber%%DialToneEntry{ loop(@"dialtone"); startTimer(@"OffHookTimer", 10000);}Exit{ stopTimer(@"OffHookTimer"); stopLoop(@"dialtone");}{ // If an invalid digit is dialed, give up collecting // digits immediately. Digit(n : NSString*) [[n intValue] < 0 || [n intValue] > 9] pop(InvalidDigit) { clearDisplay(); } // If the first digit is 1, then this is a long distance // phone call. Don't save this first digit. Digit(n : NSString*) [[n intValue] == 1] LongDistance { playTT(n); setType(LONG_DISTANCE); saveAreaCode(n); addDisplay(@"-"); } // Check for 911. Digit(n : NSString*) [[n intValue] == 9] OneOneStart { playTT(n); saveExchange(n); } Digit(n : NSString*) Exchange { playTT(n); setType(LOCAL); saveExchange(n); }}// Collect the area and then move on to the local number.LongDistanceEntry{ startTimer(@"OffHookTimer", 10000);}Exit{ stopTimer(@"OffHookTimer");}{ // If an invalid digit is dialed, give up collecting // digits immediately. Digit(n : NSString*) [[n intValue] < 0 || [n intValue] > 9] pop(InvalidDigit) { clearDisplay(); } Digit(n : NSString*) [[[ctxt areaCode] length] < 3] nil { playTT(n); saveAreaCode(n); resetTimer(@"OffHookTimer"); } Digit(n : NSString*) Exchange { playTT(n); saveAreaCode(n); addDisplay(@"-"); }}// Check if this is a 911 call.OneOneStartEntry{ startTimer(@"OffHookTimer", 10000);}Exit{ stopTimer(@"OffHookTimer");}{ // If an invalid digit is dialed, give up collecting // digits immediately. Digit(n : NSString*) [[n intValue] < 0 || [n intValue] > 9] pop(InvalidDigit) { clearDisplay(); } Digit(n : NSString*) [[n intValue] == 1] NineOne { playTT(n); saveExchange(n); } Digit(n : NSString*) Exchange { playTT(n); setType(LOCAL); saveExchange(n); }}// Almost there.NineOneEntry{ startTimer(@"OffHookTimer", 10000);}Exit{ stopTimer(@"OffHookTimer");}{ // If an invalid digit is dialed, give up collecting // digits immediately. Digit(n : NSString*) [[n intValue] < 0 || [n intValue] > 9] pop(InvalidDigit) { clearDisplay(); } Digit(n : NSString*) [[n intValue] == 1] pop(DialingDone, [ctxt type], [ctxt areaCode], [ctxt exchange], [ctxt local]) { playTT(n); setType(EMERGENCY); saveExchange(n); } Digit(n : NSString*) LocalCall { playTT(n); setType(LOCAL); saveExchange(n); addDisplay(@"-"); }}// Collect the three digit exchange.ExchangeEntry{ startTimer(@"OffHookTimer", 10000);}Exit{ stopTimer(@"OffHookTimer");}{ // If an invalid digit is dialed, give up collecting // digits immediately. Digit(n : NSString*) [[n intValue] < 0 || [n intValue] > 9] pop(InvalidDigit) { clearDisplay(); } Digit(n : NSString*) [[[ctxt exchange] length] < 2] nil { playTT(n); saveExchange(n); resetTimer(@"OffHookTimer"); } Digit(n : NSString*) LocalCall { playTT(n); saveExchange(n); addDisplay(@"-"); }}// Process a local call.LocalCallEntry{ startTimer(@"OffHookTimer", 10000);}Exit{ stopTimer(@"OffHookTimer");}{ // If an invalid digit is dialed, give up collecting // digits immediately. Digit(n : NSString*) [[n intValue] < 0 || [n intValue] > 9] pop(InvalidDigit) { clearDisplay(); } Digit(n : NSString*) [[[ctxt local] length] < 3] nil { playTT(n); saveLocal(n); resetTimer(@"OffHookTimer"); } Digit(n : NSString*) pop(DialingDone, [ctxt type], [ctxt areaCode], [ctxt exchange], [ctxt local]) { playTT(n); saveLocal(n); }}Default{ // Caller has stopped dialing and left the phone // off hook. OffHookTimer pop(LeftOffHook) { clearDisplay(); } // Pass this event up. OnHook pop(OnHook) { clearDisplay(); } InvalidDigit pop(InvalidDigit) { clearDisplay(); } // Ignore the clock timer outside of the OnHook state. ClockTimer nil {}}%%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -