• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 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 #pragma once
15 
16 #include "pw_async/dispatcher.h"
17 #include "pw_async_backend/fake_dispatcher.h"  // nogncheck
18 
19 namespace pw::async::test {
20 
21 /// FakeDispatcher is a facade for an implementation of Dispatcher that is used
22 /// in unit tests. FakeDispatcher uses simulated time. RunUntil() and RunFor()
23 /// advance time immediately, and now() returns the current simulated time.
24 ///
25 /// To support various Task backends, FakeDispatcher wraps a
26 /// backend::NativeFakeDispatcher that implements standard FakeDispatcher
27 /// behavior using backend::NativeTask objects.
28 class FakeDispatcher final : public Dispatcher {
29  public:
FakeDispatcher()30   FakeDispatcher() : native_dispatcher_(*this) {}
31 
32   /// Execute all runnable tasks and return without advancing simulated time.
RunUntilIdle()33   void RunUntilIdle() { native_dispatcher_.RunUntilIdle(); }
34 
35   /// Run the dispatcher until Now() has reached `end_time`, executing all tasks
36   /// that come due before then.
RunUntil(chrono::SystemClock::time_point end_time)37   void RunUntil(chrono::SystemClock::time_point end_time) {
38     native_dispatcher_.RunUntil(end_time);
39   }
40 
41   /// Run the Dispatcher until `duration` has elapsed, executing all tasks that
42   /// come due in that period.
RunFor(chrono::SystemClock::duration duration)43   void RunFor(chrono::SystemClock::duration duration) {
44     native_dispatcher_.RunFor(duration);
45   }
46 
47   /// Stop processing tasks. After calling RequestStop(), the next time the
48   /// Dispatcher is run, all waiting Tasks will be dequeued and their
49   /// TaskFunctions called with a PW_STATUS_CANCELLED status.
RequestStop()50   void RequestStop() { native_dispatcher_.RequestStop(); }
51 
52   // Dispatcher overrides:
Post(Task & task)53   void Post(Task& task) override { native_dispatcher_.Post(task); }
PostAfter(Task & task,chrono::SystemClock::duration delay)54   void PostAfter(Task& task, chrono::SystemClock::duration delay) override {
55     native_dispatcher_.PostAfter(task, delay);
56   }
PostAt(Task & task,chrono::SystemClock::time_point time)57   void PostAt(Task& task, chrono::SystemClock::time_point time) override {
58     native_dispatcher_.PostAt(task, time);
59   }
PostPeriodic(Task & task,chrono::SystemClock::duration interval)60   void PostPeriodic(Task& task,
61                     chrono::SystemClock::duration interval) override {
62     native_dispatcher_.PostPeriodic(task, interval);
63   }
PostPeriodicAt(Task & task,chrono::SystemClock::duration interval,chrono::SystemClock::time_point start_time)64   void PostPeriodicAt(Task& task,
65                       chrono::SystemClock::duration interval,
66                       chrono::SystemClock::time_point start_time) override {
67     native_dispatcher_.PostPeriodicAt(task, interval, start_time);
68   }
Cancel(Task & task)69   bool Cancel(Task& task) override { return native_dispatcher_.Cancel(task); }
70 
71   // VirtualSystemClock overrides:
now()72   chrono::SystemClock::time_point now() override {
73     return native_dispatcher_.now();
74   }
75 
76   // Returns the inner NativeFakeDispatcher containing backend-specific
77   // state/logic. Only non-portable code should call these methods!
native_type()78   backend::NativeFakeDispatcher& native_type() { return native_dispatcher_; }
native_type()79   const backend::NativeFakeDispatcher& native_type() const {
80     return native_dispatcher_;
81   }
82 
83  private:
84   backend::NativeFakeDispatcher native_dispatcher_;
85 };
86 
87 }  // namespace pw::async::test
88