Atlas - testautomation_events.c

Home / ext / SDL / test Lines: 1 | Size: 12337 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/** 2 * Events test suite 3 */ 4#include <SDL3/SDL.h> 5#include <SDL3/SDL_test.h> 6#include "testautomation_suites.h" 7 8/* ================= Test Case Implementation ================== */ 9 10/* Test case functions */ 11 12/* Flag indicating if the userdata should be checked */ 13static int g_userdataCheck = 0; 14 15/* Userdata value to check */ 16static int g_userdataValue = 0; 17 18/* Flag indicating that the filter was called */ 19static int g_eventFilterCalled = 0; 20 21/* Userdata values for event */ 22static int g_userdataValue1 = 1; 23static int g_userdataValue2 = 2; 24 25#define MAX_ITERATIONS 100 26 27/* Event filter that sets some flags and optionally checks userdata */ 28static bool SDLCALL events_sampleNullEventFilter(void *userdata, SDL_Event *event) 29{ 30 g_eventFilterCalled = 1; 31 32 if (g_userdataCheck != 0) { 33 SDLTest_AssertCheck(userdata != NULL, "Check userdata pointer, expected: non-NULL, got: %s", (userdata != NULL) ? "non-NULL" : "NULL"); 34 if (userdata != NULL) { 35 SDLTest_AssertCheck(*(int *)userdata == g_userdataValue, "Check userdata value, expected: %i, got: %i", g_userdataValue, *(int *)userdata); 36 } 37 } 38 39 return true; 40} 41 42/** 43 * Test pumping and peeking events. 44 * 45 * \sa SDL_PumpEvents 46 * \sa SDL_PollEvent 47 */ 48static int SDLCALL events_pushPumpAndPollUserevent(void *arg) 49{ 50 SDL_Event event_in; 51 SDL_Event event_out; 52 int result; 53 int i; 54 Sint32 ref_code = SDLTest_RandomSint32(); 55 SDL_Window *event_window; 56 57 /* Flush all events */ 58 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST); 59 SDLTest_AssertCheck(!SDL_HasEvents(SDL_EVENT_USER, SDL_EVENT_USER), "Check SDL_HasEvents returns false"); 60 61 /* Create user event */ 62 event_in.type = SDL_EVENT_USER; 63 event_in.user.windowID = 0; 64 event_in.common.timestamp = 0; 65 event_in.user.code = ref_code; 66 event_in.user.data1 = (void *)&g_userdataValue1; 67 event_in.user.data2 = (void *)&g_userdataValue2; 68 69 /* Push a user event onto the queue and force queue update */ 70 SDL_PushEvent(&event_in); 71 SDLTest_AssertPass("Call to SDL_PushEvent()"); 72 SDL_PumpEvents(); 73 SDLTest_AssertPass("Call to SDL_PumpEvents()"); 74 75 SDLTest_AssertCheck(SDL_HasEvents(SDL_EVENT_USER, SDL_EVENT_USER), "Check SDL_HasEvents returns true"); 76 77 /* Poll until we get a user event. */ 78 for (i = 0; i < MAX_ITERATIONS; i++) { 79 result = SDL_PollEvent(&event_out); 80 SDLTest_AssertPass("Call to SDL_PollEvent()"); 81 SDLTest_AssertCheck(result == 1, "Check result from SDL_PollEvent, expected: 1, got: %d", result); 82 if (!result) { 83 break; 84 } 85 if (event_out.type == SDL_EVENT_USER) { 86 break; 87 } 88 } 89 SDLTest_AssertCheck(i < MAX_ITERATIONS, "Check the user event is seen in less then %d polls, got %d poll", MAX_ITERATIONS, i + 1); 90 91 SDLTest_AssertCheck(SDL_EVENT_USER == event_out.type, "Check event type is SDL_EVENT_USER, expected: 0x%x, got: 0x%" SDL_PRIx32, SDL_EVENT_USER, event_out.type); 92 SDLTest_AssertCheck(ref_code == event_out.user.code, "Check SDL_Event.user.code, expected: 0x%" SDL_PRIx32 ", got: 0x%" SDL_PRIx32 , ref_code, event_out.user.code); 93 SDLTest_AssertCheck(0 == event_out.user.windowID, "Check SDL_Event.user.windowID, expected: NULL , got: %" SDL_PRIu32, event_out.user.windowID); 94 SDLTest_AssertCheck((void *)&g_userdataValue1 == event_out.user.data1, "Check SDL_Event.user.data1, expected: %p, got: %p", &g_userdataValue1, event_out.user.data1); 95 SDLTest_AssertCheck((void *)&g_userdataValue2 == event_out.user.data2, "Check SDL_Event.user.data2, expected: %p, got: %p", &g_userdataValue2, event_out.user.data2); 96 event_window = SDL_GetWindowFromEvent(&event_out); 97 SDLTest_AssertCheck(NULL == SDL_GetWindowFromEvent(&event_out), "Check SDL_GetWindowFromEvent returns the window id from a user event, expected: NULL, got: %p", event_window); 98 99 /* Need to finish getting all events and sentinel, otherwise other tests that rely on event are in bad state */ 100 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST); 101 102 return TEST_COMPLETED; 103} 104 105/** 106 * Adds and deletes an event watch function with NULL userdata 107 * 108 * \sa SDL_AddEventWatch 109 * \sa SDL_RemoveEventWatch 110 * 111 */ 112static int SDLCALL events_addDelEventWatch(void *arg) 113{ 114 SDL_Event event; 115 116 /* Create user event */ 117 event.type = SDL_EVENT_USER; 118 event.common.timestamp = 0; 119 event.user.code = SDLTest_RandomSint32(); 120 event.user.data1 = (void *)&g_userdataValue1; 121 event.user.data2 = (void *)&g_userdataValue2; 122 123 /* Disable userdata check */ 124 g_userdataCheck = 0; 125 126 /* Reset event filter call tracker */ 127 g_eventFilterCalled = 0; 128 129 /* Add watch */ 130 SDL_AddEventWatch(events_sampleNullEventFilter, NULL); 131 SDLTest_AssertPass("Call to SDL_AddEventWatch()"); 132 133 /* Push a user event onto the queue and force queue update */ 134 SDL_PushEvent(&event); 135 SDLTest_AssertPass("Call to SDL_PushEvent()"); 136 SDL_PumpEvents(); 137 SDLTest_AssertPass("Call to SDL_PumpEvents()"); 138 SDLTest_AssertCheck(g_eventFilterCalled == 1, "Check that event filter was called"); 139 140 /* Delete watch */ 141 SDL_RemoveEventWatch(events_sampleNullEventFilter, NULL); 142 SDLTest_AssertPass("Call to SDL_RemoveEventWatch()"); 143 144 /* Push a user event onto the queue and force queue update */ 145 g_eventFilterCalled = 0; 146 SDL_PushEvent(&event); 147 SDLTest_AssertPass("Call to SDL_PushEvent()"); 148 SDL_PumpEvents(); 149 SDLTest_AssertPass("Call to SDL_PumpEvents()"); 150 SDLTest_AssertCheck(g_eventFilterCalled == 0, "Check that event filter was NOT called"); 151 152 return TEST_COMPLETED; 153} 154 155/** 156 * Adds and deletes an event watch function with userdata 157 * 158 * \sa SDL_AddEventWatch 159 * \sa SDL_RemoveEventWatch 160 * 161 */ 162static int SDLCALL events_addDelEventWatchWithUserdata(void *arg) 163{ 164 SDL_Event event; 165 166 /* Create user event */ 167 event.type = SDL_EVENT_USER; 168 event.common.timestamp = 0; 169 event.user.code = SDLTest_RandomSint32(); 170 event.user.data1 = (void *)&g_userdataValue1; 171 event.user.data2 = (void *)&g_userdataValue2; 172 173 /* Enable userdata check and set a value to check */ 174 g_userdataCheck = 1; 175 g_userdataValue = SDLTest_RandomIntegerInRange(-1024, 1024); 176 177 /* Reset event filter call tracker */ 178 g_eventFilterCalled = 0; 179 180 /* Add watch */ 181 SDL_AddEventWatch(events_sampleNullEventFilter, (void *)&g_userdataValue); 182 SDLTest_AssertPass("Call to SDL_AddEventWatch()"); 183 184 /* Push a user event onto the queue and force queue update */ 185 SDL_PushEvent(&event); 186 SDLTest_AssertPass("Call to SDL_PushEvent()"); 187 SDL_PumpEvents(); 188 SDLTest_AssertPass("Call to SDL_PumpEvents()"); 189 SDLTest_AssertCheck(g_eventFilterCalled == 1, "Check that event filter was called"); 190 191 /* Delete watch */ 192 SDL_RemoveEventWatch(events_sampleNullEventFilter, (void *)&g_userdataValue); 193 SDLTest_AssertPass("Call to SDL_RemoveEventWatch()"); 194 195 /* Push a user event onto the queue and force queue update */ 196 g_eventFilterCalled = 0; 197 SDL_PushEvent(&event); 198 SDLTest_AssertPass("Call to SDL_PushEvent()"); 199 SDL_PumpEvents(); 200 SDLTest_AssertPass("Call to SDL_PumpEvents()"); 201 SDLTest_AssertCheck(g_eventFilterCalled == 0, "Check that event filter was NOT called"); 202 203 return TEST_COMPLETED; 204} 205 206/** 207 * Runs callbacks on the main thread. 208 * 209 * \sa SDL_IsMainThread 210 * \sa SDL_RunOnMainThread 211 * 212 */ 213 214typedef struct IncrementCounterData_t 215{ 216 Uint32 delay; 217 int counter; 218} IncrementCounterData_t; 219 220static void SDLCALL IncrementCounter(void *userdata) 221{ 222 IncrementCounterData_t *data = (IncrementCounterData_t *)userdata; 223 ++data->counter; 224} 225 226#ifndef SDL_PLATFORM_EMSCRIPTEN /* Emscripten doesn't have threads */ 227static int SDLCALL IncrementCounterThread(void *userdata) 228{ 229 IncrementCounterData_t *data = (IncrementCounterData_t *)userdata; 230 SDL_Event event; 231 232 SDL_assert(!SDL_IsMainThread()); 233 SDL_zero(event); 234 235 if (data->delay > 0) { 236 SDL_Delay(data->delay); 237 } 238 239 if (!SDL_RunOnMainThread(IncrementCounter, userdata, false)) { 240 SDLTest_LogError("Couldn't run IncrementCounter asynchronously on main thread: %s", SDL_GetError()); 241 } 242 if (!SDL_RunOnMainThread(IncrementCounter, userdata, true)) { 243 SDLTest_LogError("Couldn't run IncrementCounter synchronously on main thread: %s", SDL_GetError()); 244 } 245 246 /* Send an event to unblock the main thread, which is waiting in SDL_WaitEvent() */ 247 event.type = SDL_EVENT_USER; 248 SDL_PushEvent(&event); 249 250 return 0; 251} 252#endif /* !SDL_PLATFORM_EMSCRIPTEN */ 253 254static int SDLCALL events_mainThreadCallbacks(void *arg) 255{ 256 IncrementCounterData_t data = { 0, 0 }; 257 258 /* Make sure we're on the main thread */ 259 SDLTest_AssertCheck(SDL_IsMainThread(), "Verify we're on the main thread"); 260 261 SDL_RunOnMainThread(IncrementCounter, &data, true); 262 SDLTest_AssertCheck(data.counter == 1, "Incremented counter on main thread, expected 1, got %d", data.counter); 263 264#ifndef SDL_PLATFORM_EMSCRIPTEN /* Emscripten doesn't have threads */ 265 { 266 SDL_Window *window; 267 SDL_Thread *thread; 268 SDL_Event event; 269 270 window = SDL_CreateWindow("test", 0, 0, SDL_WINDOW_HIDDEN); 271 SDLTest_AssertCheck(window != NULL, "Create window, expected non-NULL, got %p", window); 272 273 /* Flush any pending events */ 274 SDL_PumpEvents(); 275 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST); 276 277 /* Increment the counter on a thread, waiting for both calls to be queued */ 278 thread = SDL_CreateThread(IncrementCounterThread, NULL, &data); 279 SDLTest_AssertCheck(thread != NULL, "Create counter thread"); 280 281 /* Wait for both increment calls to be queued up */ 282 SDL_Delay(100); 283 284 /* Run the main callbacks */ 285 SDL_WaitEvent(&event); 286 SDLTest_AssertCheck(event.type == SDL_EVENT_USER, "Expected user event (0x%.4x), got 0x%.4x", SDL_EVENT_USER, (int)event.type); 287 SDL_WaitThread(thread, NULL); 288 SDLTest_AssertCheck(data.counter == 3, "Incremented counter on main thread, expected 3, got %d", data.counter); 289 290 /* Flush events again, as the previous SDL_WaitEvent() call may have pumped OS events and added them to the queue */ 291 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST); 292 293 /* Try again, but this time delay the calls until we've started waiting for events */ 294 data.delay = 100; 295 thread = SDL_CreateThread(IncrementCounterThread, NULL, &data); 296 SDLTest_AssertCheck(thread != NULL, "Create counter thread"); 297 298 /* Run the main callbacks */ 299 SDL_WaitEvent(&event); 300 SDLTest_AssertCheck(event.type == SDL_EVENT_USER, "Expected user event (0x%.4x), got 0x%.4x", SDL_EVENT_USER, (int)event.type); 301 SDL_WaitThread(thread, NULL); 302 SDLTest_AssertCheck(data.counter == 5, "Incremented counter on main thread, expected 5, got %d", data.counter); 303 304 SDL_DestroyWindow(window); 305 } 306#endif /* !SDL_PLATFORM_EMSCRIPTEN */ 307 308 return TEST_COMPLETED; 309} 310 311/* ================= Test References ================== */ 312 313/* Events test cases */ 314static const SDLTest_TestCaseReference eventsTest_pushPumpAndPollUserevent = { 315 events_pushPumpAndPollUserevent, "events_pushPumpAndPollUserevent", "Pushes, pumps and polls a user event", TEST_ENABLED 316}; 317 318static const SDLTest_TestCaseReference eventsTest_addDelEventWatch = { 319 events_addDelEventWatch, "events_addDelEventWatch", "Adds and deletes an event watch function with NULL userdata", TEST_ENABLED 320}; 321 322static const SDLTest_TestCaseReference eventsTest_addDelEventWatchWithUserdata = { 323 events_addDelEventWatchWithUserdata, "events_addDelEventWatchWithUserdata", "Adds and deletes an event watch function with userdata", TEST_ENABLED 324}; 325 326static const SDLTest_TestCaseReference eventsTest_mainThreadCallbacks = { 327 events_mainThreadCallbacks, "events_mainThreadCallbacks", "Run callbacks on the main thread", TEST_ENABLED 328}; 329 330/* Sequence of Events test cases */ 331static const SDLTest_TestCaseReference *eventsTests[] = { 332 &eventsTest_pushPumpAndPollUserevent, 333 &eventsTest_addDelEventWatch, 334 &eventsTest_addDelEventWatchWithUserdata, 335 &eventsTest_mainThreadCallbacks, 336 NULL 337}; 338 339/* Events test suite (global) */ 340SDLTest_TestSuiteReference eventsTestSuite = { 341 "Events", 342 NULL, 343 eventsTests, 344 NULL 345}; 346
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.