mirror of
				https://github.com/glfw/glfw.git
				synced 2025-11-03 22:04:15 +00:00 
			
		
		
		
	Add glfwWaitEventsTimeout
This function will put the calling thread to sleep until an event arrives or until the specified timeout has elapsed.
This commit is contained in:
		
							parent
							
								
									337c77a39b
								
							
						
					
					
						commit
						5620895e88
					
				@ -83,6 +83,7 @@ does not find Doxygen, the documentation will not be generated.
 | 
				
			|||||||
   absolute and relative window size limits
 | 
					   absolute and relative window size limits
 | 
				
			||||||
 - Added `glfwGetKeyName` for querying the layout-specific name of printable
 | 
					 - Added `glfwGetKeyName` for querying the layout-specific name of printable
 | 
				
			||||||
   keys
 | 
					   keys
 | 
				
			||||||
 | 
					 - Added `glfwWaitEventsTimeout` for waiting for events for a set amount of time
 | 
				
			||||||
 - Added `glfwGetTimerValue` and `glfwGetTimerFrequency` for raw timer access
 | 
					 - Added `glfwGetTimerValue` and `glfwGetTimerFrequency` for raw timer access
 | 
				
			||||||
 - Added `GLFWuint64` for platform-independent 64-bit unsigned values
 | 
					 - Added `GLFWuint64` for platform-independent 64-bit unsigned values
 | 
				
			||||||
 - Added `GLFW_NO_API` for creating window without contexts
 | 
					 - Added `GLFW_NO_API` for creating window without contexts
 | 
				
			||||||
 | 
				
			|||||||
@ -58,6 +58,17 @@ processes all received events.  This saves a great deal of CPU cycles and is
 | 
				
			|||||||
useful for, for example, editing tools.  There must be at least one GLFW window
 | 
					useful for, for example, editing tools.  There must be at least one GLFW window
 | 
				
			||||||
for this function to sleep.
 | 
					for this function to sleep.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to wait for events but have UI elements that need periodic updates,
 | 
				
			||||||
 | 
					call @ref glfwWaitEventsTimeout.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@code
 | 
				
			||||||
 | 
					glfwWaitEventsTimeout(0.7);
 | 
				
			||||||
 | 
					@endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It puts the thread to sleep until at least one event has been received, or until
 | 
				
			||||||
 | 
					the specified number of seconds have elapsed.  It then processes any received
 | 
				
			||||||
 | 
					events.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from
 | 
					If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from
 | 
				
			||||||
another thread by posting an empty event to the event queue with @ref
 | 
					another thread by posting an empty event to the event queue with @ref
 | 
				
			||||||
glfwPostEmptyEvent.
 | 
					glfwPostEmptyEvent.
 | 
				
			||||||
 | 
				
			|||||||
@ -43,6 +43,12 @@ GLFW now supports raw timer values with @ref glfwGetTimerValue and @ref
 | 
				
			|||||||
glfwGetTimerFrequency.
 | 
					glfwGetTimerFrequency.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@subsection news_32_waittimeout Wait for events with timeout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GLFW now supports waiting for events for a set amount of time with @ref
 | 
				
			||||||
 | 
					glfwWaitEventsTimeout.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@section news_31 New features in 3.1
 | 
					@section news_31 New features in 3.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
These are the release highlights.  For a full list of changes see the
 | 
					These are the release highlights.  For a full list of changes see the
 | 
				
			||||||
 | 
				
			|||||||
@ -2633,6 +2633,7 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @sa @ref events
 | 
					 *  @sa @ref events
 | 
				
			||||||
 *  @sa glfwWaitEvents
 | 
					 *  @sa glfwWaitEvents
 | 
				
			||||||
 | 
					 *  @sa glfwWaitEventsTimeout
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @since Added in version 1.0.
 | 
					 *  @since Added in version 1.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -2677,6 +2678,7 @@ GLFWAPI void glfwPollEvents(void);
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @sa @ref events
 | 
					 *  @sa @ref events
 | 
				
			||||||
 *  @sa glfwPollEvents
 | 
					 *  @sa glfwPollEvents
 | 
				
			||||||
 | 
					 *  @sa glfwWaitEventsTimeout
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @since Added in version 2.5.
 | 
					 *  @since Added in version 2.5.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -2684,6 +2686,52 @@ GLFWAPI void glfwPollEvents(void);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
GLFWAPI void glfwWaitEvents(void);
 | 
					GLFWAPI void glfwWaitEvents(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! @brief Waits with timeout until events are queued and processes them.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This function puts the calling thread to sleep until at least one event is
 | 
				
			||||||
 | 
					 *  available in the event queue, or until the specified timeout is reached.  If
 | 
				
			||||||
 | 
					 *  one or more events are available, it behaves exactly like @ref
 | 
				
			||||||
 | 
					 *  glfwPollEvents, i.e. the events in the queue are processed and the function
 | 
				
			||||||
 | 
					 *  then returns immediately.  Processing events will cause the window and input
 | 
				
			||||||
 | 
					 *  callbacks associated with those events to be called.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  The timeout value must be a positive finite number.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Since not all events are associated with callbacks, this function may return
 | 
				
			||||||
 | 
					 *  without a callback having been called even if you are monitoring all
 | 
				
			||||||
 | 
					 *  callbacks.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  On some platforms, a window move, resize or menu operation will cause event
 | 
				
			||||||
 | 
					 *  processing to block.  This is due to how event processing is designed on
 | 
				
			||||||
 | 
					 *  those platforms.  You can use the
 | 
				
			||||||
 | 
					 *  [window refresh callback](@ref window_refresh) to redraw the contents of
 | 
				
			||||||
 | 
					 *  your window when necessary during such operations.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  On some platforms, certain callbacks may be called outside of a call to one
 | 
				
			||||||
 | 
					 *  of the event processing functions.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  If no windows exist, this function returns immediately.  For synchronization
 | 
				
			||||||
 | 
					 *  of threads in applications that do not create windows, use your threading
 | 
				
			||||||
 | 
					 *  library of choice.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Event processing is not required for joystick input to work.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @param[in] timeout The maximum amount of time, in seconds, to wait.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @reentrancy This function must not be called from a callback.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @thread_safety This function must only be called from the main thread.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @sa @ref events
 | 
				
			||||||
 | 
					 *  @sa glfwPollEvents
 | 
				
			||||||
 | 
					 *  @sa glfwWaitEvents
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @since Added in version 3.2.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @ingroup window
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					GLFWAPI void glfwWaitEventsTimeout(double timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @brief Posts an empty event to the event queue.
 | 
					/*! @brief Posts an empty event to the event queue.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  This function posts an empty event from the current thread to the event
 | 
					 *  This function posts an empty event from the current thread to the event
 | 
				
			||||||
 | 
				
			|||||||
@ -1214,6 +1214,19 @@ void _glfwPlatformWaitEvents(void)
 | 
				
			|||||||
    _glfwPlatformPollEvents();
 | 
					    _glfwPlatformPollEvents();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void _glfwPlatformWaitEventsTimeout(double timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];
 | 
				
			||||||
 | 
					    NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
 | 
				
			||||||
 | 
					                                        untilDate:date
 | 
				
			||||||
 | 
					                                           inMode:NSDefaultRunLoopMode
 | 
				
			||||||
 | 
					                                          dequeue:YES];
 | 
				
			||||||
 | 
					    if (event)
 | 
				
			||||||
 | 
					        [NSApp sendEvent:event];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _glfwPlatformPollEvents();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwPlatformPostEmptyEvent(void)
 | 
					void _glfwPlatformPostEmptyEvent(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 | 
					    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 | 
				
			||||||
 | 
				
			|||||||
@ -717,6 +717,11 @@ void _glfwPlatformPollEvents(void);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void _glfwPlatformWaitEvents(void);
 | 
					void _glfwPlatformWaitEvents(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! @copydoc glfwWaitEventsTimeout
 | 
				
			||||||
 | 
					 *  @ingroup platform
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void _glfwPlatformWaitEventsTimeout(double timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @copydoc glfwPostEmptyEvent
 | 
					/*! @copydoc glfwPostEmptyEvent
 | 
				
			||||||
 *  @ingroup platform
 | 
					 *  @ingroup platform
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
				
			|||||||
@ -550,6 +550,24 @@ void _glfwPlatformWaitEvents(void)
 | 
				
			|||||||
    _glfwPlatformPollEvents();
 | 
					    _glfwPlatformPollEvents();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void _glfwPlatformWaitEventsTimeout(double timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    pthread_mutex_lock(&_glfw.mir.event_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (emptyEventQueue(_glfw.mir.event_queue))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        struct timespec time;
 | 
				
			||||||
 | 
					        clock_gettime(CLOCK_REALTIME, &time);
 | 
				
			||||||
 | 
					        time.tv_sec += (long) timeout;
 | 
				
			||||||
 | 
					        time.tv_nsec += (long) ((timeout - (long) timeout) * 1e9);
 | 
				
			||||||
 | 
					        pthread_cond_timedwait(&_glfw.mir.event_cond, &_glfw.mir.event_mutex, &time);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pthread_mutex_unlock(&_glfw.mir.event_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _glfwPlatformPollEvents();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwPlatformPostEmptyEvent(void)
 | 
					void _glfwPlatformPostEmptyEvent(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1142,6 +1142,13 @@ void _glfwPlatformWaitEvents(void)
 | 
				
			|||||||
    _glfwPlatformPollEvents();
 | 
					    _glfwPlatformPollEvents();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void _glfwPlatformWaitEventsTimeout(double timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _glfwPlatformPollEvents();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwPlatformPostEmptyEvent(void)
 | 
					void _glfwPlatformPostEmptyEvent(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFWwindow* window = _glfw.windowListHead;
 | 
					    _GLFWwindow* window = _glfw.windowListHead;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								src/window.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/window.c
									
									
									
									
									
								
							@ -31,6 +31,7 @@
 | 
				
			|||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <float.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@ -807,6 +808,19 @@ GLFWAPI void glfwWaitEvents(void)
 | 
				
			|||||||
    _glfwPlatformWaitEvents();
 | 
					    _glfwPlatformWaitEvents();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GLFWAPI void glfwWaitEventsTimeout(double timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _GLFW_REQUIRE_INIT();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _glfwInputError(GLFW_INVALID_VALUE, "Invalid time");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _glfwPlatformWaitEventsTimeout(timeout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI void glfwPostEmptyEvent(void)
 | 
					GLFWAPI void glfwPostEmptyEvent(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFW_REQUIRE_INIT();
 | 
					    _GLFW_REQUIRE_INIT();
 | 
				
			||||||
 | 
				
			|||||||
@ -516,6 +516,11 @@ void _glfwPlatformWaitEvents(void)
 | 
				
			|||||||
    handleEvents(-1);
 | 
					    handleEvents(-1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void _glfwPlatformWaitEventsTimeout(double timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    handleEvents((int) (timeout * 1e3));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwPlatformPostEmptyEvent(void)
 | 
					void _glfwPlatformPostEmptyEvent(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    wl_display_sync(_glfw.wl.display);
 | 
					    wl_display_sync(_glfw.wl.display);
 | 
				
			||||||
 | 
				
			|||||||
@ -1912,6 +1912,28 @@ void _glfwPlatformWaitEvents(void)
 | 
				
			|||||||
    _glfwPlatformPollEvents();
 | 
					    _glfwPlatformPollEvents();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void _glfwPlatformWaitEventsTimeout(double timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const double deadline = timeout + _glfwPlatformGetTimerValue() /
 | 
				
			||||||
 | 
					        (double) _glfwPlatformGetTimerFrequency();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (!XPending(_glfw.x11.display))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const double remaining = deadline - _glfwPlatformGetTimerValue() /
 | 
				
			||||||
 | 
					            (double) _glfwPlatformGetTimerFrequency();
 | 
				
			||||||
 | 
					        if (remaining <= 0.0)
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const long seconds = (long) remaining;
 | 
				
			||||||
 | 
					        const long microseconds = (long) ((remaining - seconds) * 1e6);
 | 
				
			||||||
 | 
					        struct timeval tv = { seconds, microseconds };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        selectDisplayConnection(&tv);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _glfwPlatformPollEvents();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwPlatformPostEmptyEvent(void)
 | 
					void _glfwPlatformPostEmptyEvent(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    XEvent event;
 | 
					    XEvent event;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user