#pragma once // timer.t.hpp - Future event scheduler. // // Copyright © ????-2004 Athena Dev Teams // Copyright © 2004-2011 The Mana World Development Team // Copyright © 2011-2014 Ben Longbons // // This file is part of The Mana World (Athena server) // // 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 3 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 . #include "fwd.hpp" #include #include #include #include "../ints/little.hpp" #include "../generic/dumb_ptr.hpp" namespace tmwa { constexpr std::chrono::nanoseconds operator "" _ns(unsigned long long ns) { return std::chrono::nanoseconds(ns); } constexpr std::chrono::microseconds operator "" _us(unsigned long long us) { return std::chrono::microseconds(us); } constexpr std::chrono::milliseconds operator "" _ms(unsigned long long ms) { return std::chrono::milliseconds(ms); } constexpr std::chrono::seconds operator "" _s(unsigned long long s) { return std::chrono::seconds(s); } constexpr std::chrono::minutes operator "" _min(unsigned long long min) { return std::chrono::minutes(min); } constexpr std::chrono::hours operator "" _h(unsigned long long h) { return std::chrono::hours(h); } constexpr std::chrono::duration> operator "" _d(unsigned long long d) { return std::chrono::duration>(d); } /// An implementation of the C++ "clock" concept, exposing /// durations in milliseconds. class milli_clock { public: typedef std::chrono::milliseconds duration; typedef duration::rep rep; typedef duration::period period; typedef std::chrono::time_point time_point; static const bool is_steady = true; // assumed - not necessarily true static time_point now() noexcept; }; /// A point in time. typedef milli_clock::time_point tick_t; /// The difference between two points in time. typedef milli_clock::duration interval_t; /// (to get additional arguments, use std::bind or a lambda). typedef std::function timer_func; // 49.7 day problem inline __attribute__((warn_unused_result)) bool native_to_network(Little32 *net, tick_t nat) { auto tmp = nat.time_since_epoch().count(); return native_to_network(net, static_cast(tmp)); } inline __attribute__((warn_unused_result)) bool network_to_native(tick_t *nat, Little32 net) { (void)nat; (void)net; abort(); } inline __attribute__((warn_unused_result)) bool native_to_network(Little32 *net, interval_t nat) { auto tmp = nat.count(); return native_to_network(net, static_cast(tmp)); } inline __attribute__((warn_unused_result)) bool network_to_native(interval_t *nat, Little32 net) { uint32_t tmp; bool rv = network_to_native(&tmp, net); *nat = interval_t(tmp); return rv; } inline __attribute__((warn_unused_result)) bool native_to_network(Little16 *net, interval_t nat) { auto tmp = nat.count(); return native_to_network(net, static_cast(tmp)); } inline __attribute__((warn_unused_result)) bool network_to_native(interval_t *nat, Little16 net) { uint16_t tmp; bool rv = network_to_native(&tmp, net); *nat = interval_t(tmp); return rv; } class Timer { friend struct TimerData; dumb_ptr td; Timer(const Timer&) = delete; Timer& operator = (const Timer&) = delete; public: /// Don't own anything yet. Timer() = default; /// Schedule a timer for the given tick. /// If you do not wish to keep track of it, call disconnect(). /// Otherwise, you may cancel() or replace (operator =) it later. /// /// If the interval argument is given, the timer will reschedule /// itself again forever. Otherwise, it will disconnect() itself /// just BEFORE it is called. Timer(tick_t tick, timer_func func, interval_t interval=interval_t::zero()); Timer(Timer&& t); Timer& operator = (Timer&& t); ~Timer() { cancel(); } /// Cancel the delivery of this timer's function, and make it falsy. /// Implementation note: this doesn't actually remove it, just sets /// the functor to do_nothing, and waits for the tick before removing. void cancel(); /// Make it falsy without cancelling the timer, void detach(); /// Check if there is a timer connected. explicit operator bool() { return bool(td); } /// Check if there is no connected timer. bool operator !() { return !td; } }; } // namespace tmwa