//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * タイマヘッダ
 * @author Junpee
 */

#ifndef Timer_H_
#define Timer_H_

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * タイマ
 *
 * 時間間隔を計測します。<br>
 * タイマを使用するためには、まずシステムの初期化時に Timer::initialize()を
 * 呼んでください。その後時間を計測したい処理の前で Timer::getTick()を呼び、
 * 計測したい処理の後で Timer::getInterval() を呼んでください。
 * <pre>
 * サンプルコード
 * 
 * // 初期化
 * Timer::initialize();
 * // 計測開始時間の取得
 * Timer::Tick startTime = Timer::getTick();
 * // 時間を計測する処理
 * targetMethod1();
 * // 時間間隔の取得
 * float msTime = Timer::getInterval(startTime);
 * // デバッグ出力に表示
 * DebugOut("targetMethod1() using %fms\n", msTime);
 * </pre>
 */
//------------------------------------------------------------------------------
class Timer{
public:
	/**
	 * Timer::getTick()を呼び出した時点での時間
	 *
	 * Timer::getInterval()により時間の間隔を取得できる。
	 * @see Timer
	 */
	class Tick{
		friend class Timer;
	public:
		/**
		 * コンストラクタ
		 */
		Tick(){ tick = 0; }

		/**
		 * 値の取得
		 * @return tickの下位32ビット値
		 */
		u_int getValue(){ return (u_int)(tick & 0xffffffff); }

	private:
		// 時間
		long long tick;

	};

	/**
	 * タイマを初期化します
	 *
	 * システムの初期化時に一度呼び出してください。
	 */
	static void initialize();

	/**
	 * 時間の取得
	 * @return getTick()を呼んだ時間。
	 * @see Tick
	 */
	static Tick getTick();

	/**
	 * 時間間隔の取得
	 *
	 * 以前に取得した時間からの時間間隔をミリ秒単位で取得します。
	 * @param previousTick 以前に取得した時間
	 * @return ミリ秒単位での時間間隔
	 */
	static float getInterval(const Tick& previousTick);

	/**
	 * 時間間隔の取得
	 *
	 * 以前に取得した時間から以後に取得した時間の時間間隔をミリ秒単位で取得します。
	 * @param previousTick 以前に取得した時間
	 * @param afterTick 以後に取得した時間
	 * @return ミリ秒単位での時間間隔
	 */
	static float getInterval(const Tick& previousTick, const Tick& afterTick);

private:
	// 1msあたりのクロック数
	static float tickPerMillisecond_;
	// 初期化済みフラグ
	static bool initialized_;
};

//------------------------------------------------------------------------------
} // End of namespace Lamp
#endif // End of Timer_H_
//------------------------------------------------------------------------------
