⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 telephone.rb

📁 SMC takes a state machine stored in a .sm file and generates a State pattern in twelve programming l
💻 RB
字号:
#!/usr/bin/env ruby# -*- 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) 2000 - 2003 Charles W. Rapp.# All Rights Reserved.## Contributor(s):#       Port to Ruby by Francois Perrad, francois.perrad@gadz.org## Name#  telephone.rb## Description#  A simulation of an old fashioned touch-tone telephone.## RCS ID# $Id: telephone.rb,v 1.1 2005/06/16 17:52:04 fperrad Exp $## CHANGE LOG# $Log: telephone.rb,v $# Revision 1.1  2005/06/16 17:52:04  fperrad# Added Ruby examples 1 - 4 and 7.##require 'time'require 'tk'require 'Telephone_sm'class Telephone	LONG_DISTANCE = 1	LOCAL = 2	EMERGENCY = 3	NYC_TEMP = 4	TIME = 5	DEPOSIT_MONEY = 6	LINE_BUSY = 7	INVALID_NUMBER = 8	SEC_PER_MINUTE = 60	def initialize(root)		@_root = root		@_areaCode = ""		@_exchange = ""		@_local = ""		@_display = ""		@_receiverButton = nil		@_timerMap = {				'ClockTimer'=> nil,				'OffHookTimer'=> nil,				'LoopTimer'=> nil,				'RingTimer'=> nil,		}		@_timerAudioID = nil		_loadUI		# Create the state machine to drive this object.		@_fsm = Telephone_sm::new(self)		# DEBUG		#@_fsm.setDebugFlag(true)	end	# Create the user interface but don't display it yet.	def _loadUI()		@_root.title("Telephone demo")		frameDisplay = TkFrame.new(@_root)		frameDisplay.pack(				'side' => 'top',				'fill' => 'both'		)		# Create the read-only phone number display.		@_numberDisplay = TkLabel.new(frameDisplay,			'width' => 30,			'bg' => 'white',			'relief' => 'sunken',			'padx' => 5,			'pady' => 5		)		@_numberDisplay.pack(			'side' => 'top',			'padx' => 5,			'pady' => 5		)		frameHook = TkFrame.new(@_root)		frameHook.pack(			'side' => 'top',			'expand' => 1		)		# Create the off-hook/on-hook button.		@_receiverButton = TkButton.new(frameHook,			'text' =>  "Pick up receiver",			'state' => 'normal',			'command' => proc {				text = @_receiverButton.cget('text')				if text == "Pick up receiver" then					@_fsm.OffHook				elsif text == "Put down receiver" then					@_fsm.OnHook				else					$stderr.printf("Unknown receiver (%s).\n", text)				end			},			'padx' => 10,			'pady' => 5,			'bd'	=>  3		)		@_receiverButton.pack(				'side' => 'top',				'padx' => 5,				'pady' => 5		)		frameDial = TkFrame.new(@_root)		frameDial.pack(			'side' => 'top',			'fill' => 'both',			'padx' => 5,			'pady' => 5		)		# Create the dialing buttons.		i = 0		"123456789*0#".split(//).each do |digit|			b = TkButton.new(frameDial,				'text' => digit,				'height' => 2,				'width' => 3,				'command' => proc { @_fsm.Digit(digit) }			)			b.grid(				'row' => i/3,				'column' => i%3,				'padx' => 1,				'pady' => 1			)			i += 1		end		frameStatus = TkFrame.new(@_root)		frameStatus.pack(			'side' => 'top',			'fill' => 'both'		)		@_soundDisplay = TkLabel.new(frameStatus,			'relief' => 'groove'		)		@_soundDisplay.pack(			'side' => 'top',			'fill' => 'x',			'expand' => 1,			'anchor' => 's'		)		# Cntl-C stops the demo as well.		@_root.bind('Control-c') { exit }	end	#-----------------------------------------------------------	# State Machine Actions.	#	# Return the current area code.	def getAreaCode()		return @_areaCode	end	# Return the exchange.	def getExchange()		return @_exchange	end	# Return the local number.	def getLocal()		return @_local	end	def routeCall(callType, areaCode, exchange, local)		if callType == EMERGENCY then			route = EMERGENCY		elsif (callType == LONG_DISTANCE and			areaCode == "1212" and			exchange == "555" and			local == "1234") then			route = NYC_TEMP		elsif exchange == "555" then			if local == "1212" then				route = TIME			else				route = LINE_BUSY			end		elsif callType == LOCAL then			route = DEPOSIT_MONEY		else			route = INVALID_NUMBER		end		# Call routing needs to be done asynchronouzly in order to		# avoid issuing a transition within a transition.		Tk.after(50, proc { _callRoute(route) } )	end	def startTimer(name, delay)		if name == "ClockTimer" then			@_timerMap[name] = TkAfter.new(delay, 1, proc { @_fsm.ClockTimer } )		elsif name == "OffHookTimer" then   			@_timerMap[name] = TkAfter.new(delay, 1, proc { @_fsm.OffHookTimer } )		elsif name == "LoopTimer" then			@_timerMap[name] = TkAfter.new(delay, 1, proc { @_fsm.LoopTimer } )		elsif name == "RingTimer" then			@_timerMap[name] = TkAfter.new(delay, 1, proc { @_fsm.RingTimer } )		end		@_timerMap[name].start	end	def resetTimer(name)		unless @_timerMap[name].nil? then			@_timerMap[name].restart		end	end	def stopTimer(name)		unless @_timerMap[name].nil? then			@_timerMap[name].cancel			@_timerMap[name] = nil		end	end	def play(name, delay)		unless @_timerAudioID.nil? then			@_timerAudioID.cancel			@_timerAudioID = nil		end		@_soundDisplay.configure('text' => name)		@_timerAudioID = TkAfter.new(delay, 1, proc {			@_soundDisplay.configure('text' => "")			@_timerAudioID = nil		} )		@_timerAudioID.start	end	def playTT(name)		play(name, 400)	end	def loop(name)		unless @_timerAudioID.nil? then			@_timerAudioID.cancel			@_timerAudioID = nil		end		@_soundDisplay.configure('text' => name + " ...")	end	def stopLoop(name)		@_soundDisplay.configure('text' => "")	end	def stopPlayback()		unless @_timerAudioID.nil? then			@_timerAudioID.cancel			@_timerAudioID = nil		end		@_soundDisplay.configure('text' => "")	end	def playEmergency()		play("911", 5000)	end	def playNYCTemp()		play("NYC_temp", 2000)	end	def playDepositMoney()		play("50_cents_please", 2000)	end	def playTime()		play("the_time_is ???", 2000)	end	def playInvalidNumber()		play("you_dialed ### could_not_be_completed", 2000)	end	def getType()		return @_callType	end	def setType(type)		@_callType = type	end	def saveAreaCode(n)		@_areaCode += n		addDisplay(n)	end	def saveExchange(n)		@_exchange += n		addDisplay(n)	end	def saveLocal(n)		@_local += n		addDisplay(n)	end	def addDisplay(character)		@_display += character		@_numberDisplay.configure('text' => @_display)	end	def clearDisplay()		#Clear the internal data store.		@_display = ""		@_areaCode = ""		@_local = ""		@_exchange = ""		# Put up the current time and date on the display.		@_numberDisplay.configure('text' => "")	end	def startClockTimer()		currentTime = Time::now.to_i		timeRemaining = SEC_PER_MINUTE - (currentTime % SEC_PER_MINUTE)		# Figure out how long until the top of the minute		# and set the timer for that amount.		startTimer("ClockTimer", timeRemaining * 1000)	end	def updateClock()		text = Time::now.localtime.strftime("%H:%M  %b %d, %Y")		@_numberDisplay.configure('text' => text)	end	def setReceiver(text)		@_receiverButton.configure('text' => text)	end	def _callRoute(route)		if route == EMERGENCY then			@_fsm.Emergency		elsif route == NYC_TEMP then			@_fsm.NYCTemp		elsif route == TIME then			@_fsm.Time		elsif route == DEPOSIT_MONEY then			@_fsm.DepositMoney		elsif route == LINE_BUSY then			@_fsm.LineBusy		elsif route == INVALID_NUMBER then			@_fsm.InvalidNumber		end	endend# Display the "telephone" user interface and run until# the user quits the window.root = TkRoot.newtel = Telephone.new(root)Tk.mainloop

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -