run_loop.cpp 2.1 KB

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