Program Listing for File timeout.hpp

Return to documentation for file (src/tap/architecture/timeout.hpp)

/*
 * Copyright (c) 2020-2021 Advanced Robotics at the University of Washington <robomstr@uw.edu>
 *
 * This file is part of Taproot.
 *
 * Taproot 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.
 *
 * Taproot 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 Taproot.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef TAPROOT_TIMEOUT_HPP_
#define TAPROOT_TIMEOUT_HPP_

#include <cstdint>

#include "clock.hpp"

namespace tap
{
namespace arch
{
template <uint32_t (*T)()>
class Timeout
{
    template <typename H>
    friend class PeriodicTimer;

private:
    bool isRunning;
    bool isExecuted;
    uint32_t expireTime;

public:
    static constexpr auto TimeFunc = T;

    Timeout()
    {
        stop();
        this->expireTime = 0;
    }

    explicit Timeout(uint32_t timeout) { restart(timeout); }

    inline void restart(uint32_t timeout)
    {
        this->isRunning = true;
        this->isExecuted = false;
        this->expireTime = TimeFunc() + timeout;
    }

    inline void stop()
    {
        this->isRunning = false;
        this->isExecuted = false;
    }

    inline bool isStopped() const { return !this->isRunning; }

    inline bool isExpired() const { return this->isRunning && TimeFunc() >= this->expireTime; }

    inline uint32_t timeRemaining() const
    {
        if (this->isRunning && TimeFunc() < this->expireTime)
            return this->expireTime - TimeFunc();
        else
            return 0;
    }

    inline bool execute()
    {
        if (!isExecuted && isExpired())
        {
            isExecuted = true;
            return true;
        }

        return false;
    }
};

using MicroTimeout = Timeout<tap::arch::clock::getTimeMicroseconds>;
using MilliTimeout = Timeout<tap::arch::clock::getTimeMilliseconds>;
}  // namespace arch
}  // namespace tap

#endif  // TAPROOT_TIMEOUT_HPP_