1 module armos.app.baseapp;
2 import armos.events;
3 import armos.math;
4 import armos.utils.keytype;
5 
6 /++
7 armosの中心となるクラスです.プロジェクトを作成する際はこのクラスを継承して処理を記述していきます.
8 +/
9 class BaseApp{
10     /++
11         事前処理を記述するメンバ関数です.initializerによる初期化が行われた後,一度だけ実行されます.
12     +/
13     void setup(ref EventArg arg){
14         setup();
15     }
16 
17     /++
18         毎フレーム実行されるメンバ関数です.
19     +/
20     void update(ref EventArg arg){
21         update();
22     }
23 
24     /++
25         毎フレーム実行されるメンバ関数です.updateの次に呼ばれます.描画処理を記述します.
26     +/
27     void draw(ref EventArg arg){
28         draw();
29     }
30 
31     /++
32         事前処理を記述するメンバ関数です.initializerによる初期化が行われた後,一度だけ実行されます.
33     +/
34     void setup(){};
35 
36     /++
37         毎フレーム実行されるメンバ関数です.
38     +/
39     void update(){};
40 
41     /++
42         毎フレーム実行されるメンバ関数です.updateの次に呼ばれます.描画処理を記述します.
43     +/
44     void draw(){};
45 
46 
47     /++
48         終了時に一度だけ呼ばれるメンバ関数です.
49     +/
50     void exit(ref EventArg arg){
51         exit();
52     };
53 
54     /++
55         終了時に一度だけ呼ばれるメンバ関数です.
56     +/
57     void exit(){};
58     
59     ///
60     void windowResized(ref WindowResizeEventArg message){
61         windowResized(message.w, message.h);
62         windowResized(Vector2i(message.w, message.h));
63         windowResized;
64     }
65     
66     ///
67     void windowResized(){}
68     
69     ///
70     void windowResized(int w, int h){}
71     
72     ///
73     void windowResized(Vector2i size){}
74 
75     /++
76         キーボードを押した際に呼ばれるメンバ関数です.
77         Params:
78         message = キーボードの状態が格納されたメッセージです.
79     +/
80     void keyPressed(ref KeyPressedEventArg message){
81         import std.conv;
82         keyPressed(message.key);
83     }
84     
85     /++
86         キーボードを押した際に呼ばれるメンバ関数です.
87         Params:
88         key = 押したキーの種類を表すarmos.utils.KeyTypeが格納されています.
89     +/
90     void keyPressed(KeyType key){}
91 
92     /++
93         キーボードを離した際に呼ばれるメンバ関数です.
94         Params:
95         message = キーボードの状態が格納されたメッセージです.
96     +/
97     void keyReleased(ref KeyReleasedEventArg message){
98         import std.conv;
99         keyReleased(message.key);
100     }
101     
102     /++
103         キーボードを離した際に呼ばれるメンバ関数です.
104         Params: 
105         key = 離したキーの種類を表すarmos.utils.KeyTypeが格納されています.
106     +/
107     void keyReleased(KeyType key){}
108     
109     ///
110     void unicodeInputted(ref UnicodeInputtedEventArg message){
111         unicodeInputted(message.key);
112     }
113     
114     ///
115     void unicodeInputted(uint key){}
116 
117     /++
118         マウス位置を表すプロパティです.
119     +/
120     int mouseX, mouseY;
121 
122     /++
123         マウスが動いた際に呼ばれるメンバ関数です.
124         Params:
125         message = マウスの状態が格納されたメッセージです.
126     +/
127     void mouseMoved(ref MouseMovedEventArg message){
128         mouseMoved(message.x, message.y, message.button );
129         mouseMoved(Vector2f(message.x, message.y), message.button);
130         mouseMoved(Vector2i(message.x, message.y), message.button);
131     }
132 
133     /++
134         マウスが動いた際に呼ばれるメンバ関数です.
135         Params:
136         x = マウスのX座標です.
137         y = マウスのY座標です.
138     +/
139     void mouseMoved(int x, int y, int button){}
140 
141     /++
142         マウスが動いた際に呼ばれるメンバ関数です.
143         Params:
144         position = マウスの座標を表します.
145     +/
146     void mouseMoved(Vector2f position, int button){}
147 
148     /++
149         マウスが動いた際に呼ばれるメンバ関数です.
150         Params:
151         position = マウスの座標を表します.
152     +/
153     void mouseMoved(Vector2i position, int button){}
154 
155     /++
156         マウスがドラッグされた際に呼ばれるメンバ関数です.
157         Deprecated: 現在動作しません.
158     +/
159     void mouseDragged(ref MouseDraggedEventArg message){
160         mouseDragged(message.x, message.y, message.button );
161         mouseDragged(Vector2f(message.x, message.y), message.button);
162         mouseDragged(Vector2i(message.x, message.y), message.button);
163     }
164 
165     /++
166         マウスがドラッグされた際に呼ばれるメンバ関数です.
167         Deprecated: 現在動作しません.
168     +/
169     void mouseDragged(int x, int y, int button){}
170 
171     /++
172         マウスがドラッグされた際に呼ばれるメンバ関数です.
173         Deprecated: 現在動作しません.
174     +/
175     void mouseDragged(Vector2f position, int button){}
176 
177     /++
178         マウスがドラッグされた際に呼ばれるメンバ関数です.
179         Deprecated: 現在動作しません.
180     +/
181     void mouseDragged(Vector2i position, int button){}
182 
183 
184     /++
185         マウスのボタンが離れた際に呼ばれるメンバ関数です.
186         Params:
187         message = マウスの状態が格納されたメッセージです.
188     +/
189     void mouseReleased(ref MouseReleasedEventArg message){
190         mouseReleased(message.x, message.y, message.button );
191         mouseReleased(Vector2f(message.x, message.y), message.button);
192         mouseReleased(Vector2i(message.x, message.y), message.button);
193     }
194 
195     /++
196         マウスのボタンが離れた際に呼ばれるメンバ関数です.
197         Params:
198         x = マウスのX座標を表します.
199         y = マウスのY座標を表します.
200         button = 離れたマウスのボタンを表します.
201     +/
202     void mouseReleased(int x, int y, int button){}
203 
204     /++
205         マウスのボタンが離れた際に呼ばれるメンバ関数です.
206         Params:
207         position = マウスの座標を表します.
208         button = 離れたマウスのボタンを表します.
209     +/
210     void mouseReleased(Vector2f position, int button){}
211 
212     /++
213         マウスのボタンが離れた際に呼ばれるメンバ関数です.
214         Params:
215         position = マウスの座標を表します.
216         button = 離れたマウスのボタンを表します.
217     +/
218     void mouseReleased(Vector2i position, int button){}
219 
220     /++
221         マウスのボタンが押された際に呼ばれるメンバ関数です.
222         Params:
223         message = マウスの状態が格納されたメッセージです.
224     +/
225     void mousePressed(ref MousePressedEventArg message){
226         mousePressed(message.x, message.y, message.button );
227         mousePressed(Vector2f(message.x, message.y), message.button);
228         mousePressed(Vector2i(message.x, message.y), message.button);
229     }
230 
231     /++
232         マウスのボタンが押された際に呼ばれるメンバ関数です.
233         Params:
234         x = マウスのX座標を表します.
235         y = マウスのY座標を表します.
236         button = 押されたマウスのボタンを表します.
237     +/
238     void mousePressed(int x, int y, int button){}
239 
240     /++
241         マウスのボタンが押された際に呼ばれるメンバ関数です.
242         Params:
243         position = マウスの座標を表します.
244         button = 押されたマウスのボタンを表します.
245     +/
246     void mousePressed(Vector2f position, int button){}
247 
248     /++
249         マウスのボタンが押された際に呼ばれるメンバ関数です.
250         Params:
251         position = マウスの座標を表します.
252         button = 押されたマウスのボタンを表します.
253     +/
254     void mousePressed(Vector2i position, int button){}
255     
256     ///
257     bool hasPressedKey(in KeyType key)const{
258         return !_hasHeldKeysPrevious[key] && _hasHeldKeysCurrent[key];
259     }
260     
261     ///
262     bool hasHeldKey(in KeyType key)const{
263         return _hasHeldKeysCurrent[key];
264     }
265     
266     ///
267     bool hasReleasedKey(in KeyType key)const{
268         return _hasHeldKeysPrevious[key] && !_hasHeldKeysCurrent[key];
269     }
270 
271     final void exitApp(){
272         _shouldClose = true;
273     }
274 
275     final bool shouldClose(){
276         return _shouldClose;
277     }
278 
279     
280     private{
281         bool[KeyType] _hasHeldKeysCurrent;
282         bool[KeyType] _hasHeldKeysPrevious;
283         bool _shouldClose = false;
284     }
285 }
286 
287 void initHeldKeys(BaseApp app){
288     import std.traits:EnumMembers;
289     foreach (elem; [EnumMembers!KeyType]) {
290         app._hasHeldKeysCurrent[elem]  = false;
291         app._hasHeldKeysPrevious[elem] = false;
292     }
293 }
294 
295 package void PressKey(BaseApp app, KeyType keyType){
296     app._hasHeldKeysCurrent[keyType] = true;
297 }
298 
299 package void ReleaseKey(BaseApp app, KeyType keyType){
300     app._hasHeldKeysCurrent[keyType] = false;
301 }
302 
303 package BaseApp updateKeys(BaseApp app){
304     import std.traits:EnumMembers;
305     foreach (elem; [EnumMembers!KeyType]) {
306         app._hasHeldKeysPrevious[elem] = app._hasHeldKeysCurrent[elem];
307     }
308     return app;
309 }
310 
311 unittest{
312     auto app = new BaseApp;
313     app.initHeldKeys;
314     
315     assert(!app.hasHeldKey(KeyType.A));
316     assert(!app.hasPressedKey(KeyType.A));
317     assert(!app.hasReleasedKey(KeyType.A));
318     
319     app.updateKeys
320        .PressKey(KeyType.A);
321     
322     assert(app.hasHeldKey(KeyType.A));
323     assert(app.hasPressedKey(KeyType.A));
324     assert(!app.hasReleasedKey(KeyType.A));
325     
326     app.updateKeys;
327     
328     assert(app.hasHeldKey(KeyType.A));
329     assert(!app.hasPressedKey(KeyType.A));
330     assert(!app.hasReleasedKey(KeyType.A));
331     
332     app.updateKeys
333        .ReleaseKey(KeyType.A);
334     
335     assert(!app.hasHeldKey(KeyType.A));
336     assert(!app.hasPressedKey(KeyType.A));
337     assert(app.hasReleasedKey(KeyType.A));
338 }