YSTest: Input.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

Input.cpp
浏览该文件的文档.
1 /*
2 © 2012-2015 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "YCLib/YModules.h"
29 #include YFM_YCLib_Input
30 #include YFM_YCLib_NativeAPI
31 #include YFM_YCLib_Mutex
32 #include YFM_YCLib_Debug
33 #if YCL_Android
34 # include <android/input.h>
35 #endif
36
38 using namespace platform::Concurrency;
40 using platform::Deref;
41
42 namespace platform
43 {
44
45 void
46 WaitForInput()
47 {
48 while(true)
49 {
50 platform_ex::UpdateKeyStates();
51 if(platform_ex::FetchKeyDownState().any())
52 break;
53 #if YCL_DS
54 ::swiWaitForVBlank();
55 #endif
56 }
57 }
58
59 } // namespace platform;
60
61 namespace platform_ex
62 {
63
65 namespace
66 {
67
68 mutex CompKeyMutex;
69 mutex KeyMutex;
70
71 } // unnamed namespace;
72
73 #if YCL_KEYSTATE_DIRECT
74 platform::KeyInput KeyState, OldKeyState;
75 #else
76 namespace
77 {
78
80
81 platform::KeyInput KeyStateA;
83 platform::KeyInput KeyStateB;
84 platform::KeyInput *pKeyState(&KeyStateA), *pOldKeyState(&KeyStateB);
86 #if YCL_Android
87 platform::KeyInput KeyStateBuffer;
90 mutex CursorMutex;
92 float LastCursorPosX, LastCursorPosY;
93 #endif
94
96 inline platform::KeyInput&
97 FetchKeyStateRef()
98 {
99 return Deref(pKeyState);
100 }
101
103 inline platform::KeyInput&
104 FetchOldKeyStateRef()
105 {
106 return Deref(pOldKeyState);
107 }
108
110
111 inline platform::KeyInput
112 FetchKeyDownStateRaw()
113 {
114 return FetchKeyStateRef() & ~FetchOldKeyStateRef();
115 }
116
117 inline platform::KeyInput
118 FetchKeyUpStateRaw()
119 {
120 return (FetchKeyStateRef() ^ FetchOldKeyStateRef()) & ~FetchKeyStateRef();
121 }
123
124 } //unnamed namespace;
125
126 const platform::KeyInput&
127 FetchKeyState()
128 {
129 lock_guard<mutex> lck(KeyMutex);
130
131 return FetchKeyStateRef();
132 }
133
134 const platform::KeyInput&
135 FetchOldKeyState()
136 {
137 lock_guard<mutex> lck(KeyMutex);
138
139 return FetchOldKeyStateRef();
140 }
141
142 platform::KeyInput
143 FetchKeyDownState()
144 {
145 lock_guard<mutex> comp_lck(CompKeyMutex);
146
147 return FetchKeyDownStateRaw();
148 }
149
150 platform::KeyInput
151 FetchKeyUpState()
152 {
153 lock_guard<mutex> comp_lck(CompKeyMutex);
154
155 return FetchKeyUpStateRaw();
156 }
157
158 void
159 ClearKeyStates()
160 {
161 lock_guard<mutex> comp_lck(CompKeyMutex);
162 lock_guard<mutex> lck(KeyMutex);
163
164 yunseq(Deref(pKeyState).reset(), Deref(pOldKeyState).reset());
165 }
166
167 #endif
168
169 void
170 UpdateKeyStates()
171 {
172 lock_guard<mutex> comp_lck(CompKeyMutex);
173 lock_guard<mutex> lck(KeyMutex);
174
175 #if YCL_KEYSTATE_DIRECT
176 OldKeyState = KeyState;
177 #else
178 std::swap(pKeyState, pOldKeyState);
179 #endif
180 #if YCL_DS
181 KeyState = ::keysCurrent();
182 #elif YCL_Win32
183 // NOTE: 0x00 and 0xFF should be invalid.
184 for(size_t i(1); i < platform::KeyBitsetWidth - 1; ++i)
185 pKeyState->set(i, ::GetAsyncKeyState(int(i)) & 0x8000);
186 #elif YCL_Android
187 FetchKeyStateRef() = KeyStateBuffer;
188 #endif
189 }
190
191
192 #if YCL_DS
193 pair<std::int16_t, std::int16_t>
194 FetchCursor()
195 {
196 using pr_type = pair<std::int16_t, std::int16_t>;
197 ::touchPosition tp;
198
199 ::touchRead(&tp);
200 // NOTE: (-1, -1) is %YSLib::Point::Invalid.
201 return YB_LIKELY(tp.px != 0 && tp.py != 0) ? pr_type(tp.px - 1, tp.py - 1)
202 : pr_type(-1, -1);
203 }
204
205
206 void
207 WaitForKey(platform::KeyInput mask)
208 {
209 while(true)
210 {
211 UpdateKeyStates();
212 if((FetchKeyDownState() & mask).any())
213 break;
214 swiWaitForVBlank();
215 }
216 }
217
218 void
219 WaitForFrontKey()
220 {
221 return WaitForKey(KEY_TOUCH | KEY_A | KEY_B | KEY_X | KEY_Y
222 | KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN
223 | KEY_START | KEY_SELECT);
224 }
225
226 void
227 WaitForFrontKeypad()
228 {
229 return WaitForKey(KEY_A | KEY_B | KEY_X | KEY_Y
230 | KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN
231 | KEY_START | KEY_SELECT);
232 }
233
234 void
235 WaitForArrowKey()
236 {
237 return WaitForKey(KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN);
238 }
239
240 void
241 WaitForABXY()
242 {
243 return WaitForKey(KEY_A | KEY_B | KEY_X | KEY_Y);
244 }
245 #elif YCL_Android
246 pair<float, float>
247 FetchCursor()
248 {
249 lock_guard<mutex> lck(CursorMutex);
250
251 return {LastCursorPosX, LastCursorPosY};
252 }
253
254 void
255 SaveInput(const ::AInputEvent& e)
256 {
257 const auto update_key([](std::int32_t action, const std::uint8_t keycode){
258 lock_guard<mutex> lck(KeyMutex);
259 // TODO: Track Alt/Shift/Sym key states.
260 // const auto meta(::AKeyEvent_getMetaState(&e));
261
262 switch(action)
263 {
264 case ::AKEY_EVENT_ACTION_DOWN:
265 case ::AKEY_EVENT_ACTION_UP:
266 KeyStateBuffer.set(keycode, action == ::AKEY_EVENT_ACTION_DOWN);
267 break;
268 case ::AKEY_EVENT_ACTION_MULTIPLE:
269 // TODO: Record.
270 break;
271 }
272 });
273 const auto update_motion_key([](bool down){
274 lock_guard<mutex> lck(KeyMutex);
275
276 KeyStateBuffer.set(platform::KeyCodes::Primary, down);
277 });
278
279 switch(::AInputEvent_getType(&e))
280 {
281 case AINPUT_EVENT_TYPE_KEY:
282 if(~::AKeyEvent_getFlags(&e) & ::AKEY_EVENT_FLAG_CANCELED)
283 update_key(::AKeyEvent_getAction(&e),
284 ::AKeyEvent_getKeyCode(&e) & 0xFF);
285 break;
286 case AINPUT_EVENT_TYPE_MOTION:
287 // TODO: Detect multiple pointers using 'AMotionEvent_getPointerCount'.
288 // TODO: Support multiple pointers handlers.
289 // TODO: Detect edges using 'AMotionEvent_getEdgeFlags'.
290 // TODO: Record pressure using 'AMotionEvent_getPressure'.
291 // TODO: Record touch area size using 'AMotionEvent_getSize'.
292 // TODO: Track historical motion using 'AMotionEvent_getHistorical*'.
293 if(::AMotionEvent_getFlags(&e) != AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED)
294 switch(::AKeyEvent_getAction(&e) & AMOTION_EVENT_ACTION_MASK)
295 {
296 case AMOTION_EVENT_ACTION_CANCEL:
297 break;
298 case AMOTION_EVENT_ACTION_UP:
299 update_motion_key({});
300 break;
301 case AMOTION_EVENT_ACTION_DOWN:
302 update_motion_key(true);
303 case AMOTION_EVENT_ACTION_MOVE:
304 default:
305 {
306 lock_guard<mutex> lck(CursorMutex);
307
308 yunseq(LastCursorPosX = ::AMotionEvent_getRawX(&e, 0),
309 LastCursorPosY = ::AMotionEvent_getRawY(&e, 0));
310 }
311 }
312 }
313 }
314 #endif
315
316 } // namespace platform_ex;
317
platform_ex::ClearKeyStates
YF_API void ClearKeyStates()
清除按键缓冲。
Definition: Input.cpp:159
ystdex::swap
void swap(container_adaptor< _tSeqCon > &x, container_adaptor< _tSeqCon > &y)
Definition: container.hpp:179
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:109
platform_ex::FetchKeyDownState
YF_API platform::KeyInput FetchKeyDownState()
取键按下状态。
Definition: Input.cpp:143
ystdex::reset
bool reset(std::unique_ptr< _type > &p)
Definition: memory.hpp:584
platform_ex::FetchOldKeyState
YF_API const platform::KeyInput & FetchOldKeyState()
取上一次更新的按键状态。
Definition: Input.cpp:135
platform_ex::FetchKeyUpState
YF_API platform::KeyInput FetchKeyUpState()
取键释放状态。
Definition: Input.cpp:151
platform_ex::FetchKeyState
YF_API const platform::KeyInput & FetchKeyState()
取按键状态。
Definition: Input.cpp:127
platform::WaitForInput
YF_API void WaitForInput()
等待任意按键。
Definition: Input.cpp:46
platform::Concurrency
Definition: Mutex.h:47
platform
默认平台命名空间。
Definition: Container.h:47
platform::Deref
yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:440
platform::KeyCodes::DS::Primary
static yconstexpr const NativeSet Primary
Definition: Keys.h:241
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
platform_ex
平台扩展命名空间。
Definition: Android.h:45
YModules.h
platform::KeyInput
std::bitset< KeyBitsetWidth > KeyInput
按键并行位宽。
Definition: Keys.h:67
YSLib::i
return i
Definition: YCoreUtilities.h:176
platform_ex::UpdateKeyStates
YF_API void UpdateKeyStates()
更新按键状态。
Definition: Input.cpp:170
YB_LIKELY
#define YB_LIKELY(_expr)
Definition: ydef.h:437
ystdex::single_thread::lock_guard
Definition: pseudo_mutex.h:197
ystdex::single_thread::mutex
Definition: pseudo_mutex.h:63