summaryrefslogblamecommitdiff
path: root/src/net/timer.t.hpp
blob: 090e62a0b84a4c98d3fa5f56bff3c0afd3b7a8f3 (plain) (tree)
1
            




















                                                                           
                  
 
                  
 

                     
 
                             
 
                                  
 


              
         
                                                               

                                        
                                                                

                                         
                                                                

                                         
                                                         

                                   
                                                             

                                     
                                                       

                                 
                                                                                     

                                                               

















                                                                         

                                                             
 
















































                                                              


                            
                           




                                              
                      




















                                                                                
                                                 


                                             
                   
#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 <b.r.longbons@gmail.com>
//
//    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 <http://www.gnu.org/licenses/>.

#include "fwd.hpp"

#include <cstdlib>

#include <chrono>
#include <functional>

#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<int, std::ratio<60*60*24>> operator "" _d(unsigned long long d)
{ return std::chrono::duration<int, std::ratio<60*60*24>>(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<milli_clock, duration> 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<void (TimerData *, tick_t)> 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<uint32_t>(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<uint32_t>(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<uint16_t>(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<TimerData> 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