xref: /aosp_15_r20/external/pigweed/pw_async2/examples/coro_blinky_loop.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_async2/coro.h"
16 #include "pw_async2/dispatcher.h"
17 #include "pw_async2/simulated_time_provider.h"
18 #include "pw_chrono/system_clock.h"
19 #include "pw_result/result.h"
20 #include "pw_status/status.h"
21 
22 namespace {
23 
24 using ::pw::OkStatus;
25 using ::pw::Result;
26 using ::pw::Status;
27 using ::pw::async2::Coro;
28 using ::pw::async2::CoroContext;
29 using ::pw::async2::TimeProvider;
30 using ::pw::chrono::SystemClock;
31 using ::std::chrono_literals::operator""ms;
32 
33 class Led {
34  public:
TurnOn()35   void TurnOn() {}
TurnOff()36   void TurnOff() {}
37 };
38 
39 // DOCSTAG: [pw_async2-examples-coro-blinky-loop]
Blink(CoroContext &,TimeProvider<SystemClock> & time,Led & led,int times)40 Coro<Status> Blink(CoroContext&,
41                    TimeProvider<SystemClock>& time,
42                    Led& led,
43                    int times) {
44   for (int i = 0; i < times; ++i) {
45     led.TurnOn();
46     co_await time.WaitFor(500ms);
47     led.TurnOff();
48     co_await time.WaitFor(500ms);
49   }
50   led.TurnOff();
51   co_return OkStatus();
52 }
53 // DOCSTAG: [pw_async2-examples-coro-blinky-loop]
54 
55 }  // namespace
56 
57 #include "pw_allocator/testing.h"
58 
59 namespace {
60 
61 using ::pw::OkStatus;
62 using ::pw::allocator::test::AllocatorForTest;
63 using ::pw::async2::Context;
64 using ::pw::async2::Coro;
65 using ::pw::async2::CoroContext;
66 using ::pw::async2::Dispatcher;
67 using ::pw::async2::Pending;
68 using ::pw::async2::Poll;
69 using ::pw::async2::Ready;
70 using ::pw::async2::SimulatedTimeProvider;
71 using ::pw::async2::Task;
72 
73 class ExpectCoroTask final : public Task {
74  public:
ExpectCoroTask(Coro<pw::Status> && coro)75   ExpectCoroTask(Coro<pw::Status>&& coro) : coro_(std::move(coro)) {}
76 
77  private:
DoPend(Context & cx)78   Poll<> DoPend(Context& cx) final {
79     Poll<Status> result = coro_.Pend(cx);
80     if (result.IsPending()) {
81       return Pending();
82     }
83     EXPECT_EQ(*result, OkStatus());
84     return Ready();
85   }
86   Coro<pw::Status> coro_;
87 };
88 
TEST(CoroExample,ReturnsOk)89 TEST(CoroExample, ReturnsOk) {
90   AllocatorForTest<512> alloc;
91   CoroContext coro_cx(alloc);
92   SimulatedTimeProvider<SystemClock> time;
93   Led led;
94   ExpectCoroTask task = Blink(coro_cx, time, led, /*times=*/3);
95   Dispatcher dispatcher;
96   dispatcher.Post(task);
97   while (dispatcher.RunUntilStalled().IsPending()) {
98     time.AdvanceUntilNextExpiration();
99   }
100 }
101 
102 }  // namespace
103