<commit_before>/**
 * Created by <NAME>
 * @since  2017.02.03
 * @author <NAME> <<EMAIL>>
 * @link   http://chensoft.com
 */
#pragma once

#include <socket/base/ev_base.hpp>
#include <functional>
#include <chrono>

namespace chen
{
    class ev_timer: public ev_base
    {
    public:
        ev_timer(std::function<void ()> cb = nullptr);

    public:
        /**
         * Invoke callback only once after a period of time
         */
        void timeout(const std::chrono::nanoseconds &value);

        /**
         * Invoke callback only once in a future calendar date
         */
        void future(const std::chrono::high_resolution_clock::time_point &value);

        /**
         * Invoke callback repeatedly after a period of time
         */
        void interval(const std::chrono::nanoseconds &value);

    public:
        /**
         * Attach callback
         */
        void attach(std::function<void ()> cb);

    public:
        /**
         * Timer properties
         */
        bool repeat() const
        {
            return this->_repeat;
        }

        std::chrono::nanoseconds cycle() const
        {
            return this->_cycle;
        }

        std::chrono::high_resolution_clock::time_point alarm() const
        {
            return this->_alarm;
        }

        /**
         * Calculate init value
         */
        void setup(const std::chrono::high_resolution_clock::time_point &now);

        /**
         * Check if timer expire
         */
        bool expire(const std::chrono::high_resolution_clock::time_point &now) const;

        /**
         * Update timer value
         */
        void update(const std::chrono::high_resolution_clock::time_point &now);

        /**
         * Comparator, used in conjunction with multiset
         * @note if alarm value is changed, you should re-add timer to multiset
         */
        struct Compare
        {
            bool operator()(const ev_timer *a, const ev_timer *b) const
            {
                return a->alarm() < b->alarm();
            }
        };

    protected:
        /**
         * At least one event has occurred
         */
        virtual void onEvent(int type);

    private:
        bool _repeat = false;
        std::function<void ()> _notify;

        std::chrono::nanoseconds _cycle;  // value when call timeout or interval
        std::chrono::high_resolution_clock::time_point _alarm;  // the next trigger time point<commit_msg>timer: if alarm is equal then check cycle, let the minimum first trigger<commit_after>/**
 * Created by <NAME>
 * @since  2017.02.03
 * @author <NAME> <<EMAIL>>
 * @link   http://chensoft.com
 */
#pragma once

#include <socket/base/ev_base.hpp>
#include <functional>
#include <chrono>

namespace chen
{
    class ev_timer: public ev_base
    {
    public:
        ev_timer(std::function<void ()> cb = nullptr);

    public:
        /**
         * Invoke callback only once after a period of time
         */
        void timeout(const std::chrono::nanoseconds &value);

        /**
         * Invoke callback only once in a future calendar date
         */
        void future(const std::chrono::high_resolution_clock::time_point &value);

        /**
         * Invoke callback repeatedly after a period of time
         */
        void interval(const std::chrono::nanoseconds &value);

    public:
        /**
         * Attach callback
         */
        void attach(std::function<void ()> cb);

    public:
        /**
         * Timer properties
         */
        bool repeat() const
        {
            return this->_repeat;
        }

        std::chrono::nanoseconds cycle() const
        {
            return this->_cycle;
        }

        std::chrono::high_resolution_clock::time_point alarm() const
        {
            return this->_alarm;
        }

        /**
         * Calculate init value
         */
        void setup(const std::chrono::high_resolution_clock::time_point &now);

        /**
         * Check if timer expire
         */
        bool expire(const std::chrono::high_resolution_clock::time_point &now) const;

        /**
         * Update timer value
         */
        void update(const std::chrono::high_resolution_clock::time_point &now);

        /**
         * Comparator, used in conjunction with multiset
         * @note if the cycle or alarm value changes, you should re-add the timer to multiset
         */
        struct Compare
        {
            bool operator()(const ev_timer *a, const ev_timer *b) const
            {
                auto alarm_a = a->alarm();
                auto alarm_b = b->alarm();
                return alarm_a == alarm_b ? a->cycle() < b->cycle() : alarm_a < alarm_b;
            }
        };

    protected:
        /**
         * At least one event has occurred
         */
        virtual void onEvent(int type);

    private:
        bool _repeat = false;
        std::function<void ()> _notify;

        std::chrono::nanoseconds _cycle;  // value when call timeout or interval
        std::chrono::high_resolution_clock::time_point _alarm;  // the next trigger time point
{'fraction_non_alphanumeric': 0.10983222785797893, 'fraction_numerical': 0.0031213421771361686, 'mean_word_length': 1.783387622149837, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5302664', 'n_tokens_mistral': 1461, 'n_tokens_neox': 1380, 'n_words': 380}