Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
WaitSupport.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
6#if qStroika_Foundation_Common_Platform_Windows
7#include <Windows.h>
8#else
9#error "WINDOWS REQUIRED FOR THIS MODULE"
10#endif
11
12#include "Stroika/Foundation/Common/Common.h"
13#include "Stroika/Foundation/Containers/Common.h"
16
18
19#include "WaitSupport.h"
20
21using namespace Stroika::Foundation;
22using namespace Stroika::Foundation::Execution;
23using namespace Stroika::Foundation::Execution::Platform;
25
26/*
27 ********************************************************************************
28 ********************************** WaitSupport *********************************
29 ********************************************************************************
30 */
31
32/*
33 * Call this if you want to pump messages and want to block/wait for a while if need be (to avoid busy-waiting).
34 */
36{
37 Windows::WaitAndPumpMessages (dialog, vector<HANDLE> (), forNSecs);
38}
39
40void Windows::WaitAndPumpMessages (HWND dialog, const vector<HANDLE>& waitOn, Time::DurationSeconds forNSecs)
41{
42 Time::TimePointSeconds startAt = Time::GetTickCount ();
43 Time::TimePointSeconds endAt = startAt + forNSecs;
44
45 for (Time::DurationSeconds timeLeft = endAt - Time::GetTickCount (); timeLeft > 0s; timeLeft = endAt - Time::GetTickCount ()) {
47 DWORD waitResult = ::MsgWaitForMultipleObjectsEx (static_cast<DWORD> (waitOn.size ()), Containers::Start (waitOn),
48 Platform::Windows::Duration2Milliseconds (timeLeft), QS_ALLEVENTS, MWMO_INPUTAVAILABLE);
49 if (WAIT_OBJECT_0 <= waitResult and waitResult < WAIT_OBJECT_0 + waitOn.size ()) {
50 return;
51 }
52 MSG msg;
53 while (::PeekMessage (&msg, nullptr, 0, 0, PM_REMOVE)) {
54 try {
55 if (dialog == nullptr or not::IsDialogMessage (dialog, &msg)) {
56 ::TranslateMessage (&msg);
57 ::DispatchMessage (&msg);
58 }
59 }
60 catch (...) {
61 }
62 timeLeft = endAt - Time::GetTickCount ();
63 if (timeLeft < 0s) {
64 break;
65 }
66 }
67 }
68}
69
70/*
71 * Call this if you want to pump messages, but return immediately if none available (e.g. when you are
72 * doing something else).
73 */
74void Windows::PumpMessagesWhileInputAvailable (HWND dialog, Time::DurationSeconds atMostNSecs)
75{
76 Time::TimePointSeconds startAt = Time::GetTickCount ();
77 Time::TimePointSeconds endAt = startAt + atMostNSecs;
78
79 MSG msg;
80 while (::PeekMessage (&msg, nullptr, 0, 0, PM_REMOVE)) {
81 try {
82 if (dialog == nullptr or not::IsDialogMessage (dialog, &msg)) {
83 ::TranslateMessage (&msg);
84 ::DispatchMessage (&msg);
85 }
86 }
87 catch (...) {
88 }
89 if (endAt < Time::GetTickCount ()) {
90 break; // should be only rarely triggered, except if atMostNSecs <= 0
91 }
92 }
93}
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
Definition Realtime.h:82
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Definition Realtime.h:57
CONTAINER::value_type * Start(CONTAINER &c)
For a contiguous container (such as a vector or basic_string) - find the pointer to the start of the ...
void WaitAndPumpMessages(HWND dialog=nullptr, Time::DurationSeconds forNSecs=0.1s)