OSDN Git Service

[NyARToolKit for java]update document
[nyartoolkit-and/nyartoolkit-and.git] / lib / src / jp / nyatla / nyartoolkit / core / utils / NyARManagedObjectPool.java
1 package jp.nyatla.nyartoolkit.core.utils;\r
2 \r
3 import java.lang.reflect.Array;\r
4 \r
5 import jp.nyatla.nyartoolkit.NyARException;\r
6 \r
7 \r
8 \r
9 /**\r
10  * このクラスは、参照カウンタ付きのObjectPoolの基本クラスです。\r
11  * {@link NyARManagedObject}から派生したオブジェクト型Tのオブジェクトプールを実現します。\r
12  * \r
13  * オブジェクトプールは、未割当リストを使って、オブジェクト要素を管理します。\r
14  * はじめ、全てのオブジェクト要素は未割当リストにあります。オブジェクト要素の生成要求があると、オブジェクトプール\r
15  * は未割当リストにあるオブジェクト要素の参照カウンタを1加算して、未割当リストから削除します。\r
16  * 逆に、オブジェクト要素の解放を要求があると、オブジェクト要素の参照カウンタを1減算して、その数が 0になったら、\r
17  * オブジェクト要素を未割当リストへ加えます。\r
18  * <br/>\r
19  * このクラスは、NyARManagedObjectと密接に関係して動作することに注意してください。\r
20  * 割り当て関数はオブジェクトプールの{@link NyARManagedObjectPool#newObject}、解放関数にはオブジェクト要素の\r
21  * {@link NyARManagedObject#releaseObject()}を使います。\r
22  * <br/>\r
23  * また、このクラスは{@link NyARManagedObject}に対して、特殊な関数を持つインタフェイスを提供します。\r
24  * このインタフェイスは、{@link NyARManagedObject}が{@link NyARManagedObjectPool}のリストを操作するために使います。\r
25  * <p>継承クラスの実装について - \r
26  * このクラスは、そのまま実体化できません。継承クラスを実装する必要があります。\r
27  * 実装するには、{@link #createElement}をオーバライドして、コンストラクタから{@link #initInstance}を呼び出します。\r
28  * {@link #initInstance}には2種類の関数があります。要素生成パラメータの有無で、どちらかを選択して呼び出してください。\r
29  * </p>\r
30  * \r
31  * @param <T>\r
32  */\r
33 public class NyARManagedObjectPool<T extends NyARManagedObject>\r
34 {\r
35         /**\r
36          * このクラスは、{@link NyARManagedObject}へ提供する操作インタフェイスの実体です。\r
37          * 未割当リストを操作する関数を定義します。\r
38          * Javaの都合でバッファを所有させていますが、別にこの形で実装しなくてもかまいません。\r
39          */\r
40         public class Operator implements NyARManagedObject.INyARManagedObjectPoolOperater\r
41         {\r
42                 /** 要素の実体の保管用リスト*/\r
43                 public NyARManagedObject[] _buffer;\r
44                 /** 未割当オブジェクトのリスト*/\r
45                 public NyARManagedObject[] _pool;\r
46                 public int _pool_stock;\r
47                 public void deleteObject(NyARManagedObject i_object)\r
48                 {\r
49                         assert(i_object!=null);\r
50                         assert(this._pool_stock<this._pool.length);\r
51                         this._pool[this._pool_stock]=i_object;\r
52                         this._pool_stock++;\r
53                 }\r
54         }\r
55         /**\r
56          * オブジェクト要素から参照する操作インタフェイス。ユーザが使用することはありません。\r
57          * <p>メモ - このスコープはprotectedではないか?</p>\r
58          */\r
59         public Operator _op_interface=new Operator();\r
60 \r
61         /**\r
62          * この関数は、新しいオブジェクトを1個割り当てて返します。\r
63          * @return\r
64          * 新しいオブジェクト。失敗した場合はnull\r
65          */\r
66         @SuppressWarnings("unchecked")\r
67         public T newObject() throws NyARException\r
68         {\r
69                 Operator pool=this._op_interface;\r
70                 if(pool._pool_stock<1){\r
71                         return null;\r
72                 }\r
73                 pool._pool_stock--;\r
74                 //参照オブジェクトを作成して返す。\r
75                 return (T)(pool._pool[pool._pool_stock].initObject());\r
76         }\r
77         /**\r
78          * コンストラクタです。\r
79          * 生成拒否の為に、コンストラクタを隠蔽します。\r
80          * 継承クラスを作成してください。\r
81          */\r
82         protected NyARManagedObjectPool()\r
83         {\r
84         }\r
85         /**\r
86          * この関数は、インスタンスを初期化します。\r
87          * 継承クラスのコンストラクタから呼び出します。\r
88          * {@link #initInstance(int, Class, Object)}との違いは、オブジェクトの生成に引数を渡すかどうかです。\r
89          * 引数が必要な時は、こちらの関数を使って、{@link #createElement()}をオーバライドします。\r
90          * @param i_length\r
91          * 配列の最大長さ\r
92          * @param i_element_type\r
93          * 配列型を示すクラスタイプ\r
94          * @throws NyARException\r
95          */\r
96         @SuppressWarnings("unchecked")\r
97         protected void initInstance(int i_length,Class<T> i_element_type) throws NyARException\r
98         {\r
99                 Operator pool=this._op_interface;\r
100                 //領域確保\r
101                 pool._buffer = (T[])Array.newInstance(i_element_type, i_length);\r
102                 pool._pool = (T[])Array.newInstance(i_element_type, i_length);\r
103                 //使用中個数をリセット\r
104                 pool._pool_stock=i_length;\r
105                 //オブジェクトを作成\r
106                 for(int i=pool._pool.length-1;i>=0;i--)\r
107                 {\r
108                         pool._buffer[i]=pool._pool[i]=createElement();\r
109                 }\r
110                 return;         \r
111         }\r
112         /**\r
113          * この関数は、インスタンスを初期化します。\r
114          * 継承クラスのコンストラクタから呼び出します。\r
115          * {@link #initInstance(int, Class)}との違いは、オブジェクトの生成に引数を渡すかどうかです。\r
116          * 引数が必要な時は、こちらの関数を使って、{@link #createElement(Object)}をオーバライドします。\r
117          * @param i_length\r
118          * 配列の最大長さ\r
119          * @param i_element_type\r
120          * 配列型を示すクラスタイプ\r
121          * @param i_param\r
122          * 配列要素を生成するときに渡すパラメータ\r
123          * @throws NyARException\r
124          */\r
125         @SuppressWarnings("unchecked")\r
126         protected void initInstance(int i_length,Class<T> i_element_type,Object i_param) throws NyARException\r
127         {\r
128                 Operator pool=this._op_interface;\r
129                 //領域確保\r
130                 pool._buffer = (T[])Array.newInstance(i_element_type, i_length);\r
131                 pool._pool = (T[])Array.newInstance(i_element_type, i_length);\r
132                 //使用中個数をリセット\r
133                 pool._pool_stock=i_length;\r
134                 //オブジェクトを作成\r
135                 for(int i=pool._pool.length-1;i>=0;i--)\r
136                 {\r
137                         pool._buffer[i]=pool._pool[i]=createElement(i_param);\r
138                 }\r
139                 return;         \r
140         }\r
141         /**\r
142          * この関数は、配列要素のオブジェクトを1個作ります。\r
143          * {@link #initInstance(int, Class)}から呼び出されます。\r
144          * 継承クラスでオーバライドして、要素オブジェクトを1個生成して返す処理を実装してください。\r
145          * @return\r
146          * 新しいオブジェクトを返してください。\r
147          * @throws NyARException\r
148          */\r
149         protected T createElement() throws NyARException\r
150         {\r
151                 throw new NyARException();\r
152         }\r
153         /**\r
154          * この関数は、配列要素のオブジェクトを(引数付きで)1個作ります。\r
155          * {@link #initInstance(int, Class, Object)}から呼び出されます。\r
156          * 継承クラスでオーバライドして、要素オブジェクトを1個生成して返す処理を実装してください。\r
157          * @return\r
158          * 新しいオブジェクトを返してください。\r
159          * @throws NyARException\r
160          */     \r
161         protected T createElement(Object i_param) throws NyARException\r
162         {\r
163                 throw new NyARException();\r
164         }\r
165 }\r