module y4d_aux.prioritycallback;
private import ytl.vector;

///	優先順位付き描画を実現する
/**
	実体は、delegateのvectorのvector。

	サンプル5bも参考にすること。
*/
class PriorityCallback {
public:

	///	コールバック
	alias void delegate(Object) CallBack;

	///	コールバックリスト
	alias vector!(CallBack) CallBackList;
	/*
		Objectとしては、Screenや描画コンテクスト等を渡す

		実装にvectorを用いているのは、clear～push_backでnewが発生
		しにくいように。
		（毎フレーム大量のnewが発生するとたまらんので。）
	*/

	///	コールバックリストの配列
	alias CallBackList[] CallBackListVector;

	///	使用するプライオリティの最大数を設定する
	/**
		setMax(4)とすれば、0～3のプライオリティが使えるようになる。
		最初に必ず設定する必要がある。
	*/
	void	setMax(int max_) {
		callbacklist = new CallBackList[max_];
		foreach(inout CallBackList l;callbacklist)
			l = new CallBackList;
	}

	/// コールバックに登録する
	/**
		プライオリティは 0 が一番高い。(画面上、一番手前に描画される)

		setMaxを呼び出していないのにこの関数が呼び出された場合は
		assertされる。エラーリザルトでも良いのだが、致命的だし、
		スプライトは何度もこの関数を呼び出して描画するので無駄なことを
		したくない。
	*/
	void	add(int nPriority,CallBack dg){
		assert(callbacklist);
		callbacklist[nPriority].push_back(dg);
	}

	///	コールバックする
	/**
		プライオリティは 0 が一番高い。(画面上、一番手前に描画される)
		ここで引数に渡したものは、コールバックのときに引数として渡される
<PRE>
		for(int i=callbacklist.length-1;i>=0;--i)
			foreach(CallBack f;callbacklist[i])
				f(o);
</PRE>
	*/
	void update(Object o){
		for(int i=callbacklist.length-1;i>=0;--i)
			foreach(CallBack f;callbacklist[i])
				f(o);
		//	これちゃんとforeach展開されるんやろか..(´Д｀)
	}

	///	addで登録されているコールバックをクリアする
	void clear() {
		foreach(inout CallBackList l;callbacklist) l.clear();
	}

private:
	CallBackListVector callbacklist;
}

