/* Copyright 2016, Ableton AG, Berlin. All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you would like to incorporate Link into a proprietary software application, * please contact . */ #pragma once #include #include #include #include #include namespace ableton { namespace test { namespace serial_io { class SchedulerTree { public: using TimePoint = std::chrono::system_clock::time_point; using TimerId = std::size_t; using TimerErrorCode = int; void run(); std::shared_ptr makeChild(); template void async(Handler handler) { mPendingHandlers.push_back(std::move(handler)); } template void setTimer(const TimerId timerId, const TimePoint expiration, Handler handler) { using namespace std; mTimers[make_pair(std::move(expiration), timerId)] = std::move(handler); } void cancelTimer(const TimerId timerId); // returns the time that the next timer in the subtree expires TimePoint nextTimerExpiration(); // triggers all timers in the subtree that expire at time t or before void triggerTimersUntil(const TimePoint t); private: // returns true if some work was done, false if there was none to do bool handlePending(); // returns the time that the next timer from this node expires TimePoint nextOwnTimerExpiration(); // Traversal function over children that cleans up children that // have been destroyed. template void withChildren(Fn fn) { auto it = begin(mChildren); while (it != end(mChildren)) { const auto childIt = it++; auto pChild = childIt->lock(); if (pChild) { fn(*pChild); } else { mChildren.erase(childIt); } } } using TimerHandler = std::function; using TimerMap = std::map, TimerHandler>; TimerMap mTimers; std::list> mPendingHandlers; std::list> mChildren; }; } // namespace serial_io } // namespace test } // namespace ableton