--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.stack;\r
+import java.lang.reflect.*;\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+\r
+/**\r
+ * オンデマンド割り当てをするオブジェクト配列。\r
+ * 配列には実体を格納します。\r
+ */\r
+public abstract class NyObjectStack<T>\r
+{\r
+ private final static int ARRAY_APPEND_STEP = 64;\r
+\r
+ protected final T[] _items;\r
+\r
+ private int _allocated_size;\r
+\r
+ protected int _length;\r
+\r
+ /**\r
+ * 最大ARRAY_MAX個の動的割り当てバッファを準備する。\r
+ * \r
+ * @param i_array\r
+ * @param i_element_type\r
+ * JavaのGenedicsの制限突破\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ protected NyObjectStack(int i_length,Class<T> i_element_type)\r
+ {\r
+ // ポインタだけははじめに確保しておく\r
+ this._items = (T[])Array.newInstance(i_element_type, i_length);\r
+ // アロケート済サイズと、使用中個数をリセット\r
+ this._allocated_size = 0;\r
+ this._length = 0;\r
+ return;\r
+ }\r
+ protected abstract T createElement();\r
+ /**\r
+ * ポインタを1進めて、その要素を予約し、その要素へのポインタを返します。\r
+ * 特定型に依存させるときには、継承したクラスでこの関数をオーバーライドしてください。\r
+ */\r
+ public final T prePush() throws NyARException\r
+ {\r
+ // 必要に応じてアロケート\r
+ if (this._length >= this._allocated_size) {\r
+ // 要求されたインデクスは範囲外\r
+ if (this._length >= this._items.length) {\r
+ throw new NyARException();\r
+ }\r
+ // 追加アロケート範囲を計算\r
+ int range = this._length + ARRAY_APPEND_STEP;\r
+ if (range >= this._items.length) {\r
+ range = this._items.length;\r
+ }\r
+ // アロケート\r
+ this.onReservRequest(this._allocated_size, range, this._items);\r
+ this._allocated_size = range;\r
+ }\r
+ // 使用領域を+1して、予約した領域を返す。\r
+ T ret = this._items[this._length];\r
+ this._length++;\r
+ return ret;\r
+ }\r
+ /** \r
+ * 見かけ上の要素数を1減らして、最後尾のアイテムを返します。\r
+ * @return\r
+ */\r
+ public final T pop()\r
+ {\r
+ assert(this._length>=1);\r
+ this._length--;\r
+ return this._items[this._length];\r
+ }\r
+ /**\r
+ * 見かけ上の要素数をi_count個減らします。\r
+ * @param i_count\r
+ * @return\r
+ * NULLを返します。\r
+ */\r
+ public final void pops(int i_count)\r
+ {\r
+ assert(this._length>=i_count);\r
+ this._length-=i_count;\r
+ return;\r
+ } \r
+ \r
+ /**\r
+ * 0~i_number_of_item-1までの領域を予約します。\r
+ * 予約済の領域よりも小さい場合には、現在の長さを調整します。\r
+ * @param i_number_of_reserv\r
+ */\r
+ final public void reserv(int i_number_of_item) throws NyARException\r
+ {\r
+ // 必要に応じてアロケート\r
+ if (i_number_of_item >= this._allocated_size) {\r
+ // 要求されたインデクスは範囲外\r
+ if (i_number_of_item >= this._items.length) {\r
+ throw new NyARException();\r
+ }\r
+ // 追加アロケート範囲を計算\r
+ int range = i_number_of_item+ARRAY_APPEND_STEP;\r
+ if (range >= this._items.length) {\r
+ range = this._items.length;\r
+ }\r
+ // アロケート\r
+ this.onReservRequest(this._allocated_size, range, this._items);\r
+ this._allocated_size = range;\r
+ }\r
+ //見かけ上の配列サイズを指定\r
+ this._length=i_number_of_item;\r
+ return;\r
+ }\r
+ /**\r
+ * 必要に応じて、この関数を継承先クラスで実装して下さい。\r
+ * i_bufferの配列の、i_start番目からi_end-1番目までの要素に、オブジェクトを割り当てて下さい。\r
+ * @param i_start\r
+ * @param i_end\r
+ * @param i_buffer\r
+ */ \r
+ final protected void onReservRequest(int i_start, int i_end, Object[] i_buffer)\r
+ {\r
+ try { \r
+ for (int i = i_start; i < i_end; i++){\r
+ i_buffer[i] =createElement();\r
+ }\r
+ } catch(Exception e) { \r
+ e.printStackTrace(); \r
+ }\r
+ return;\r
+ }\r
+\r
+\r
+ /**\r
+ * 配列を返します。\r
+ * \r
+ * @return\r
+ */\r
+ public final T[] getArray()\r
+ {\r
+ return this._items;\r
+ }\r
+ public final T getItem(int i_index)\r
+ {\r
+ return this._items[i_index];\r
+ }\r
+ /**\r
+ * 配列の見かけ上の要素数を返却します。\r
+ * @return\r
+ */\r
+ public final int getLength()\r
+ {\r
+ return this._length;\r
+ }\r
+ /**\r
+ * 見かけ上の要素数をリセットします。\r
+ */\r
+ public final void clear()\r
+ {\r
+ this._length = 0;\r
+ }\r
+}\r