run_loop.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "run_loop.h"
  2. #include <Windows.h>
  3. // Don't stomp std::min/std::max
  4. #undef max
  5. #undef min
  6. #include <algorithm>
  7. RunLoop::RunLoop() {}
  8. RunLoop::~RunLoop() {}
  9. void RunLoop::Run() {
  10. bool keep_running = true;
  11. TimePoint next_flutter_event_time = TimePoint::clock::now();
  12. while (keep_running) {
  13. std::chrono::nanoseconds wait_duration =
  14. std::max(std::chrono::nanoseconds(0),
  15. next_flutter_event_time - TimePoint::clock::now());
  16. ::MsgWaitForMultipleObjects(
  17. 0, nullptr, FALSE, static_cast<DWORD>(wait_duration.count() / 1000),
  18. QS_ALLINPUT);
  19. bool processed_events = false;
  20. MSG message;
  21. // All pending Windows messages must be processed; MsgWaitForMultipleObjects
  22. // won't return again for items left in the queue after PeekMessage.
  23. while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) {
  24. processed_events = true;
  25. if (message.message == WM_QUIT) {
  26. keep_running = false;
  27. break;
  28. }
  29. ::TranslateMessage(&message);
  30. ::DispatchMessage(&message);
  31. // Allow Flutter to process messages each time a Windows message is
  32. // processed, to prevent starvation.
  33. next_flutter_event_time =
  34. std::min(next_flutter_event_time, ProcessFlutterMessages());
  35. }
  36. // If the PeekMessage loop didn't run, process Flutter messages.
  37. if (!processed_events) {
  38. next_flutter_event_time =
  39. std::min(next_flutter_event_time, ProcessFlutterMessages());
  40. }
  41. }
  42. }
  43. void RunLoop::RegisterFlutterInstance(
  44. flutter::FlutterViewController* flutter_instance) {
  45. flutter_instances_.insert(flutter_instance);
  46. }
  47. void RunLoop::UnregisterFlutterInstance(
  48. flutter::FlutterViewController* flutter_instance) {
  49. flutter_instances_.erase(flutter_instance);
  50. }
  51. RunLoop::TimePoint RunLoop::ProcessFlutterMessages() {
  52. TimePoint next_event_time = TimePoint::max();
  53. for (auto flutter_controller : flutter_instances_) {
  54. std::chrono::nanoseconds wait_duration =
  55. flutter_controller->ProcessMessages();
  56. if (wait_duration != std::chrono::nanoseconds::max()) {
  57. next_event_time =
  58. std::min(next_event_time, TimePoint::clock::now() + wait_duration);
  59. }
  60. }
  61. return next_event_time;
  62. }