mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
335 lines
11 KiB
C++
335 lines
11 KiB
C++
/******************************************************************************
|
|
The MIT License(MIT)
|
|
|
|
Embedded Template Library.
|
|
https://github.com/ETLCPP/etl
|
|
https://www.etlcpp.com
|
|
|
|
Copyright(c) 2026 John Wellbelove
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files(the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions :
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
#ifndef ETL_TIMER_NODE_INCLUDED
|
|
#define ETL_TIMER_NODE_INCLUDED
|
|
|
|
#include "platform.h"
|
|
#include "message_router.h"
|
|
#include "nullptr.h"
|
|
#include "timer.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
//*****************************************************************************
|
|
// Definitions common to intrusive timers.
|
|
//*****************************************************************************
|
|
|
|
namespace etl
|
|
{
|
|
namespace private_timer
|
|
{
|
|
class timer_register_list;
|
|
class timer_active_list;
|
|
class timer_expired_list;
|
|
} // namespace private_timer
|
|
|
|
class timer_node;
|
|
class intrusive_timer;
|
|
|
|
//***************************************************************************
|
|
/// A timer configuration data structure.
|
|
//***************************************************************************
|
|
class timer_config
|
|
{
|
|
public:
|
|
|
|
friend class private_timer::timer_register_list;
|
|
friend class private_timer::timer_active_list;
|
|
friend class private_timer::timer_expired_list;
|
|
|
|
friend class timer_node;
|
|
friend class intrusive_timer;
|
|
|
|
//*******************************************
|
|
/// Constructor.
|
|
//*******************************************
|
|
ETL_CONSTEXPR timer_config(uint32_t period_, etl::timer::mode::type repeating_) ETL_NOEXCEPT
|
|
: period(period_)
|
|
, mode(repeating_)
|
|
, id(etl::timer::id::No_Timer)
|
|
{
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns the period of the timer.
|
|
//*******************************************
|
|
ETL_CONSTEXPR uint32_t get_period() const ETL_NOEXCEPT
|
|
{
|
|
return period;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns the mode of the timer.
|
|
//*******************************************
|
|
ETL_CONSTEXPR uint32_t get_mode() const ETL_NOEXCEPT
|
|
{
|
|
return mode;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns the id of the timer.
|
|
//*******************************************
|
|
ETL_CONSTEXPR etl::timer::id::type get_id() const ETL_NOEXCEPT
|
|
{
|
|
return id;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Clears the timer configuration.
|
|
//*******************************************
|
|
ETL_CONSTEXPR14 void clear() ETL_NOEXCEPT
|
|
{
|
|
period = etl::timer::state::Inactive;
|
|
mode = etl::timer::mode::Repeating;
|
|
id = etl::timer::id::No_Timer;
|
|
}
|
|
|
|
private:
|
|
|
|
uint32_t period; ///< The period of the timer.
|
|
etl::timer::mode::type mode; ///< Whether the timer is repeating or single-shot.
|
|
etl::timer::id::type id; ///< The id of the timer.
|
|
};
|
|
|
|
class sentinal_node;
|
|
|
|
//***************************************************************************
|
|
/// A timer data structure that can be linked into the timer lists.
|
|
/// Contains a timer configuration.
|
|
//***************************************************************************
|
|
class timer_node
|
|
{
|
|
public:
|
|
|
|
friend class private_timer::timer_register_list;
|
|
friend class private_timer::timer_active_list;
|
|
friend class private_timer::timer_expired_list;
|
|
|
|
friend class intrusive_timer;
|
|
|
|
//*******************************************
|
|
/// Constructor.
|
|
//*******************************************
|
|
timer_node(const timer_config& config_) ETL_NOEXCEPT
|
|
: registered_next(unlinked())
|
|
, active_next(unlinked())
|
|
, expired_next(unlinked())
|
|
, config(config_)
|
|
, delta(config_.get_period())
|
|
{
|
|
}
|
|
|
|
//*******************************************
|
|
/// Copy constructor.
|
|
//*******************************************
|
|
timer_node(const timer_node& node_) ETL_NOEXCEPT
|
|
: registered_next(unlinked())
|
|
, active_next(unlinked())
|
|
, expired_next(unlinked())
|
|
, config(node_.config)
|
|
, delta(node_.config.get_period())
|
|
{
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns the configuration of the timer.
|
|
//*******************************************
|
|
const timer_config& get_config() const ETL_NOEXCEPT
|
|
{
|
|
return config;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns the delta of the timer.
|
|
//*******************************************
|
|
ETL_CONSTEXPR uint32_t get_delta() const ETL_NOEXCEPT
|
|
{
|
|
return delta;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns the period of the timer.
|
|
//*******************************************
|
|
ETL_CONSTEXPR uint32_t get_period() const ETL_NOEXCEPT
|
|
{
|
|
return config.get_period();
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns the mode of the timer.
|
|
//*******************************************
|
|
ETL_CONSTEXPR uint32_t get_mode() const ETL_NOEXCEPT
|
|
{
|
|
return config.get_mode();
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns the id of the timer.
|
|
//*******************************************
|
|
ETL_CONSTEXPR etl::timer::id::type get_id() const ETL_NOEXCEPT
|
|
{
|
|
return config.get_id();
|
|
}
|
|
|
|
private:
|
|
|
|
//*******************************************
|
|
/// Sets the period of the timer.
|
|
//*******************************************
|
|
void set_period(uint32_t period_) ETL_NOEXCEPT
|
|
{
|
|
config.period = period_;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Sets the mode of the timer.
|
|
//*******************************************
|
|
void set_mode(etl::timer::mode::type mode_) ETL_NOEXCEPT
|
|
{
|
|
config.mode = mode_;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Returns a nullptr to indicate that the timer is not linked into any list.
|
|
//*******************************************
|
|
static etl::timer_node* unlinked() ETL_NOEXCEPT
|
|
{
|
|
return ETL_NULLPTR;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Sets the ID of the timer.
|
|
//*******************************************
|
|
void set_id(etl::timer::id::type id_) ETL_NOEXCEPT
|
|
{
|
|
config.id = id_;
|
|
}
|
|
|
|
//***************************************************************************
|
|
/// Returns a reference to the sentinel timer node used to mark the end of
|
|
/// the intrusive timer lists.
|
|
/// Implemented as a function-local static so that there is only ever one
|
|
/// instance, regardless of how many translation units include this header.
|
|
/// This avoids needing C++17 inline variables, so it remains compatible
|
|
/// with C++03 and C++11.
|
|
//***************************************************************************
|
|
static etl::timer_node* sentinal() ETL_NOEXCEPT
|
|
{
|
|
static etl::timer_node sentinel_node(etl::timer_config(0, 0));
|
|
|
|
return &sentinel_node;
|
|
}
|
|
|
|
//*******************************************
|
|
/// Clear the next pointers.
|
|
//*******************************************
|
|
void clear() ETL_NOEXCEPT
|
|
{
|
|
registered_next = unlinked();
|
|
active_next = unlinked();
|
|
expired_next = unlinked();
|
|
delta = config.get_period();
|
|
}
|
|
|
|
//*******************************************
|
|
/// Invokes the timer's callback.
|
|
//*******************************************
|
|
virtual void invoke(const etl::timer_config& /*config*/)
|
|
{
|
|
// Default implementation does nothing.
|
|
}
|
|
|
|
timer_node& operator=(const timer_node&) ETL_DELETE;
|
|
|
|
timer_node* registered_next; ///< The next timer in the registered timer list. nullptr if the timer is not registered.
|
|
timer_node* active_next; ///< The next timer in the active timer list. nullptr if the timer is not active.
|
|
timer_node* expired_next; ///< The next timer in the expired timer list. nullptr if the timer is not expired.
|
|
timer_config config; ///< The configuration of the timer.
|
|
uint32_t delta; ///< The time remaining until the timer expires.
|
|
};
|
|
|
|
//***************************************************************************
|
|
/// A timer node that invokes a callback delegate.
|
|
//***************************************************************************
|
|
template <typename TCallback>
|
|
struct callback_timer_node : public timer_node
|
|
{
|
|
//*******************************************
|
|
/// Constructor.
|
|
//*******************************************
|
|
callback_timer_node(TCallback callback_) ETL_NOEXCEPT
|
|
: timer_node()
|
|
, callback(callback_)
|
|
{
|
|
}
|
|
|
|
//*******************************************
|
|
/// Invokes the timer's callback.
|
|
//*******************************************
|
|
virtual void invoke(const etl::timer_config& config) ETL_OVERRIDE
|
|
{
|
|
callback(config);
|
|
}
|
|
|
|
TCallback callback; ///< The callback delegate for the timer.
|
|
};
|
|
|
|
//***************************************************************************
|
|
/// A timer node that invokes a message callback.
|
|
//***************************************************************************
|
|
template <typename TMessage>
|
|
struct message_timer_node : public timer_node
|
|
{
|
|
//*******************************************
|
|
/// Constructor.
|
|
//*******************************************
|
|
message_timer_node(etl::imessage_router& router_, TMessage message_) ETL_NOEXCEPT
|
|
: timer_node()
|
|
, router(&router_)
|
|
, message(message_)
|
|
{
|
|
}
|
|
|
|
//*******************************************
|
|
/// Invokes the timer's callback.
|
|
//*******************************************
|
|
virtual void invoke(const etl::timer_config& config) ETL_OVERRIDE
|
|
{
|
|
message.set_timer_config(config);
|
|
|
|
router->receive(message);
|
|
}
|
|
|
|
etl::imessage_router* router; ///< The message router to send the message to.
|
|
TMessage message; ///< The message to send when the timer expires.
|
|
};
|
|
} // namespace etl
|
|
|
|
#endif
|