# = Stop Watch # #-- # Ruby version 1.8 # # == Authors # * Yomei Komiya # # == Copyright # 2008 the original author or authors. # # == License # Apache License 2.0 # # Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #++ # == Version # SVN: $Id: stop_watch.rb 76 2008-10-12 11:45:33Z whitestar $ # # == Since # File available since Release 0.8.0 require 'commons/lang/state_error' require 'commons/lang/time/duration_format_utils' module Commons module Lang module Time # StopWatch # # Example: # require 'commons/lang/time/stop_watch' # # ... # stop_watch = Commons::Lang::Time::StopWatch.new # stop_watch.reset # stop_watch.start # # ... # stop_watch.stop # elapsed_time = stop_watch.get_time # 7 (milliseconds) # elapsed_time_str = stop_watch.to_s # 0:00:00.007 class StopWatch # running states STATE_UNSTARTED = 0 STATE_RUNNING = 1 STATE_STOPPED = 2 STATE_SUSPENDED = 3 # split states STATE_UNSPLIT = 10 STATE_SPLIT = 11 def initialize super() # The current running state of the StopWatch. @running_state = STATE_UNSTARTED # Whether the stopwatch has a split time recorded. @split_state = STATE_UNSPLIT # The start time. @start_time = nil # The stop time. @stop_time = nil end def start if @running_state == STATE_STOPPED raise StateError, 'Stopwatch must be reset before being restarted.' end if @running_state != STATE_UNSTARTED raise StateError, 'Stopwatch already started.' end @stop_time = nil @start_time = ::Time.now @running_state = STATE_RUNNING end def stop if @running_state != STATE_RUNNING && @running_state != STATE_SUSPENDED raise StateError, 'Stopwatch is not running.' end if @running_state == STATE_RUNNING @stop_time = ::Time.now end @running_state = STATE_STOPPED end def reset @running_state = STATE_UNSTARTED @split_state = STATE_UNSPLIT @start_time = nil @stop_time = nil end def split if @running_state != STATE_RUNNING raise StateError, 'Stopwatch is not running.' end @stop_time = ::Time.now @split_state = STATE_SPLIT end def unsplit if @split_state != STATE_SPLIT raise StateError, 'Stopwatch has not been split.' end @stop_time = nil @split_state = STATE_UNSPLIT end def suspend if @running_state != STATE_RUNNING raise StateError, 'Stopwatch must be running to suspend.' end @stop_time = ::Time.now @running_state = STATE_SUSPENDED end def resume if @running_state != STATE_SUSPENDED raise StateError, 'Stopwatch must be suspended to resume.' end @start_time = ::Time.at(@start_time.to_f + (::Time.now - @stop_time)) @stop_time = nil @running_state = STATE_RUNNING end # Gets the time in milliseconds def get_time if @running_state == STATE_STOPPED || @running_state == STATE_SUSPENDED return sec_to_millis(@stop_time - @start_time) elsif @running_state == STATE_UNSTARTED return 0 elsif @running_state == STATE_RUNNING return sec_to_millis(::Time.now - @start_time) end raise RuntimeError, 'Illegal running state has occured.' end # Gets the split time in milliseconds def get_split_time if @split_state != STATE_SPLIT raise StateError, 'Stopwatch must be split to get the split time.' end return sec_to_millis(@stop_time - @start_time) end def sec_to_millis(sec) return (sec * 1000).to_i end # Gets the start time (Time object). def get_start_time if @running_state == STATE_UNSTARTED raise StateError, 'Stopwatch has not been started' end return @start_time end def to_s return DurationFormatUtils.format_duration_hms(get_time) end def to_split_s return DurationFormatUtils.format_duration_hms(get_split_time) end end end end end