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 <chrono> 23 #include <functional> 24 25 namespace ableton 26 { 27 namespace util 28 { 29 namespace test 30 { 31 32 struct Timer 33 { 34 using ErrorCode = int; 35 using TimePoint = std::chrono::system_clock::time_point; 36 37 // Initialize timer with an arbitrary large value to simulate the 38 // time_since_epoch of a real clock. Timerableton::util::test::Timer39 Timer() 40 : mNow{std::chrono::milliseconds{123456789}} 41 { 42 } 43 expires_atableton::util::test::Timer44 void expires_at(std::chrono::system_clock::time_point t) 45 { 46 cancel(); 47 mFireAt = std::move(t); 48 } 49 50 template <typename T, typename Rep> expires_from_nowableton::util::test::Timer51 void expires_from_now(std::chrono::duration<T, Rep> duration) 52 { 53 cancel(); 54 mFireAt = now() + duration; 55 } 56 cancelableton::util::test::Timer57 ErrorCode cancel() 58 { 59 if (mHandler) 60 { 61 mHandler(1); // call existing handler with truthy error code 62 } 63 mHandler = nullptr; 64 return 0; 65 } 66 67 template <typename Handler> async_waitableton::util::test::Timer68 void async_wait(Handler handler) 69 { 70 mHandler = [handler](ErrorCode ec) { handler(ec); }; 71 } 72 nowableton::util::test::Timer73 std::chrono::system_clock::time_point now() const 74 { 75 return mNow; 76 } 77 78 template <typename T, typename Rep> advanceableton::util::test::Timer79 void advance(std::chrono::duration<T, Rep> duration) 80 { 81 mNow += duration; 82 if (mHandler && mFireAt < mNow) 83 { 84 mHandler(0); 85 mHandler = nullptr; 86 } 87 } 88 89 std::function<void(ErrorCode)> mHandler; 90 std::chrono::system_clock::time_point mFireAt; 91 std::chrono::system_clock::time_point mNow; 92 }; 93 94 } // namespace test 95 } // namespace util 96 } // namespace ableton 97