1 /* Copyright 2016, Ableton AG, Berlin. All rights reserved.
2  *
3  *  This program is free software: you can redistribute it and/or modify
4  *  it under the terms of the GNU General Public License as published by
5  *  the Free Software Foundation, either version 2 of the License, or
6  *  (at your option) any later version.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  *  If you would like to incorporate Link into a proprietary software application,
17  *  please contact <link-devs@ableton.com>.
18  */
19 
20 #pragma once
21 
22 #include <ableton/test/serial_io/SchedulerTree.hpp>
23 
24 namespace ableton
25 {
26 namespace test
27 {
28 namespace serial_io
29 {
30 
31 struct Timer
32 {
33   using ErrorCode = SchedulerTree::TimerErrorCode;
34   using TimePoint = SchedulerTree::TimePoint;
35 
Timerableton::test::serial_io::Timer36   Timer(const SchedulerTree::TimerId timerId,
37     const TimePoint& now,
38     std::shared_ptr<SchedulerTree> pScheduler)
39     : mId(timerId)
40     , mNow(now)
41     , mpScheduler(std::move(pScheduler))
42   {
43   }
44 
~Timerableton::test::serial_io::Timer45   ~Timer()
46   {
47     if (!mbMovedFrom)
48     {
49       cancel();
50     }
51   }
52 
53   Timer(const Timer&) = delete;
54 
Timerableton::test::serial_io::Timer55   Timer(Timer&& rhs)
56     : mId(rhs.mId)
57     , mNow(rhs.mNow)
58     , mExpiration(std::move(rhs.mExpiration))
59     , mpScheduler(std::move(rhs.mpScheduler))
60   {
61     rhs.mbMovedFrom = true;
62   }
63 
expires_atableton::test::serial_io::Timer64   void expires_at(const TimePoint t)
65   {
66     if (t < mNow)
67     {
68       throw std::runtime_error("Setting timer in the past");
69     }
70     else
71     {
72       cancel();
73       mExpiration = t;
74     }
75   }
76 
77   template <typename T, typename Rep>
expires_from_nowableton::test::serial_io::Timer78   void expires_from_now(std::chrono::duration<T, Rep> duration)
79   {
80     expires_at(mNow + duration);
81   }
82 
cancelableton::test::serial_io::Timer83   void cancel()
84   {
85     auto pScheduler = mpScheduler.lock();
86     pScheduler->cancelTimer(mId);
87   }
88 
89   template <typename Handler>
async_waitableton::test::serial_io::Timer90   void async_wait(Handler handler)
91   {
92     auto pScheduler = mpScheduler.lock();
93     pScheduler->setTimer(mId, mExpiration, std::move(handler));
94   }
95 
nowableton::test::serial_io::Timer96   TimePoint now() const
97   {
98     return mNow;
99   }
100 
101   const SchedulerTree::TimerId mId;
102   const TimePoint& mNow;
103   TimePoint mExpiration;
104   std::weak_ptr<SchedulerTree> mpScheduler;
105   bool mbMovedFrom = false;
106 };
107 
108 } // namespace serial_io
109 } // namespace test
110 } // namespace ableton
111