1  /*
     2   * Copyright the original author or authors.
     3   * 
     4   * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   * 
     8   *      http://www.mozilla.org/MPL/MPL-1.1.html
     9   * 
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  import org.as2lib.core.BasicClass;
    18  import org.as2lib.env.except.IllegalStateException;
    19  
    20  /**
    21   * {@code Stopwatch} stops the time.
    22   * 
    23   * <p>Instantiate this class as follows:
    24   * <code>
    25   *   import org.as2lib.util.StopWatch;
    26   *   var stopWatch:StopWatch = new StopWatch();
    27   * </code>
    28   * 
    29   * <p>This will create a still standing stopwatch. You can start and stop the 
    30   * stopwatch to record time as you please.
    31   * 
    32   * <code>
    33   *   stopWatch.start();
    34   *   // Do something
    35   *   stopWatch.stop();
    36   * </code>
    37   * 
    38   * <p>The recored time is available in milliseconds and seconds.
    39   * 
    40   * <code>
    41   *   trace(stopWatch.getTimeInMilliSeconds() + " ms");
    42   *   trace(stopWatch.getTimeInSeconds() + " s");
    43   * </code>
    44   * 
    45   * @author Martin Heidegger
    46   */
    47  class org.as2lib.util.StopWatch extends BasicClass {
    48  	
    49  	/** Starttime of the last start */
    50  	private var started:Boolean = false;
    51  	
    52  	/** Holder for all start-time-keys */
    53  	private var startTimeKeys:Array;
    54  	
    55  	/** Holder for all stop-time-keys */
    56  	private var stopTimeKeys:Array;
    57  	
    58  	/** Total recored run time. */
    59  	private var runTime:Number = 0;
    60  	
    61  	/** 
    62  	 * Constructs a new {@code StopWatch} instance.
    63  	 */
    64  	public function StopWatch(Void) {
    65  		reset();
    66  	}
    67  	
    68  	/**
    69  	 * Starts the time recording process.
    70  	 * 
    71  	 * @throws IllegalStateException if the stopwatch has already been started
    72  	 */
    73  	public function start(Void):Void {
    74  		if(hasStarted()) {
    75  			throw new IllegalStateException("Stopwatch is already started.", this, arguments);
    76  		}
    77  		started = true;
    78  		startTimeKeys.push(getTimer());
    79  	}
    80  	
    81  	/**
    82  	 * Stops the time recording process if the process has been started before.
    83  	 * 
    84  	 * @throws IllegalStateException if the stopwatch has not been already started
    85  	 */
    86  	public function stop(Void):Void {
    87  		if (!hasStarted()) {
    88  			throw new IllegalStateException("Stopwatch isn't started yet.", this, arguments);
    89  		}
    90  		var stopTime:Number = getTimer();
    91  		stopTimeKeys[startTimeKeys.length-1] = stopTime;
    92  		started = false;
    93  	}
    94  	
    95  	/**
    96  	 * Returns whether this stopwatch has been started.
    97  	 * 
    98  	 * @return {@code true} if this stopwatch has been started else {@code false}
    99  	 */
   100  	public function hasStarted(Void):Boolean {
   101  		return started;
   102  	}
   103  	
   104  	/**
   105  	 * Resets the stopwatch total running time.
   106  	 */
   107  	public function reset(Void):Void {
   108  		startTimeKeys = new Array();
   109  		stopTimeKeys = new Array();
   110  		started = false;
   111  	}
   112  	
   113  	/**
   114  	 * Calculates and returns the elapsed time in milliseconds.
   115  	 * 
   116  	 * <p>This stopwatch will not be stopped by calling this method. If this stopwatch
   117  	 * is still running it takes the current time as stoptime for the result.
   118  	 * 
   119  	 * @return the elapsed time in milliseconds
   120  	 * @see #getTimeInSeconds
   121  	 */
   122  	public function getTimeInMilliSeconds(Void):Number {
   123  		if (hasStarted()) {
   124  			stopTimeKeys[startTimeKeys.length-1] = getTimer();
   125  		}
   126  		var result:Number = 0;
   127  		for (var i:Number = 0; i < startTimeKeys.length; i++) {
   128  			result += (stopTimeKeys[i] - startTimeKeys[i]);
   129  		}
   130  		return result;		
   131  	}
   132  	
   133  	/**
   134  	 * Calculates and returns the elapsed time in seconds.
   135  	 * 
   136  	 * <p>This stopwatch will not be stopped by calling this method. If this stopwatch
   137  	 * is still running it takes the current time as stoptime for the result.
   138  	 * 
   139  	 * @return the elapsed time in seconds
   140  	 * @see #getTimeInMilliSeconds.
   141  	 */
   142  	public function getTimeInSeconds(Void):Number {
   143  		return getTimeInMilliSeconds()/1000;
   144  	}
   145  	
   146  	/**
   147  	 * Generates a string representation of this stopwatch that includes all start and
   148  	 * stop times in milliseconds.
   149  	 * 
   150  	 * @return the string representation of this stopwatch
   151  	 */
   152  	public function toString():String {
   153  		var result:String;
   154  		result = "\n------- [STOPWATCH] -------";
   155  		var i:Number;
   156  		for(i=0; i<startTimeKeys.length; i++) {
   157  			result += "\n started["+startTimeKeys[i]+"ms] stopped["+stopTimeKeys[i]+"ms]";
   158  		}
   159  		if(i==0) {
   160  			result += "\n never started.";
   161  		} else {
   162  			result += "\n\n total runnning time: "+getTimeInMilliSeconds()+"ms";
   163  		}
   164  		result += "\n---------------------------\n";
   165  		return result;
   166  	}
   167  	
   168  }