2015-06-21 17:33:46 +02:00
/**
* Events test suite
*/
2022-11-26 20:43:38 -08:00
# include <SDL3/SDL.h>
# include <SDL3/SDL_test.h>
2023-03-08 16:12:45 +01:00
# include "testautomation_suites.h"
2015-06-21 17:33:46 +02:00
/* ================= Test Case Implementation ================== */
/* Test case functions */
/* Flag indicating if the userdata should be checked */
2022-12-29 22:58:16 +01:00
static int g_userdataCheck = 0 ;
2015-06-21 17:33:46 +02:00
/* Userdata value to check */
2022-12-29 22:58:16 +01:00
static int g_userdataValue = 0 ;
2015-06-21 17:33:46 +02:00
/* Flag indicating that the filter was called */
2022-12-29 22:58:16 +01:00
static int g_eventFilterCalled = 0 ;
2015-06-21 17:33:46 +02:00
/* Userdata values for event */
2022-12-29 22:58:16 +01:00
static int g_userdataValue1 = 1 ;
static int g_userdataValue2 = 2 ;
2015-06-21 17:33:46 +02:00
2024-08-02 23:47:03 +02:00
# define MAX_ITERATIONS 100
2015-06-21 17:33:46 +02:00
/* Event filter that sets some flags and optionally checks userdata */
2024-09-18 07:52:28 -07:00
static bool SDLCALL events_sampleNullEventFilter ( void * userdata , SDL_Event * event )
2015-06-21 17:33:46 +02:00
{
2022-12-29 22:58:16 +01:00
g_eventFilterCalled = 1 ;
2015-06-21 17:33:46 +02:00
2022-12-29 22:58:16 +01:00
if ( g_userdataCheck ! = 0 ) {
2022-11-30 12:51:59 -08:00
SDLTest_AssertCheck ( userdata ! = NULL , " Check userdata pointer, expected: non-NULL, got: %s " , ( userdata ! = NULL ) ? " non-NULL " : " NULL " ) ;
if ( userdata ! = NULL ) {
2022-12-29 22:58:16 +01:00
SDLTest_AssertCheck ( * ( int * ) userdata = = g_userdataValue , " Check userdata value, expected: %i, got: %i " , g_userdataValue , * ( int * ) userdata ) ;
2022-11-30 12:51:59 -08:00
}
}
2015-06-21 17:33:46 +02:00
2024-09-18 07:52:28 -07:00
return true ;
2015-06-21 17:33:46 +02:00
}
/**
2023-11-06 10:26:06 -05:00
* Test pumping and peeking events .
2015-06-21 17:33:46 +02:00
*
2023-02-02 00:21:53 +01:00
* \ sa SDL_PumpEvents
* \ sa SDL_PollEvent
2015-06-21 17:33:46 +02:00
*/
2024-09-06 03:21:13 +02:00
static int SDLCALL events_pushPumpAndPollUserevent ( void * arg )
2015-06-21 17:33:46 +02:00
{
2024-08-02 23:47:03 +02:00
SDL_Event event_in ;
SDL_Event event_out ;
2022-11-30 12:51:59 -08:00
int result ;
2024-08-02 23:47:03 +02:00
int i ;
Sint32 ref_code = SDLTest_RandomSint32 ( ) ;
SDL_Window * event_window ;
/* Flush all events */
SDL_FlushEvents ( SDL_EVENT_FIRST , SDL_EVENT_LAST ) ;
SDLTest_AssertCheck ( ! SDL_HasEvents ( SDL_EVENT_USER , SDL_EVENT_USER ) , " Check SDL_HasEvents returns false " ) ;
2022-11-30 12:51:59 -08:00
/* Create user event */
2024-08-02 23:47:03 +02:00
event_in . type = SDL_EVENT_USER ;
event_in . user . windowID = 0 ;
event_in . common . timestamp = 0 ;
event_in . user . code = ref_code ;
event_in . user . data1 = ( void * ) & g_userdataValue1 ;
event_in . user . data2 = ( void * ) & g_userdataValue2 ;
2022-11-30 12:51:59 -08:00
/* Push a user event onto the queue and force queue update */
2024-08-02 23:47:03 +02:00
SDL_PushEvent ( & event_in ) ;
2022-11-30 12:51:59 -08:00
SDLTest_AssertPass ( " Call to SDL_PushEvent() " ) ;
SDL_PumpEvents ( ) ;
SDLTest_AssertPass ( " Call to SDL_PumpEvents() " ) ;
2024-08-02 23:47:03 +02:00
SDLTest_AssertCheck ( SDL_HasEvents ( SDL_EVENT_USER , SDL_EVENT_USER ) , " Check SDL_HasEvents returns true " ) ;
2022-11-30 12:51:59 -08:00
2024-08-02 23:47:03 +02:00
/* Poll until we get a user event. */
for ( i = 0 ; i < MAX_ITERATIONS ; i + + ) {
result = SDL_PollEvent ( & event_out ) ;
SDLTest_AssertPass ( " Call to SDL_PollEvent() " ) ;
SDLTest_AssertCheck ( result = = 1 , " Check result from SDL_PollEvent, expected: 1, got: %d " , result ) ;
if ( ! result ) {
break ;
}
if ( event_out . type = = SDL_EVENT_USER ) {
break ;
}
2023-03-21 12:11:57 +01:00
}
2024-08-02 23:47:03 +02:00
SDLTest_AssertCheck ( i < MAX_ITERATIONS , " Check the user event is seen in less then %d polls, got %d poll " , MAX_ITERATIONS , i + 1 ) ;
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 ) ;
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 ) ;
SDLTest_AssertCheck ( 0 = = event_out . user . windowID , " Check SDL_Event.user.windowID, expected: NULL , got: % " SDL_PRIu32 , event_out . user . windowID ) ;
2024-09-24 13:07:15 +02:00
SDLTest_AssertCheck ( ( void * ) & g_userdataValue1 = = event_out . user . data1 , " Check SDL_Event.user.data1, expected: %p, got: %p " , & g_userdataValue1 , event_out . user . data1 ) ;
SDLTest_AssertCheck ( ( void * ) & g_userdataValue2 = = event_out . user . data2 , " Check SDL_Event.user.data2, expected: %p, got: %p " , & g_userdataValue2 , event_out . user . data2 ) ;
2024-08-02 23:47:03 +02:00
event_window = SDL_GetWindowFromEvent ( & event_out ) ;
SDLTest_AssertCheck ( NULL = = SDL_GetWindowFromEvent ( & event_out ) , " Check SDL_GetWindowFromEvent returns the window id from a user event, expected: NULL, got: %p " , event_window ) ;
/* Need to finish getting all events and sentinel, otherwise other tests that rely on event are in bad state */
SDL_FlushEvents ( SDL_EVENT_FIRST , SDL_EVENT_LAST ) ;
2023-03-21 12:11:57 +01:00
2022-11-30 12:51:59 -08:00
return TEST_COMPLETED ;
2015-06-21 17:33:46 +02:00
}
/**
2023-11-06 10:26:06 -05:00
* Adds and deletes an event watch function with NULL userdata
2015-06-21 17:33:46 +02:00
*
2023-02-02 00:21:53 +01:00
* \ sa SDL_AddEventWatch
2024-08-31 07:23:51 -07:00
* \ sa SDL_RemoveEventWatch
2015-06-21 17:33:46 +02:00
*
*/
2024-09-06 03:21:13 +02:00
static int SDLCALL events_addDelEventWatch ( void * arg )
2015-06-21 17:33:46 +02:00
{
2022-11-30 12:51:59 -08:00
SDL_Event event ;
/* Create user event */
2023-01-23 17:54:09 -08:00
event . type = SDL_EVENT_USER ;
2023-06-13 23:00:00 +02:00
event . common . timestamp = 0 ;
2022-11-30 12:51:59 -08:00
event . user . code = SDLTest_RandomSint32 ( ) ;
2022-12-29 22:58:16 +01:00
event . user . data1 = ( void * ) & g_userdataValue1 ;
event . user . data2 = ( void * ) & g_userdataValue2 ;
2022-11-30 12:51:59 -08:00
/* Disable userdata check */
2022-12-29 22:58:16 +01:00
g_userdataCheck = 0 ;
2022-11-30 12:51:59 -08:00
/* Reset event filter call tracker */
2022-12-29 22:58:16 +01:00
g_eventFilterCalled = 0 ;
2022-11-30 12:51:59 -08:00
/* Add watch */
2022-12-29 22:58:16 +01:00
SDL_AddEventWatch ( events_sampleNullEventFilter , NULL ) ;
2022-11-30 12:51:59 -08:00
SDLTest_AssertPass ( " Call to SDL_AddEventWatch() " ) ;
/* Push a user event onto the queue and force queue update */
SDL_PushEvent ( & event ) ;
SDLTest_AssertPass ( " Call to SDL_PushEvent() " ) ;
SDL_PumpEvents ( ) ;
SDLTest_AssertPass ( " Call to SDL_PumpEvents() " ) ;
2022-12-29 22:58:16 +01:00
SDLTest_AssertCheck ( g_eventFilterCalled = = 1 , " Check that event filter was called " ) ;
2022-11-30 12:51:59 -08:00
/* Delete watch */
2024-08-31 07:23:51 -07:00
SDL_RemoveEventWatch ( events_sampleNullEventFilter , NULL ) ;
SDLTest_AssertPass ( " Call to SDL_RemoveEventWatch() " ) ;
2022-11-30 12:51:59 -08:00
/* Push a user event onto the queue and force queue update */
2022-12-29 22:58:16 +01:00
g_eventFilterCalled = 0 ;
2022-11-30 12:51:59 -08:00
SDL_PushEvent ( & event ) ;
SDLTest_AssertPass ( " Call to SDL_PushEvent() " ) ;
SDL_PumpEvents ( ) ;
SDLTest_AssertPass ( " Call to SDL_PumpEvents() " ) ;
2022-12-29 22:58:16 +01:00
SDLTest_AssertCheck ( g_eventFilterCalled = = 0 , " Check that event filter was NOT called " ) ;
2022-11-30 12:51:59 -08:00
return TEST_COMPLETED ;
2015-06-21 17:33:46 +02:00
}
/**
2023-11-06 10:26:06 -05:00
* Adds and deletes an event watch function with userdata
2015-06-21 17:33:46 +02:00
*
2023-02-02 00:21:53 +01:00
* \ sa SDL_AddEventWatch
2024-08-31 07:23:51 -07:00
* \ sa SDL_RemoveEventWatch
2015-06-21 17:33:46 +02:00
*
*/
2024-09-06 03:21:13 +02:00
static int SDLCALL events_addDelEventWatchWithUserdata ( void * arg )
2015-06-21 17:33:46 +02:00
{
2022-11-30 12:51:59 -08:00
SDL_Event event ;
/* Create user event */
2023-01-23 17:54:09 -08:00
event . type = SDL_EVENT_USER ;
2023-06-13 23:00:00 +02:00
event . common . timestamp = 0 ;
2022-11-30 12:51:59 -08:00
event . user . code = SDLTest_RandomSint32 ( ) ;
2022-12-29 22:58:16 +01:00
event . user . data1 = ( void * ) & g_userdataValue1 ;
event . user . data2 = ( void * ) & g_userdataValue2 ;
2022-11-30 12:51:59 -08:00
/* Enable userdata check and set a value to check */
2022-12-29 22:58:16 +01:00
g_userdataCheck = 1 ;
g_userdataValue = SDLTest_RandomIntegerInRange ( - 1024 , 1024 ) ;
2022-11-30 12:51:59 -08:00
/* Reset event filter call tracker */
2022-12-29 22:58:16 +01:00
g_eventFilterCalled = 0 ;
2022-11-30 12:51:59 -08:00
/* Add watch */
2022-12-29 22:58:16 +01:00
SDL_AddEventWatch ( events_sampleNullEventFilter , ( void * ) & g_userdataValue ) ;
2022-11-30 12:51:59 -08:00
SDLTest_AssertPass ( " Call to SDL_AddEventWatch() " ) ;
/* Push a user event onto the queue and force queue update */
SDL_PushEvent ( & event ) ;
SDLTest_AssertPass ( " Call to SDL_PushEvent() " ) ;
SDL_PumpEvents ( ) ;
SDLTest_AssertPass ( " Call to SDL_PumpEvents() " ) ;
2022-12-29 22:58:16 +01:00
SDLTest_AssertCheck ( g_eventFilterCalled = = 1 , " Check that event filter was called " ) ;
2022-11-30 12:51:59 -08:00
/* Delete watch */
2024-08-31 07:23:51 -07:00
SDL_RemoveEventWatch ( events_sampleNullEventFilter , ( void * ) & g_userdataValue ) ;
SDLTest_AssertPass ( " Call to SDL_RemoveEventWatch() " ) ;
2022-11-30 12:51:59 -08:00
/* Push a user event onto the queue and force queue update */
2022-12-29 22:58:16 +01:00
g_eventFilterCalled = 0 ;
2022-11-30 12:51:59 -08:00
SDL_PushEvent ( & event ) ;
SDLTest_AssertPass ( " Call to SDL_PushEvent() " ) ;
SDL_PumpEvents ( ) ;
SDLTest_AssertPass ( " Call to SDL_PumpEvents() " ) ;
2022-12-29 22:58:16 +01:00
SDLTest_AssertCheck ( g_eventFilterCalled = = 0 , " Check that event filter was NOT called " ) ;
2022-11-30 12:51:59 -08:00
return TEST_COMPLETED ;
2015-06-21 17:33:46 +02:00
}
2024-12-05 12:35:23 -08:00
/**
* Runs callbacks on the main thread .
*
* \ sa SDL_IsMainThread
* \ sa SDL_RunOnMainThread
*
*/
2025-02-25 12:23:32 -08:00
typedef struct IncrementCounterData_t
{
Uint32 delay ;
int counter ;
} IncrementCounterData_t ;
2024-12-05 12:35:23 -08:00
static void SDLCALL IncrementCounter ( void * userdata )
{
2025-02-25 12:23:32 -08:00
IncrementCounterData_t * data = ( IncrementCounterData_t * ) userdata ;
+ + data - > counter ;
2024-12-05 12:35:23 -08:00
}
# ifndef SDL_PLATFORM_EMSCRIPTEN /* Emscripten doesn't have threads */
static int SDLCALL IncrementCounterThread ( void * userdata )
{
2025-02-25 12:23:32 -08:00
IncrementCounterData_t * data = ( IncrementCounterData_t * ) userdata ;
SDL_Event event ;
2024-12-05 12:35:23 -08:00
SDL_assert ( ! SDL_IsMainThread ( ) ) ;
2025-09-03 10:13:05 +02:00
SDL_zero ( event ) ;
2025-02-25 12:23:32 -08:00
if ( data - > delay > 0 ) {
SDL_Delay ( data - > delay ) ;
}
if ( ! SDL_RunOnMainThread ( IncrementCounter , userdata , false ) ) {
SDLTest_LogError ( " Couldn't run IncrementCounter asynchronously on main thread: %s " , SDL_GetError ( ) ) ;
}
if ( ! SDL_RunOnMainThread ( IncrementCounter , userdata , true ) ) {
SDLTest_LogError ( " Couldn't run IncrementCounter synchronously on main thread: %s " , SDL_GetError ( ) ) ;
}
/* Send an event to unblock the main thread, which is waiting in SDL_WaitEvent() */
event . type = SDL_EVENT_USER ;
SDL_PushEvent ( & event ) ;
2024-12-05 12:35:23 -08:00
return 0 ;
}
# endif /* !SDL_PLATFORM_EMSCRIPTEN */
static int SDLCALL events_mainThreadCallbacks ( void * arg )
{
2025-02-25 12:23:32 -08:00
IncrementCounterData_t data = { 0 , 0 } ;
2024-12-05 12:35:23 -08:00
/* Make sure we're on the main thread */
SDLTest_AssertCheck ( SDL_IsMainThread ( ) , " Verify we're on the main thread " ) ;
2025-02-25 12:23:32 -08:00
SDL_RunOnMainThread ( IncrementCounter , & data , true ) ;
SDLTest_AssertCheck ( data . counter = = 1 , " Incremented counter on main thread, expected 1, got %d " , data . counter ) ;
2024-12-05 12:35:23 -08:00
# ifndef SDL_PLATFORM_EMSCRIPTEN /* Emscripten doesn't have threads */
{
2025-02-25 12:23:32 -08:00
SDL_Window * window ;
2024-12-05 12:35:23 -08:00
SDL_Thread * thread ;
2025-02-25 12:23:32 -08:00
SDL_Event event ;
window = SDL_CreateWindow ( " test " , 0 , 0 , SDL_WINDOW_HIDDEN ) ;
SDLTest_AssertCheck ( window ! = NULL , " Create window, expected non-NULL, got %p " , window ) ;
2024-12-05 12:35:23 -08:00
2025-02-25 12:23:32 -08:00
/* Flush any pending events */
SDL_PumpEvents ( ) ;
SDL_FlushEvents ( SDL_EVENT_FIRST , SDL_EVENT_LAST ) ;
/* Increment the counter on a thread, waiting for both calls to be queued */
thread = SDL_CreateThread ( IncrementCounterThread , NULL , & data ) ;
2024-12-05 12:35:23 -08:00
SDLTest_AssertCheck ( thread ! = NULL , " Create counter thread " ) ;
/* Wait for both increment calls to be queued up */
SDL_Delay ( 100 ) ;
/* Run the main callbacks */
2025-02-25 12:23:32 -08:00
SDL_WaitEvent ( & event ) ;
SDLTest_AssertCheck ( event . type = = SDL_EVENT_USER , " Expected user event (0x%.4x), got 0x%.4x " , SDL_EVENT_USER , ( int ) event . type ) ;
2024-12-05 12:35:23 -08:00
SDL_WaitThread ( thread , NULL ) ;
2025-02-25 12:23:32 -08:00
SDLTest_AssertCheck ( data . counter = = 3 , " Incremented counter on main thread, expected 3, got %d " , data . counter ) ;
2025-09-19 11:22:29 -04:00
/* Flush events again, as the previous SDL_WaitEvent() call may have pumped OS events and added them to the queue */
SDL_FlushEvents ( SDL_EVENT_FIRST , SDL_EVENT_LAST ) ;
2025-02-25 12:23:32 -08:00
/* Try again, but this time delay the calls until we've started waiting for events */
data . delay = 100 ;
thread = SDL_CreateThread ( IncrementCounterThread , NULL , & data ) ;
SDLTest_AssertCheck ( thread ! = NULL , " Create counter thread " ) ;
/* Run the main callbacks */
SDL_WaitEvent ( & event ) ;
SDLTest_AssertCheck ( event . type = = SDL_EVENT_USER , " Expected user event (0x%.4x), got 0x%.4x " , SDL_EVENT_USER , ( int ) event . type ) ;
SDL_WaitThread ( thread , NULL ) ;
SDLTest_AssertCheck ( data . counter = = 5 , " Incremented counter on main thread, expected 5, got %d " , data . counter ) ;
SDL_DestroyWindow ( window ) ;
2024-12-05 12:35:23 -08:00
}
# endif /* !SDL_PLATFORM_EMSCRIPTEN */
return TEST_COMPLETED ;
}
2015-06-21 17:33:46 +02:00
/* ================= Test References ================== */
/* Events test cases */
2024-08-02 23:47:03 +02:00
static const SDLTest_TestCaseReference eventsTest_pushPumpAndPollUserevent = {
events_pushPumpAndPollUserevent , " events_pushPumpAndPollUserevent " , " Pushes, pumps and polls a user event " , TEST_ENABLED
2022-11-30 12:51:59 -08:00
} ;
2015-06-21 17:33:46 +02:00
2024-08-02 23:47:03 +02:00
static const SDLTest_TestCaseReference eventsTest_addDelEventWatch = {
events_addDelEventWatch , " events_addDelEventWatch " , " Adds and deletes an event watch function with NULL userdata " , TEST_ENABLED
2022-11-30 12:51:59 -08:00
} ;
2015-06-21 17:33:46 +02:00
2024-08-02 23:47:03 +02:00
static const SDLTest_TestCaseReference eventsTest_addDelEventWatchWithUserdata = {
events_addDelEventWatchWithUserdata , " events_addDelEventWatchWithUserdata " , " Adds and deletes an event watch function with userdata " , TEST_ENABLED
2022-11-30 12:51:59 -08:00
} ;
2015-06-21 17:33:46 +02:00
2024-12-05 12:35:23 -08:00
static const SDLTest_TestCaseReference eventsTest_mainThreadCallbacks = {
events_mainThreadCallbacks , " events_mainThreadCallbacks " , " Run callbacks on the main thread " , TEST_ENABLED
} ;
2015-06-21 17:33:46 +02:00
/* Sequence of Events test cases */
2022-11-30 12:51:59 -08:00
static const SDLTest_TestCaseReference * eventsTests [ ] = {
2024-08-02 23:47:03 +02:00
& eventsTest_pushPumpAndPollUserevent ,
& eventsTest_addDelEventWatch ,
& eventsTest_addDelEventWatchWithUserdata ,
2024-12-05 12:35:23 -08:00
& eventsTest_mainThreadCallbacks ,
2024-08-02 23:47:03 +02:00
NULL
2015-06-21 17:33:46 +02:00
} ;
/* Events test suite (global) */
SDLTest_TestSuiteReference eventsTestSuite = {
" Events " ,
NULL ,
eventsTests ,
NULL
} ;