mirror of
https://github.com/glfw/glfw.git
synced 2024-11-25 19:42:00 +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
|
||||
- Added `glfwGetKeyName` for querying the layout-specific name of printable
|
||||
keys
|
||||
- Added `glfwWaitEventsTimeout` for waiting for events for a set amount of time
|
||||
- Added `glfwGetTimerValue` and `glfwGetTimerFrequency` for raw timer access
|
||||
- Added `GLFWuint64` for platform-independent 64-bit unsigned values
|
||||
- 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
|
||||
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
|
||||
another thread by posting an empty event to the event queue with @ref
|
||||
glfwPostEmptyEvent.
|
||||
|
@ -43,6 +43,12 @@ GLFW now supports raw timer values with @ref glfwGetTimerValue and @ref
|
||||
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
|
||||
|
||||
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 glfwWaitEvents
|
||||
* @sa glfwWaitEventsTimeout
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
*
|
||||
@ -2677,6 +2678,7 @@ GLFWAPI void glfwPollEvents(void);
|
||||
*
|
||||
* @sa @ref events
|
||||
* @sa glfwPollEvents
|
||||
* @sa glfwWaitEventsTimeout
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
*
|
||||
@ -2684,6 +2686,52 @@ GLFWAPI void glfwPollEvents(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.
|
||||
*
|
||||
* This function posts an empty event from the current thread to the event
|
||||
|
@ -1214,6 +1214,19 @@ void _glfwPlatformWaitEvents(void)
|
||||
_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)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
@ -717,6 +717,11 @@ void _glfwPlatformPollEvents(void);
|
||||
*/
|
||||
void _glfwPlatformWaitEvents(void);
|
||||
|
||||
/*! @copydoc glfwWaitEventsTimeout
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformWaitEventsTimeout(double timeout);
|
||||
|
||||
/*! @copydoc glfwPostEmptyEvent
|
||||
* @ingroup platform
|
||||
*/
|
||||
|
@ -550,6 +550,24 @@ void _glfwPlatformWaitEvents(void)
|
||||
_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)
|
||||
{
|
||||
}
|
||||
|
@ -1142,6 +1142,13 @@ void _glfwPlatformWaitEvents(void)
|
||||
_glfwPlatformPollEvents();
|
||||
}
|
||||
|
||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||
{
|
||||
MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);
|
||||
|
||||
_glfwPlatformPollEvents();
|
||||
}
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.windowListHead;
|
||||
|
14
src/window.c
14
src/window.c
@ -31,6 +31,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -807,6 +808,19 @@ GLFWAPI void glfwWaitEvents(void)
|
||||
_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)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
@ -516,6 +516,11 @@ void _glfwPlatformWaitEvents(void)
|
||||
handleEvents(-1);
|
||||
}
|
||||
|
||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||
{
|
||||
handleEvents((int) (timeout * 1e3));
|
||||
}
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
wl_display_sync(_glfw.wl.display);
|
||||
|
@ -1912,6 +1912,28 @@ void _glfwPlatformWaitEvents(void)
|
||||
_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)
|
||||
{
|
||||
XEvent event;
|
||||
|
Loading…
Reference in New Issue
Block a user