|
5 | 5 | #define FML_USED_ON_EMBEDDER |
6 | 6 |
|
7 | 7 | #include "flutter/fml/message_loop_task_queue.h" |
| 8 | +#include "flutter/fml/synchronization/count_down_latch.h" |
| 9 | +#include "flutter/fml/synchronization/waitable_event.h" |
8 | 10 | #include "gtest/gtest.h" |
9 | 11 |
|
| 12 | +class TestWakeable : public fml::Wakeable { |
| 13 | + public: |
| 14 | + using WakeUpCall = std::function<void(const fml::TimePoint)>; |
| 15 | + |
| 16 | + TestWakeable(WakeUpCall call) : wake_up_call_(call) {} |
| 17 | + |
| 18 | + void WakeUp(fml::TimePoint time_point) override { wake_up_call_(time_point); } |
| 19 | + |
| 20 | + private: |
| 21 | + WakeUpCall wake_up_call_; |
| 22 | +}; |
| 23 | + |
10 | 24 | TEST(MessageLoopTaskQueue, StartsWithNoPendingTasks) { |
11 | 25 | auto task_queue = std::make_unique<fml::MessageLoopTaskQueue>(); |
12 | 26 | ASSERT_FALSE(task_queue->HasPendingTasks()); |
13 | 27 | } |
14 | 28 |
|
15 | 29 | TEST(MessageLoopTaskQueue, RegisterOneTask) { |
16 | | - auto task_queue = std::make_unique<fml::MessageLoopTaskQueue>(); |
17 | 30 | const auto time = fml::TimePoint::Max(); |
18 | | - const auto wake_time = task_queue->RegisterTask([] {}, time); |
| 31 | + |
| 32 | + auto task_queue = std::make_unique<fml::MessageLoopTaskQueue>(); |
| 33 | + task_queue->SetWakeable(new TestWakeable( |
| 34 | + [&time](fml::TimePoint wake_time) { ASSERT_TRUE(wake_time == time); })); |
| 35 | + |
| 36 | + task_queue->RegisterTask([] {}, time); |
19 | 37 | ASSERT_TRUE(task_queue->HasPendingTasks()); |
20 | 38 | ASSERT_TRUE(task_queue->GetNumPendingTasks() == 1); |
21 | | - ASSERT_TRUE(wake_time == time); |
22 | 39 | } |
23 | 40 |
|
24 | 41 | TEST(MessageLoopTaskQueue, RegisterTwoTasksAndCount) { |
@@ -68,3 +85,51 @@ TEST(MessageLoopTaskQueue, AddRemoveNotifyObservers) { |
68 | 85 | task_queue->NotifyObservers(); |
69 | 86 | ASSERT_TRUE(test_val == 0); |
70 | 87 | } |
| 88 | + |
| 89 | +TEST(MessageLoopTaskQueue, WakeUpIndependentOfTime) { |
| 90 | + auto task_queue = std::make_unique<fml::MessageLoopTaskQueue>(); |
| 91 | + |
| 92 | + int num_wakes = 0; |
| 93 | + task_queue->SetWakeable(new TestWakeable( |
| 94 | + [&num_wakes](fml::TimePoint wake_time) { ++num_wakes; })); |
| 95 | + |
| 96 | + task_queue->RegisterTask([]() {}, fml::TimePoint::Now()); |
| 97 | + task_queue->RegisterTask([]() {}, fml::TimePoint::Max()); |
| 98 | + |
| 99 | + ASSERT_TRUE(num_wakes == 2); |
| 100 | +} |
| 101 | + |
| 102 | +TEST(MessageLoopTaskQueue, WakeUpWithMaxIfNoInvocations) { |
| 103 | + auto task_queue = std::make_unique<fml::MessageLoopTaskQueue>(); |
| 104 | + fml::AutoResetWaitableEvent ev; |
| 105 | + |
| 106 | + task_queue->SetWakeable(new TestWakeable([&ev](fml::TimePoint wake_time) { |
| 107 | + ASSERT_TRUE(wake_time == fml::TimePoint::Max()); |
| 108 | + ev.Signal(); |
| 109 | + })); |
| 110 | + |
| 111 | + std::vector<fml::closure> invocations; |
| 112 | + task_queue->GetTasksToRunNow(fml::FlushType::kAll, invocations); |
| 113 | + ev.Wait(); |
| 114 | +} |
| 115 | + |
| 116 | +TEST(MessageLoopTaskQueue, WokenUpWithNewerTime) { |
| 117 | + auto task_queue = std::make_unique<fml::MessageLoopTaskQueue>(); |
| 118 | + fml::CountDownLatch latch(2); |
| 119 | + |
| 120 | + fml::TimePoint expected = fml::TimePoint::Max(); |
| 121 | + |
| 122 | + task_queue->SetWakeable( |
| 123 | + new TestWakeable([&latch, &expected](fml::TimePoint wake_time) { |
| 124 | + ASSERT_TRUE(wake_time == expected); |
| 125 | + latch.CountDown(); |
| 126 | + })); |
| 127 | + |
| 128 | + task_queue->RegisterTask([]() {}, fml::TimePoint::Max()); |
| 129 | + |
| 130 | + const auto now = fml::TimePoint::Now(); |
| 131 | + expected = now; |
| 132 | + task_queue->RegisterTask([]() {}, now); |
| 133 | + |
| 134 | + latch.Wait(); |
| 135 | +} |
0 commit comments