#pragma once

#include "refCTimer.h"

namespace FDK
{
	public ref class C一定間隔処理
	{
	public:
		C一定間隔処理()
		{
			this->Disposed = gcnew CDisposed();
			this->lockObject = gcnew Object();
			this->timer = gcnew CTimer( CTimer::E種別::MultiMedia );
			this->n前回の時刻 = CTimer::n未使用;
		}
		~C一定間隔処理()
		{
			if( this->Disposed->bDispose済みまたは処理中である )
				return;		// 例外は発出させない。

			if( !this->Disposed->t開始を宣言する() )
				return;		// 例外は発出させない。


			SAFE_REF_DELETE( this->timer );
			SAFE_REF_DELETE( this->lockObject );
			
			//GC::SuppressFinalize( this );   --> コンパイラが勝手にやる
		}

		delegate void dg処理();
		
		void t進行( Int64 n間隔ms, dg処理^ dg処理 )
		{
			this->Disposed->tDispose済みまたは実行中なら例外発生( "C一定間隔処理" );

			lock l( this->lockObject );

			
			// タイマ更新

			if( nullptr == this->timer )
				return;
			
			this->timer->t更新();


			// 初めての進行処理

			if( CTimer::n未使用 == this->n前回の時刻 )
				this->n前回の時刻 = this->timer->n現在時刻ms;


			// タイマが一回りしてしまった時のため……

			if( this->timer->n現在時刻ms < this->n前回の時刻 )
				this->n前回の時刻 = this->timer->n現在時刻ms;

	
			// 時間内の処理を実行。

			while( ( this->timer->n現在時刻ms - this->n前回の時刻 ) >= n間隔ms )
			{
				dg処理();

				this->n前回の時刻 += n間隔ms;
			}
		}

	protected:
		CTimer^ timer;
		Int64 n前回の時刻;
		Object^ lockObject;

	private:
		CDisposed^ Disposed;
	};
}
