OSDN Git Service

[Backup]NyARToolkit for Java
[nyartoolkit-and/nyartoolkit-and.git] / trunk / src / jp / nyatla / utils / NyObjectStack.java
1 /* \r
2  * PROJECT: NyARToolkit\r
3  * --------------------------------------------------------------------------------\r
4  * The NyARToolkit is Java version ARToolkit class library.\r
5  * Copyright (C)2008 R.Iizuka\r
6  *\r
7  * This program is free software; you can redistribute it and/or\r
8  * modify it under the terms of the GNU General Public License\r
9  * as published by the Free Software Foundation; either version 2\r
10  * of the License, or (at your option) any later version.\r
11  * \r
12  * This program is distributed in the hope that it will be useful,\r
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15  * GNU General Public License for more details.\r
16  * \r
17  * You should have received a copy of the GNU General Public License\r
18  * along with this framework; if not, write to the Free Software\r
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
20  * \r
21  * For further information please contact.\r
22  *      http://nyatla.jp/nyatoolkit/\r
23  *      <airmail(at)ebony.plala.or.jp>\r
24  * \r
25  */\r
26 package jp.nyatla.utils;\r
27 import java.lang.reflect.*;\r
28 import jp.nyatla.nyartoolkit.NyARException;\r
29 \r
30 \r
31 \r
32 \r
33 /**\r
34  * オンデマンド割り当てをするオブジェクト配列。\r
35  * 配列には実体を格納します。\r
36  */\r
37 public abstract class NyObjectStack<T>\r
38 {\r
39         private final static int ARRAY_APPEND_STEP = 64;\r
40 \r
41         protected final T[] _items;\r
42 \r
43         private int _allocated_size;\r
44 \r
45         protected int _length;\r
46 \r
47         /**\r
48          * 最大ARRAY_MAX個の動的割り当てバッファを準備する。\r
49          * \r
50          * @param i_array\r
51          * @param i_element_type\r
52          * JavaのGenedicsの制限突破\r
53          */\r
54         @SuppressWarnings("unchecked")\r
55         protected NyObjectStack(int i_length,Class<T> i_element_type)\r
56         {\r
57                 // ポインタだけははじめに確保しておく\r
58                 this._items = (T[])Array.newInstance(i_element_type, i_length);\r
59                 // アロケート済サイズと、使用中個数をリセット\r
60                 this._allocated_size = 0;\r
61                 this._length = 0;\r
62                 return;\r
63         }\r
64         protected abstract T createElement();\r
65         /**\r
66          * ポインタを1進めて、その要素を予約し、その要素へのポインタを返します。\r
67          * 特定型に依存させるときには、継承したクラスでこの関数をオーバーライドしてください。\r
68          */\r
69         public final T prePush() throws NyARException\r
70         {\r
71                 // 必要に応じてアロケート\r
72                 if (this._length >= this._allocated_size) {\r
73                         // 要求されたインデクスは範囲外\r
74                         if (this._length >= this._items.length) {\r
75                                 throw new NyARException();\r
76                         }\r
77                         // 追加アロケート範囲を計算\r
78                         int range = this._length + ARRAY_APPEND_STEP;\r
79                         if (range >= this._items.length) {\r
80                                 range = this._items.length;\r
81                         }\r
82                         // アロケート\r
83                         this.onReservRequest(this._allocated_size, range, this._items);\r
84                         this._allocated_size = range;\r
85                 }\r
86                 // 使用領域を+1して、予約した領域を返す。\r
87                 T ret = this._items[this._length];\r
88                 this._length++;\r
89                 return ret;\r
90         }\r
91         /** \r
92          * 見かけ上の要素数を1減らして、最後尾のアイテムを返します。\r
93          * @return\r
94          */\r
95         public final T pop() throws NyARException\r
96         {\r
97                 if(this._length<1){\r
98                         throw new NyARException();\r
99                 }\r
100                 this._length--;\r
101                 return this.getItem(this._length);\r
102         }\r
103         /**\r
104          * 0~i_number_of_item-1までの領域を予約します。\r
105          * 予約すると、見かけ上の要素数は0にリセットされます。\r
106          * @param i_number_of_reserv\r
107          */\r
108         final public void reserv(int i_number_of_item) throws NyARException\r
109         {\r
110                 // 必要に応じてアロケート\r
111                 if (i_number_of_item >= this._allocated_size) {\r
112                         // 要求されたインデクスは範囲外\r
113                         if (i_number_of_item >= this._items.length) {\r
114                                 throw new NyARException();\r
115                         }\r
116                         // 追加アロケート範囲を計算\r
117                         int range = i_number_of_item+ARRAY_APPEND_STEP;\r
118                         if (range >= this._items.length) {\r
119                                 range = this._items.length;\r
120                         }\r
121                         // アロケート\r
122                         this.onReservRequest(this._allocated_size, range, this._items);\r
123                         this._allocated_size = range;\r
124                 }\r
125                 //見かけ上の配列サイズを指定\r
126                 this._length=i_number_of_item;\r
127                 return;\r
128         }\r
129         /**\r
130          * 必要に応じて、この関数を継承先クラスで実装して下さい。\r
131          * i_bufferの配列の、i_start番目からi_end-1番目までの要素に、オブジェクトを割り当てて下さい。\r
132          * @param i_start\r
133          * @param i_end\r
134          * @param i_buffer\r
135          */     \r
136         final protected void onReservRequest(int i_start, int i_end, Object[] i_buffer)\r
137         {\r
138                 try {  \r
139                         for (int i = i_start; i < i_end; i++){\r
140                                 i_buffer[i] =createElement();\r
141                         }\r
142                 } catch(Exception e) {  \r
143                         e.printStackTrace();  \r
144                 }\r
145                 return;\r
146         }\r
147 \r
148 \r
149         /**\r
150          * 配列を返します。\r
151          * \r
152          * @return\r
153          */\r
154         public final T[] getArray()\r
155         {\r
156                 return this._items;\r
157         }\r
158         public final T getItem(int i_index)\r
159         {\r
160                 return this._items[i_index];\r
161         }\r
162         /**\r
163          * 配列の見かけ上の要素数を返却します。\r
164          * @return\r
165          */\r
166         public final int getLength()\r
167         {\r
168                 return this._length;\r
169         }\r
170         \r
171         /**\r
172          * 見かけ上の要素数をリセットします。\r
173          */\r
174         public final void clear()\r
175         {\r
176                 this._length = 0;\r
177         }\r
178 }\r