Separated node and config into individual files

Added more node derived types and examples
This commit is contained in:
John Wellbelove 2026-10-28 20:42:29 +00:00
parent f02e431686
commit 37400764a9
20 changed files with 1496 additions and 813 deletions

View File

@ -0,0 +1,6 @@
---
title: "Intrusive Timers"
weight: 100
---
Classes that implement intrusive timer-based services.

View File

@ -1,9 +1,11 @@
---
title: "intrusive_timer"
weight: 103
---
{{< callout type="info">}}
Header: `intrusive_timer.h`
Namespace: `etl`
Since: `20.46.0`
From: `C++03`
{{< /callout >}}
@ -94,19 +96,19 @@ explicit intrusive_timer(timer_lock_policy& lock_policy) ETL_NOEXCEPT
Constructor.
**Parameters**
`lock_policy` The lock policy which determines access to parts of the timer.
`lock_policy` : The lock policy which determines access to parts of the timer.
---
```cpp
bool register_timer(etl::timer_node& timer) ETL_NOEXCEPT
bool register_timer(etl::timer::node& timer) ETL_NOEXCEPT
```
**Description**
Register a timer.
It will not be started until the `start()` method is called.
**Parameters**
`etl::timer_node& timer` : The timer node to register.
`etl::timer::node& timer` : The timer node to register.
The timer node must not be already registered with anything else.
The timer nodes's ID will be set here and this timer will be set as its owner.
@ -116,7 +118,7 @@ The timer nodes's ID will be set here and this timer will be set as its owner.
---
```cpp
bool unregister_timer(etl::timer_node& timer) ETL_NOEXCEPT
bool unregister_timer(etl::timer::node& timer) ETL_NOEXCEPT
```
**Description**
Unregisters a timer node.
@ -124,7 +126,7 @@ Stops the timer, if active.
Callbacks for any expired timers may still occur.
**Parameters**
`etl::timer_node& timer` : The timer node to unregister.
`etl::timer::node& timer` : The timer node to unregister.
The timer node must be registered with this timer. If it isn't then the function will return false.
The timer nodes's ID will be set here and this timer will be set as its owner.
@ -176,7 +178,7 @@ If the tick was not processed then the next tick must accommodate for the extra
---
```cpp
bool start(etl::timer_node& timer,
bool start(etl::timer::node& timer,
bool immediate = false)
```
**Description**
@ -189,7 +191,7 @@ It will be started only if:-
If the started timer will now be the first to expire then a 'time to next' notification will be sent.
**Parameters**
`etl::timer_node& timer` : The timer node to start.
`etl::timer::node& timer` : The timer node to start.
`bool immediate` : If `true` then the timer expires immediately.
**Return**
@ -198,7 +200,7 @@ If the started timer will now be the first to expire then a 'time to next' notif
---
```cpp
bool stop(etl::timer_node& timer) ETL_NOEXCEPT
bool stop(etl::timer::node& timer) ETL_NOEXCEPT
```
**Description**
Stops a timer.
@ -206,7 +208,7 @@ A 'time to next' notification will be sent for the next timer to expire.
Expired timer callbacks occur outside of the locked regions.
**Parameters**
`etl::timer_node& timer` : The timer node to stop.
`etl::timer::node& timer` : The timer node to stop.
**Return**
`true` if the timer was stopped,
@ -214,7 +216,7 @@ Expired timer callbacks occur outside of the locked regions.
---
```cpp
bool set_interval(etl::timer_node& timer,
bool set_interval(etl::timer::node& timer,
uint32_t interval) ETL_NOEXCEPT
```
**Description**
@ -224,7 +226,7 @@ The timer will be stopped if active.
If the timer node was the next to expire then a 'time to next' notification will be sent.
**Parameters**
`etl::timer_node& timer` : The timer node to start.
`etl::timer::node& timer` : The timer node to start.
`uint32_t interval` : The new interval.
**Return**
@ -233,7 +235,7 @@ If the timer node was the next to expire then a 'time to next' notification will
---
```cpp
bool set_mode(etl::timer_node& timer,
bool set_mode(etl::timer::node& timer,
etl::timer::mode::type mode) ETL_NOEXCEPT
```
**Description**
@ -243,7 +245,7 @@ The timer will be stopped if active.
If the timer node was the next to expire then a 'time to next' notification will be sent.
**Parameters**
`etl::timer_node& timer` : The timer node to start.
`etl::timer::node& timer` : The timer node to start.
`etl::timer::mode::type mode` : The new mode.
**Return**
@ -252,7 +254,7 @@ If the timer node was the next to expire then a 'time to next' notification will
---
```cpp
bool set_config(etl::timer_node& timer,
bool set_config(etl::timer::node& timer,
const etl::timer_config& config) ETL_NOEXCEPT
```
**Description**
@ -262,7 +264,7 @@ The timer will be stopped if active.
If the timer node was the next to expire then a 'time to next' notification will be sent.
**Parameters**
`etl::timer_node& timer` : The timer node to start.
`etl::timer::node& timer` : The timer node to start.
`const etl::timer_config& config` : The new configuration.
**Return**
@ -293,7 +295,7 @@ Returns `etl::timer::interval::No_Active_Interval` if there is no active timer.
---
```cpp
bool is_registered(const etl::timer_node& timer) const ETL_NOEXCEPT
bool is_registered(const etl::timer::node& timer) const ETL_NOEXCEPT
```
**Description**
Check if a timer is registered with this timer.
@ -331,7 +333,7 @@ Clears the update notification callback.
---
```cpp
etl::timer_node* find_timer(etl::timer::id::type id) ETL_NOEXCEPT
etl::timer::node* find_timer(etl::timer::id::type id) ETL_NOEXCEPT
```
**Description**
Finds a timer node by its id.
@ -340,4 +342,30 @@ Finds a timer node by its id.
`etl::timer::id::type id` : The ID of the timer node.
**Return**
A pointer to the node or `etl::timer_node::end()`
A pointer to the node or `etl::timer::node::end()`
## Examples
### Callback with a lambda
```cpp
int call_count = 0;
auto timer_lambda = [&call_count]()
{
++call_count;
};
etl::timer::atomic_lock_policy lock_policy;
etl::intrusive_timer timer_controller(lock_policy);
etl::timer::callback_node node1(etl::timer::config(1, etl::timer::mode::Single_Shot), timer_lambda);
timer_controller.register_timer(node1);
timer_controller.enable(true);
timer_controller.start(node1);
timer_controller.tick(1);
assert(call_count == 1);
```

View File

@ -1,25 +1,27 @@
---
title: "timer_config"
title: "config"
weight: 101
---
{{< callout type="info">}}
Header: `timer_node.h`
Header: `timer_config.h`
Namespace: `etl::timer`
Since: `TBA`
From: `C++03`
{{< /callout >}}
## timer_config
## config
```cpp
class timer_config
class config
```
**Description**
Contains the configuration for a timer.
Used to configure a timer for an `etl::timer_node` derived timer element.
Used to configure a timer for an `etl::timer::node` derived timer element.
---
```cpp
ETL_CONSTEXPR timer_config(uint32_t interval, etl::timer::mode::type mode) ETL_NOEXCEPT
ETL_CONSTEXPR config(uint32_t interval, etl::timer::mode::type mode) ETL_NOEXCEPT
```
**Description**
Constructs a timer configuration.
@ -43,6 +45,7 @@ ETL_CONSTEXPR etl::timer::mode::type get_mode() const ETL_NOEXCEPT
```
**Description**
Returns the mode of the timer.
One of:-
`etl::timer::mode::No_Mode`
`etl::timer::mode::Single_Shot`
`etl::timer::mode::Repeating`

View File

@ -0,0 +1,311 @@
---
title: "node"
weight: 102
---
{{< callout type="info">}}
Header: `timer_node.h`
Namespace: `etl::timer`
Since: `TBA`
From: `C++03`
{{< /callout >}}
## Class diagram
```mermaid
---
config:
theme: neutral
look: classic
layout: dagre
title: namespace etl::timer
---
classDiagram
node <|-- callback_node
node <|-- callback_ref_node
node <|-- message_node
node "1" *-- "*" config : contains
class config {
+config()
+get_interval() const uint32_t
+get_mode() etl::timer::mode::type
+get_id() etl::timer::id::type
+clear() void
}
class node {
+node(const etl::timer::config&)
+get_config() config&
+get_delta() uint32_t
+get_interval() uint32_t
+get_mode() etl::timer::mode::type
+get_id() etl::timer::id::type
+static end() etl::timer::node*
+virtual invoke() void
}
class callback_node {
<<template TCallback>>
+callback_node(const etl::timer::config&, TCallback, )
+invoke() void override
}
class callback_ref_node {
<<template TCallback>>
+callback_ref_node(const etl::timer::config&, TCallback, )
+invoke() void override
}
class message_node {
<<template TMessage>>
+message_node(const etl::timer::config&, etl::imessage_router&, TMessage)
+invoke() void override
}
```
## node
```cpp
class node
```
**Description**
Base class for all timer nodes.
Used as the timer element in `etl::intrusive_timer`.
---
```cpp
node(const etl::timer::config& config_) ETL_NOEXCEPT
```
**Description**
Construct from an `etl::timer::config`.
---
```cpp
node(const etl::timer::node& node_) ETL_NOEXCEPT
```
**Description**
Copy constructor.
---
```cpp
const etl::timer::config& get_config() const ETL_NOEXCEPT
```
**Description**
Returns the configuration of the timer.
---
```cpp
ETL_CONSTEXPR uint32_t get_delta() const ETL_NOEXCEPT
```
**Description**
Returns the delta of the timer.
---
```cpp
ETL_CONSTEXPR uint32_t get_interval() const ETL_NOEXCEPT
```
**Description**
Returns the interval of the timer.
---
```cpp
ETL_CONSTEXPR etl::timer::mode::type get_mode() const ETL_NOEXCEPT
```
**Description**
Returns the mode of the timer.
One of:-
`etl::timer::mode::No_Mode`
`etl::timer::mode::Single_Shot`
`etl::timer::mode::Repeating`
---
```cpp
ETL_CONSTEXPR etl::timer::id::type get_id() const ETL_NOEXCEPT
```
**Description**
Returns the id of the timer.
---
```cpp
static etl::timer::node* end() ETL_NOEXCEPT
```
**Description**
Returns a pointer to the static sentinel timer node used to mark the end of the intrusive timer lists.
## callback_node
```cpp
template <typename TCallback>
class callback_node : public etl::timer::node
```
**Description**
A timer node for a function callback using `etl::delegate`, `etl::inplace_function`, functors or lambdas that can be copied.
Derived from `etl::timer::node`.
## callback_ref_node
```cpp
template <typename TCallback>
class callback_node : public etl::timer::node
```
**Description**
A timer node for a function callback using functors that cannot be copied.
Derived from `etl::timer::node`.
## message_node
```cpp
template <typename TMessage>
class message_node : public etl::timer::node
```
**Description**
A timer node for a message callback using an `etl::message` derived object.
Derived from `etl::timer::node`.
Static asserts if `TMessage` is not derived from `etl::imessage`.
## Examples
### Global function callback
```cpp
void callback()
{
std::cout << "callback()\n";
}
etl::timer::config config(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::callback_node node(config, callback);
```
### Lambda callback
```cpp
auto callback = [](){ std::cout << "lambda\n"; };
etl::timer::config config(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::callback_node node(config, callback);
```
### Message callback
```cpp
struct CallbackMessage : public etl::message<1>
{
};
class MessageProcessor : public etl::message_router<MessageProcessor, CallbackMessage>
{
public:
MessageProcessor()
: etl::message_router<MessageProcessor, CallbackMessage>()
{
}
//*******************************************
void on_receive(const CallbackMessage& msg)
{
std::cout << "CallbackMessage\n";
}
//*******************************************
void on_receive_unknown(const etl::imessage& msg) {}
};
etl::timer::config config(etl::timer::config(100, etl::timer::mode::Single_Shot));
MessageProcessor message_processor;
CallbackMessage message
etl::timer::message_node node(config, message_processor, message);
```
### Functor callback
```cpp
int call_count = 0;
// Functor that can be copied to the node, because `call_count` is referenced by a pointer.
struct Functor
{
Functor(int& call_count_)
: call_count(&call_count_)
{
}
void operator()()
{
++(*call_count);
std::cout << "Functor ref callback : " << *call_count << "\n";
}
int* call_count;
};
Functor functor;
etl::timer::config config(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::callback_node node(config, functor);
```
### Functor ref callback
```cpp
// Functor that must not be copied to the node, otherwise `functor` will not get updated.
struct Functor
{
Functor()
: call_count(0)
{
}
void operator()()
{
++call_count;
std::cout << "Functor ref callback : " << call_count << "\n";
}
int call_count;
};
Functor functor;
etl::timer::config config(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::callback_ref_node node(config, functor);
```
### Delegate callback
```cpp
struct Object
{
Object()
: call_count(0)
{
}
void Increment()
{
++call_count;
std::cout << "Increment callback : " << call_count << "\n";
}
int call_count;
};
static Functor functor;
auto delegate = etl::delegate<void()>::create<Object, functor, &Object::Increment>();
etl::timer::config config(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::callback_node node(config, delegate);
```

View File

@ -1,156 +0,0 @@
---
title: "timer_node"
---
{{< callout type="info">}}
Header: `timer_node.h`
Since: `TBA`
From: `C++03`
{{< /callout >}}
## Class diagram
```mermaid
---
config:
theme: neutral
look: classic
layout: dagre
---
classDiagram
timer_node <|-- timer_callback_node
timer_node <|-- timer_message_node
timer_node "1" *-- "*" timer_config : contains
class timer_config {
+timer_config()
+get_interval() const uint32_t
+get_mode() const uint32_t
+get_id() const etl::timer::id::type
+clear() void
}
class timer_node {
+timer_node(const etl::timer_config&)
+get_config() timer_config&
+get_delta() uint32_t
+get_interval() uint32_t
+get_mode() uint32_t
+get_id() etl::timer::id::type
+static end() etl::timer_node*
}
class timer_node {
+virtual invoke() void
}
class timer_callback_node {
<<template TCallback>>
+timer_callback_node(const etl::timer_config&, TCallback, )
+invoke() void override
}
class timer_message_node {
<<template TMessage>>
+timer_message_node(const etl::timer_config&, etl::imessage_router&, TMessage)
+invoke() void override
}
```
## timer_node
```cpp
class timer_node
```
**Description**
Base class for all timer nodes.
Used as the timer element in `etl::intrusive_timer`.
---
```cpp
timer_node(const timer_config& config_) ETL_NOEXCEPT
```
**Description**
Construct from an `etl::timer_config`.
---
```cpp
timer_node(const timer_node& node_) ETL_NOEXCEPT
```
**Description**
Copy constructor.
---
```cpp
const timer_config& get_config() const ETL_NOEXCEPT
```
**Description**
Returns the configuration of the timer.
---
```cpp
ETL_CONSTEXPR uint32_t get_delta() const ETL_NOEXCEPT
```
**Description**
Returns the delta of the timer.
---
```cpp
ETL_CONSTEXPR uint32_t get_interval() const ETL_NOEXCEPT
```
**Description**
Returns the interval of the timer.
---
```cpp
ETL_CONSTEXPR etl::timer::mode::type get_mode() const ETL_NOEXCEPT
```
**Description**
Returns the mode of the timer.
`etl::timer::mode::No_Mode`
`etl::timer::mode::Single_Shot`
`etl::timer::mode::Repeating`
---
```cpp
ETL_CONSTEXPR etl::timer::id::type get_id() const ETL_NOEXCEPT
```
**Description**
Returns the id of the timer.
---
```cpp
static etl::timer_node* end() ETL_NOEXCEPT
```
**Description**
Returns a pointer to the static sentinel timer node used to mark the end of the intrusive timer lists.
## timer_callback_node
```cpp
template <typename TCallback>
class timer_callback_node : public etl::timer_node
```
**Description**
A timer node for a function callback using `etl::delegate`, `etl::inplace_function`, or similar.
Derived from `etl::timer_node`.
## timer_message_node
```cpp
template <typename TMessage>
class timer_message_node : public etl::timer_node
```
**Description**
A timer node for a message callback using an `etl::message` derived object.
Derived from `etl::timer_node`.
Static asserts if `TMessage` is not derived from `etl::imessage`.
## Example
etl::timer_config

View File

@ -0,0 +1,17 @@
{{ with .Page.Sections.ByTitle }}
<h3>Categories</h3>
<ul>
{{ range . }}
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
{{ end }}
</ul>
{{ end }}
{{ with .Page.RegularPages.ByWeight }}
<h3>Components</h3>
<ul>
{{ range . }}
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
{{ end }}
</ul>
{{ end }}

View File

@ -31,7 +31,9 @@ SOFTWARE.
#include "platform.h"
#include "nullptr.h"
#include "timer_lock_policy.h"
#include "timer_node.h"
#include "timer_notification.h"
#if ETL_HAS_ATOMIC
#include "atomic.h"
@ -43,77 +45,6 @@ SOFTWARE.
namespace etl
{
//***************************************************************************
/// Interface for timer lock policy
//***************************************************************************
class timer_lock_policy
{
public:
virtual void lock() ETL_NOEXCEPT = 0;
virtual void unlock() ETL_NOEXCEPT = 0;
virtual bool is_locked() ETL_NOEXCEPT = 0;
};
//***************************************************************************
/// No lock policy for timers.
//***************************************************************************
class timer_no_lock_policy : public timer_lock_policy
{
public:
void lock() ETL_NOEXCEPT ETL_OVERRIDE {}
void unlock() ETL_NOEXCEPT ETL_OVERRIDE {}
bool is_locked() ETL_NOEXCEPT ETL_OVERRIDE
{
return false;
}
};
#if ETL_HAS_ATOMIC
//***************************************************************************
/// Atomic lock policy for timers.
//***************************************************************************
class timer_atomic_lock_policy : public timer_lock_policy
{
public:
void lock() ETL_NOEXCEPT ETL_OVERRIDE
{
lock_flag.store(true, etl::memory_order_seq_cst);
}
void unlock() ETL_NOEXCEPT ETL_OVERRIDE
{
lock_flag.store(false, etl::memory_order_seq_cst);
}
bool is_locked() ETL_NOEXCEPT ETL_OVERRIDE
{
return lock_flag.load(etl::memory_order_seq_cst);
}
private:
etl::atomic_bool lock_flag;
};
#endif
//***************************************************************************
/// Default class for time to next notification
//***************************************************************************
class timer_time_to_next_notification
{
public:
virtual void invoke(uint32_t)
{
// Do nothing by default.
}
};
//***************************************************************************
/// Interface for intrusive timer
//***************************************************************************
@ -124,7 +55,7 @@ namespace etl
//*******************************************
/// Constructor.
//*******************************************
explicit intrusive_timer(timer_lock_policy& lock_policy_) ETL_NOEXCEPT
explicit intrusive_timer(etl::timer::lock_policy& lock_policy_) ETL_NOEXCEPT
: lock_policy(lock_policy_)
, register_list()
, active_list()
@ -139,7 +70,7 @@ namespace etl
/// Register a timer.
/// It will not be started until the start() method is called.
//*******************************************
bool register_timer(etl::timer_node& timer_) ETL_NOEXCEPT
bool register_timer(etl::timer::node& timer_) ETL_NOEXCEPT
{
bool result = false;
@ -162,7 +93,7 @@ namespace etl
//*******************************************
/// Unregister a timer.
//*******************************************
bool unregister_timer(etl::timer_node& timer_) ETL_NOEXCEPT
bool unregister_timer(etl::timer::node& timer_) ETL_NOEXCEPT
{
lock_policy.lock();
@ -244,7 +175,7 @@ namespace etl
if (has_active)
{
// Process timers that have expired.
etl::timer_node* timer = active_list.first();
etl::timer::node* timer = active_list.first();
while (has_active && (count >= timer->delta))
{
@ -297,7 +228,7 @@ namespace etl
//*******************************************
/// Starts a timer.
//*******************************************
bool start(etl::timer_node& timer_, bool immediate_ = false)
bool start(etl::timer::node& timer_, bool immediate_ = false)
{
bool is_started = false;
@ -332,7 +263,7 @@ namespace etl
//*******************************************
/// Stops a timer.
//*******************************************
bool stop(etl::timer_node& timer_) ETL_NOEXCEPT
bool stop(etl::timer::node& timer_) ETL_NOEXCEPT
{
bool is_stopped = false;
@ -355,7 +286,7 @@ namespace etl
//*******************************************
/// Sets a timer's interval.
//*******************************************
bool set_interval(etl::timer_node& timer_, uint32_t interval_) ETL_NOEXCEPT
bool set_interval(etl::timer::node& timer_, uint32_t interval_) ETL_NOEXCEPT
{
bool result = false;
@ -385,7 +316,7 @@ namespace etl
//*******************************************
/// Sets a timer's mode.
//*******************************************
bool set_mode(etl::timer_node& timer_, etl::timer::mode::type mode_) ETL_NOEXCEPT
bool set_mode(etl::timer::node& timer_, etl::timer::mode::type mode_) ETL_NOEXCEPT
{
bool result = false;
@ -414,7 +345,7 @@ namespace etl
//*******************************************
/// Sets a timer's configuration.
//*******************************************
bool set_config(etl::timer_node& timer_, const etl::timer_config& config_) ETL_NOEXCEPT
bool set_config(etl::timer::node& timer_, const etl::timer::config& config_) ETL_NOEXCEPT
{
bool result = false;
@ -477,7 +408,7 @@ namespace etl
//*******************************************
/// Check if a timer is registered with this timer.
//*******************************************
bool is_registered(const etl::timer_node& timer_) const ETL_NOEXCEPT
bool is_registered(const etl::timer::node& timer_) const ETL_NOEXCEPT
{
lock_policy.lock();
@ -499,7 +430,7 @@ namespace etl
//*******************************************
/// Sets the update notification.
//*******************************************
void set_next_timer_notification(timer_time_to_next_notification& notification) ETL_NOEXCEPT
void set_next_timer_notification(etl::timer::time_to_next_notification& notification) ETL_NOEXCEPT
{
active_notify_time_to_next = &notification;
}
@ -515,9 +446,9 @@ namespace etl
//*******************************************
/// Finds a timer by its id.
//*******************************************
etl::timer_node* find_timer(etl::timer::id::type id_) ETL_NOEXCEPT
etl::timer::node* find_timer(etl::timer::id::type id_) ETL_NOEXCEPT
{
etl::timer_node* timer = register_list.first();
etl::timer::node* timer = register_list.first();
while (timer != register_list.end())
{
@ -528,7 +459,7 @@ namespace etl
timer = register_list.next(timer);
}
return etl::timer_node::end();
return etl::timer::node::end();
}
private:
@ -536,7 +467,7 @@ namespace etl
//*******************************************
/// Notifies the user of the next timer that is due to expire.
//*******************************************
void notify_about_timer_change(bool notify_, etl::timer_node* timer_) ETL_NOEXCEPT
void notify_about_timer_change(bool notify_, etl::timer::node* timer_) ETL_NOEXCEPT
{
if (notify_)
{
@ -553,7 +484,7 @@ namespace etl
{
etl::timer::id::type next_id = 0; // IDs start at 0.
etl::timer_node* timer = register_list.first();
etl::timer::node* timer = register_list.first();
while ((timer != register_list.end()) && (timer->get_id() == next_id))
{
@ -567,7 +498,7 @@ namespace etl
//*******************************************
/// Stops a timer without locking.
//*******************************************
void stop_timer(etl::timer_node& timer_) ETL_NOEXCEPT
void stop_timer(etl::timer::node& timer_) ETL_NOEXCEPT
{
active_list.remove(&timer_);
}
@ -578,7 +509,7 @@ namespace etl
//*******************************************
void invoke_expired_timers()
{
etl::timer_node* timer = expired_list.first();
etl::timer::node* timer = expired_list.first();
while (timer != expired_list.end())
{
@ -592,13 +523,13 @@ namespace etl
intrusive_timer(const intrusive_timer&) ETL_DELETE;
intrusive_timer& operator=(const intrusive_timer&) ETL_DELETE;
etl::timer_lock_policy& lock_policy;
etl::private_timer::timer_register_list register_list;
etl::private_timer::timer_active_list active_list;
etl::private_timer::timer_expired_list expired_list;
etl::timer::lock_policy& lock_policy;
etl::private_timer::register_list register_list;
etl::private_timer::active_list active_list;
etl::private_timer::expired_list expired_list;
timer_time_to_next_notification default_notify_time_to_next;
timer_time_to_next_notification* active_notify_time_to_next;
etl::timer::time_to_next_notification default_notify_time_to_next;
etl::timer::time_to_next_notification* active_notify_time_to_next;
bool enabled;
size_t timer_count;

View File

@ -48,14 +48,14 @@ namespace etl
/// The list of timers that are registered.
/// The list does not do any checking of parameters as it is assumed that the timer service has already done this.
//*************************************************************************
class timer_register_list
class register_list
{
public:
//*******************************
/// Constructor.
//*******************************
timer_register_list() ETL_NOEXCEPT
register_list() ETL_NOEXCEPT
: head(end())
, tail(end())
{
@ -72,7 +72,7 @@ namespace etl
//*******************************
// Adds the timer in to the list in ID order.
//*******************************
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
void insert(etl::timer::node* new_timer) ETL_NOEXCEPT
{
new_timer->registered_next = end();
@ -89,8 +89,8 @@ namespace etl
}
else
{
etl::timer_node* current = head;
etl::timer_node* previous = head;
etl::timer::node* current = head;
etl::timer::node* previous = head;
// Find the correct place to insert the new timer in to the list.
while ((current != end()) && (current->get_id() < new_timer->get_id()))
@ -112,14 +112,14 @@ namespace etl
}
}
// We are now the exclusive owner of this timer_node.
// We are now the exclusive owner of this node.
new_timer->set_owner(this);
}
//*******************************
// Adds the timer in to the list.
//*******************************
void insert(etl::timer_node& new_timer) ETL_NOEXCEPT
void insert(etl::timer::node& new_timer) ETL_NOEXCEPT
{
insert(&new_timer);
}
@ -128,10 +128,10 @@ namespace etl
// Remove the timer from the list.
// Returns the next timer in the list after the removed timer, or nullptr if the removed timer was the last in the list.
//*******************************
etl::timer_node* remove(etl::timer_node* timer_) ETL_NOEXCEPT
etl::timer::node* remove(etl::timer::node* timer_) ETL_NOEXCEPT
{
etl::timer_node* current = head;
etl::timer_node* previous = head;
etl::timer::node* current = head;
etl::timer::node* previous = head;
// Find the timer in the list so we can know what timer was previous to it.
while (current != timer_)
@ -141,7 +141,7 @@ namespace etl
}
// Get the next timer in the lister the timer to be removed.
etl::timer_node* next = current->registered_next;
etl::timer::node* next = current->registered_next;
// Remove it from the list.
if (current == head)
@ -162,9 +162,9 @@ namespace etl
// Clear the id and next pointer of the removed timer.
current->set_id(etl::timer::id::No_Timer);
current->registered_next = etl::timer_node::unlinked();
current->registered_next = etl::timer::node::unlinked();
// We are no longer the owner of this timer_node.
// We are no longer the owner of this node.
current->set_owner(ETL_NULLPTR);
return next;
@ -174,7 +174,7 @@ namespace etl
/// Returns the first timer in the list.
/// If the list is empty, returns end().
//*******************************
etl::timer_node* first() const ETL_NOEXCEPT
etl::timer::node* first() const ETL_NOEXCEPT
{
return head;
}
@ -184,7 +184,7 @@ namespace etl
/// May be end() if the given timer is the last in the list.
/// If the given timer is nullptr, returns end().
//*******************************
etl::timer_node* next(etl::timer_node* timer) const ETL_NOEXCEPT
etl::timer::node* next(etl::timer::node* timer) const ETL_NOEXCEPT
{
if (timer != end())
{
@ -198,11 +198,11 @@ namespace etl
//*******************************
/// Returns the end of the list.
/// Always returns &etl::timer_node::end().
/// Always returns &etl::timer::node::end().
//*******************************
etl::timer_node* const end() const ETL_NOEXCEPT
etl::timer::node* const end() const ETL_NOEXCEPT
{
return etl::timer_node::end();
return etl::timer::node::end();
}
//*******************************
@ -210,7 +210,7 @@ namespace etl
//*******************************
void clear()
{
etl::timer_node* timer = head;
etl::timer::node* timer = head;
while (head != end())
{
@ -227,9 +227,9 @@ namespace etl
/// If in the list then returns itself.
/// If not in the list then returns end().
//*******************************************
etl::timer_node* find(etl::timer_node* timer_) const ETL_NOEXCEPT
etl::timer::node* find(etl::timer::node* timer_) const ETL_NOEXCEPT
{
timer_node* node = first();
etl::timer::node* node = first();
while ((node != end()) && (node != timer_))
{
@ -241,22 +241,22 @@ namespace etl
private:
etl::timer_node* head;
etl::timer_node* tail;
etl::timer::node* head;
etl::timer::node* tail;
};
//*************************************************************************
/// The list of timers that are active.
/// The list does not do any checking of parameters as it is assumed that the timer service has already done this.
//*************************************************************************
class timer_active_list
class active_list
{
public:
//*******************************
/// Constructor.
//*******************************
timer_active_list() ETL_NOEXCEPT
active_list() ETL_NOEXCEPT
: head(end())
{
}
@ -272,7 +272,7 @@ namespace etl
//*******************************
// Inserts the timer at the correct delta position
//*******************************
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
void insert(etl::timer::node* new_timer) ETL_NOEXCEPT
{
if (empty())
{
@ -290,8 +290,8 @@ namespace etl
else
{
// We already have entries, and new_timer doesn't go before head.
timer_node* previous_timer = head;
timer_node* timer = head->active_next;
etl::timer::node* previous_timer = head;
etl::timer::node* timer = head->active_next;
// Adjust the new_timer delta to take account of the head timer's delta.
new_timer->delta -= previous_timer->delta;
@ -336,7 +336,7 @@ namespace etl
//*******************************
// Inserts the timer at the correct delta position
//*******************************
void insert(etl::timer_node& new_timer) ETL_NOEXCEPT
void insert(etl::timer::node& new_timer) ETL_NOEXCEPT
{
insert(&new_timer);
}
@ -344,10 +344,10 @@ namespace etl
//*******************************
/// Removes the selected timer from the list.
//*******************************
etl::timer_node* remove(etl::timer_node* timer_) ETL_NOEXCEPT
etl::timer::node* remove(etl::timer::node* timer_) ETL_NOEXCEPT
{
etl::timer_node* current = head;
etl::timer_node* previous = head;
etl::timer::node* current = head;
etl::timer::node* previous = head;
// Find the timer in the list so we can know what timer was previous to it.
while (current != timer_)
@ -357,7 +357,7 @@ namespace etl
}
// Get the next timer in the list after the timer to be removed.
etl::timer_node* next = current->active_next;
etl::timer::node* next = current->active_next;
// Adjust the next delta.
if (next != end())
@ -377,7 +377,7 @@ namespace etl
}
// Clear the next pointer of the removed timer.
timer_->active_next = etl::timer_node::unlinked();
timer_->active_next = etl::timer::node::unlinked();
return next;
}
@ -386,7 +386,7 @@ namespace etl
/// Returns the first timer in the list.
/// If the list is empty, returns end().
//*******************************
etl::timer_node* first() const ETL_NOEXCEPT
etl::timer::node* first() const ETL_NOEXCEPT
{
return head;
}
@ -396,7 +396,7 @@ namespace etl
/// May be end() if the given timer is the last in the list.
/// If the given timer is nullptr, returns end().
//*******************************
etl::timer_node* next(etl::timer_node* timer) const ETL_NOEXCEPT
etl::timer::node* next(etl::timer::node* timer) const ETL_NOEXCEPT
{
if (timer != end())
{
@ -410,11 +410,11 @@ namespace etl
//*******************************
/// Returns the end of the list.
/// Always returns &etl::timer_node::end().
/// Always returns &etl::timer::node::end().
//*******************************
etl::timer_node* const end() const ETL_NOEXCEPT
etl::timer::node* const end() const ETL_NOEXCEPT
{
return etl::timer_node::end();
return etl::timer::node::end();
}
//*******************************
@ -422,12 +422,12 @@ namespace etl
//*******************************
void clear()
{
etl::timer_node* timer = head;
etl::timer::node* timer = head;
while (head != end())
{
head = timer->active_next;
timer->active_next = etl::timer_node::unlinked();
timer->active_next = etl::timer::node::unlinked();
timer = head;
}
}
@ -437,9 +437,9 @@ namespace etl
/// If in the list then returns itself.
/// If not in the list then returns end().
//*******************************************
etl::timer_node* find(etl::timer_node* timer_) const ETL_NOEXCEPT
etl::timer::node* find(etl::timer::node* timer_) const ETL_NOEXCEPT
{
timer_node* node = first();
etl::timer::node* node = first();
while ((node != end()) && (node != timer_))
{
@ -451,21 +451,21 @@ namespace etl
private:
etl::timer_node* head;
etl::timer::node* head;
};
//*************************************************************************
/// The list of timers that are registered.
/// The list does not do any checking of parameters as it is assumed that the timer service has already done this.
//*************************************************************************
class timer_expired_list
class expired_list
{
public:
//*******************************
/// Constructor.
//*******************************
timer_expired_list() ETL_NOEXCEPT
expired_list() ETL_NOEXCEPT
: head(end())
, tail(end())
{
@ -482,7 +482,7 @@ namespace etl
//*******************************
// Adds the timer in to the list.
//*******************************
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
void insert(etl::timer::node* new_timer) ETL_NOEXCEPT
{
new_timer->expired_next = end();
@ -501,7 +501,7 @@ namespace etl
//*******************************
// Adds the timer in to the list.
//*******************************
void insert(etl::timer_node& new_timer) ETL_NOEXCEPT
void insert(etl::timer::node& new_timer) ETL_NOEXCEPT
{
insert(&new_timer);
}
@ -510,7 +510,7 @@ namespace etl
/// Returns the first timer in the list.
/// If the list is empty, returns nullptr.
//*******************************
etl::timer_node* first() const ETL_NOEXCEPT
etl::timer::node* first() const ETL_NOEXCEPT
{
return head;
}
@ -520,7 +520,7 @@ namespace etl
/// May be end() if the given timer is the last in the list.
/// If the given timer is nullptr, returns end().
//*******************************
etl::timer_node* next(etl::timer_node* timer) const ETL_NOEXCEPT
etl::timer::node* next(etl::timer::node* timer) const ETL_NOEXCEPT
{
if (timer != end())
{
@ -534,11 +534,11 @@ namespace etl
//*******************************
/// Returns the end of the list.
/// Always returns &etl::timer_node::end().
/// Always returns &etl::timer::node::end().
//*******************************
etl::timer_node* const end() const ETL_NOEXCEPT
etl::timer::node* const end() const ETL_NOEXCEPT
{
return etl::timer_node::end();
return etl::timer::node::end();
}
//*******************************
@ -546,7 +546,7 @@ namespace etl
//*******************************
void clear()
{
etl::timer_node* timer = head;
etl::timer::node* timer = head;
while (head != end())
{
@ -563,9 +563,9 @@ namespace etl
/// If in the list then returns itself.
/// If not in the list then returns end().
//*******************************************
etl::timer_node* find(etl::timer_node* timer_) const ETL_NOEXCEPT
etl::timer::node* find(etl::timer::node* timer_) const ETL_NOEXCEPT
{
timer_node* node = first();
etl::timer::node* node = first();
while ((node != end()) && (node != timer_))
{
@ -577,8 +577,8 @@ namespace etl
private:
etl::timer_node* head;
etl::timer_node* tail;
etl::timer::node* head;
etl::timer::node* tail;
};
} // namespace private_timer
} // namespace etl

View File

@ -41,7 +41,7 @@ SOFTWARE.
namespace etl
{
#ifdef ETL_TIMER_SEMAPHORE_TYPE
typedef ETL_TIMER_SEMAPHORE_TYPE timer_semaphore_t;
typedef ETL_TIMER_SEMAPHORE_TYPE timer_semaphore
#else
#if ETL_HAS_ATOMIC
typedef etl::atomic_uint32_t timer_semaphore_t;
@ -74,10 +74,10 @@ namespace etl
{
enum
{
DELAYED = false,
DELAYED = false, // Deprecated
IMMEDIATE = true,
Delayed = false,
Delayed = false, // Deprecated
Immediate = true
};
@ -89,7 +89,7 @@ namespace etl
{
enum
{
NO_TIMER = 255,
NO_TIMER = 255, // Deprecated
No_Timer = 255
};
@ -101,7 +101,7 @@ namespace etl
{
enum
{
INACTIVE = 0xFFFFFFFFUL,
INACTIVE = 0xFFFFFFFFUL, // Deprecated
Inactive = 0xFFFFFFFFUL
};
};
@ -111,7 +111,7 @@ namespace etl
{
enum
{
No_Active_Interval = 0xFFFFFFFFUL,
No_Active_Interval = 0xFFFFFFFFUL, // Deprecated
No_Interval = 0xFFFFFFFFUL
};
@ -123,7 +123,7 @@ namespace etl
{
static ETL_CONSTANT void* No_Owner = ETL_NULLPTR;
};
};
} // namespace timer
} // namespace etl
#endif

142
include/etl/timer_config.h Normal file
View File

@ -0,0 +1,142 @@
/******************************************************************************
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_CONFIG_INCLUDED
#define ETL_TIMER_CONFIG_INCLUDED
#include "platform.h"
#include "nullptr.h"
#include "timer.h"
#include <stdint.h>
//*****************************************************************************
// Definitions common to intrusive timers.
//*****************************************************************************
#if defined(ETL_IN_UNIT_TEST)
namespace
{
class etl_unit_test_intrusive_timer;
}
#endif
namespace etl
{
namespace private_timer
{
class register_list;
class active_list;
class expired_list;
} // namespace private_timer
class intrusive_timer;
class imessage_router;
namespace timer
{
class node;
//***************************************************************************
/// A timer configuration data structure.
//***************************************************************************
class config
{
public:
friend class private_timer::register_list;
friend class private_timer::active_list;
friend class private_timer::expired_list;
friend class node;
friend class intrusive_timer;
//*******************************************
/// Default constructor.
//*******************************************
ETL_CONSTEXPR config() ETL_NOEXCEPT
: interval(etl::timer::interval::No_Interval)
, mode(etl::timer::mode::No_Mode)
, id(etl::timer::id::No_Timer)
{
}
//*******************************************
/// Constructor.
//*******************************************
ETL_CONSTEXPR config(uint32_t interval_, etl::timer::mode::type mode_) ETL_NOEXCEPT
: interval(interval_)
, mode(mode_)
, id(etl::timer::id::No_Timer)
{
}
//*******************************************
/// Returns the interval of the timer.
//*******************************************
ETL_CONSTEXPR uint32_t get_interval() const ETL_NOEXCEPT
{
return interval;
}
//*******************************************
/// Returns the mode of the timer.
//*******************************************
ETL_CONSTEXPR etl::timer::mode::type 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
{
interval = etl::timer::interval::No_Interval;
mode = etl::timer::mode::No_Mode;
id = etl::timer::id::No_Timer;
}
private:
uint32_t interval; ///< The interval 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.
};
} // namespace timer
} // namespace etl
#endif

View File

@ -0,0 +1,103 @@
/******************************************************************************
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_LOCK_POLICY_INCLUDED
#define ETL_TIMER_LOCK_POLICY_INCLUDED
#include "platform.h"
#if ETL_HAS_ATOMIC
#include "atomic.h"
#endif
namespace etl
{
namespace timer
{
//***************************************************************************
/// Interface for timer lock policy
//***************************************************************************
class lock_policy
{
public:
virtual ~lock_policy() ETL_NOEXCEPT {}
virtual void lock() ETL_NOEXCEPT = 0;
virtual void unlock() ETL_NOEXCEPT = 0;
virtual bool is_locked() ETL_NOEXCEPT = 0;
};
//***************************************************************************
/// No lock policy for timers.
//***************************************************************************
class no_lock_policy : public lock_policy
{
public:
void lock() ETL_NOEXCEPT ETL_OVERRIDE {}
void unlock() ETL_NOEXCEPT ETL_OVERRIDE {}
bool is_locked() ETL_NOEXCEPT ETL_OVERRIDE
{
return false;
}
};
#if ETL_HAS_ATOMIC
//***************************************************************************
/// Atomic lock policy for timers.
//***************************************************************************
class atomic_lock_policy : public lock_policy
{
public:
void lock() ETL_NOEXCEPT ETL_OVERRIDE
{
lock_flag.store(true, etl::memory_order_seq_cst);
}
void unlock() ETL_NOEXCEPT ETL_OVERRIDE
{
lock_flag.store(false, etl::memory_order_seq_cst);
}
bool is_locked() ETL_NOEXCEPT ETL_OVERRIDE
{
return lock_flag.load(etl::memory_order_seq_cst);
}
private:
etl::atomic_bool lock_flag;
};
}
}
#endif
#endif

View File

@ -32,6 +32,7 @@ SOFTWARE.
#include "platform.h"
#include "nullptr.h"
#include "timer.h"
#include "timer_config.h"
#include <stdint.h>
@ -50,371 +51,331 @@ namespace etl
{
namespace private_timer
{
class timer_register_list;
class timer_active_list;
class timer_expired_list;
class register_list;
class active_list;
class expired_list;
} // namespace private_timer
class timer_node;
class intrusive_timer;
class imessage_router;
//***************************************************************************
/// A timer configuration data structure.
//***************************************************************************
class timer_config
namespace timer
{
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;
//*******************************************
/// Default constructor.
//*******************************************
ETL_CONSTEXPR timer_config() ETL_NOEXCEPT
: interval(etl::timer::interval::No_Interval)
, mode(etl::timer::mode::No_Mode)
, id(etl::timer::id::No_Timer)
//***************************************************************************
/// A timer data structure that can be linked into the timer lists.
/// Contains a timer configuration.
///
/// registered_next points to the next node in registered list.
/// - A value of etl::timer::node::unlinked() indicates that the timer is not in the registered list.
/// - A value of etl::timer::node::end() indicates that the timer is the last in the list.
///
/// active_next points to the next node in active list.
/// - A value of etl::timer::node::unlinked() indicates that the timer is not in the active list.
/// - A value of etl::timer::node::end() indicates that the timer is the last in the list.
///
/// expired_next points to the next node in expired list.
/// - A value of etl::timer::node::unlinked() indicates that the timer is not in the expired list.
/// - A value of etl::timer::node::end() indicates that the timer is the last in the list.
///
//***************************************************************************
class node
{
}
public:
//*******************************************
/// Constructor.
//*******************************************
ETL_CONSTEXPR timer_config(uint32_t interval_, etl::timer::mode::type mode_) ETL_NOEXCEPT
: interval(interval_)
, mode(mode_)
, id(etl::timer::id::No_Timer)
{
}
friend class private_timer::register_list;
friend class private_timer::active_list;
friend class private_timer::expired_list;
//*******************************************
/// Returns the interval of the timer.
//*******************************************
ETL_CONSTEXPR uint32_t get_interval() const ETL_NOEXCEPT
{
return interval;
}
//*******************************************
/// Returns the mode of the timer.
//*******************************************
ETL_CONSTEXPR etl::timer::mode::type 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
{
interval = etl::timer::interval::No_Interval;
mode = etl::timer::mode::No_Mode;
id = etl::timer::id::No_Timer;
}
private:
uint32_t interval; ///< The interval 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.
};
//***************************************************************************
/// A timer data structure that can be linked into the timer lists.
/// Contains a timer configuration.
///
/// registered_next points to the next node in registered list.
/// - A value of etl::timer_node::unlinked() indicates that the timer is not in the registered list.
/// - A value of etl::timer_node::end() indicates that the timer is the last in the list.
///
/// active_next points to the next node in active list.
/// - A value of etl::timer_node::unlinked() indicates that the timer is not in the active list.
/// - A value of etl::timer_node::end() indicates that the timer is the last in the list.
///
/// expired_next points to the next node in expired list.
/// - A value of etl::timer_node::unlinked() indicates that the timer is not in the expired list.
/// - A value of etl::timer_node::end() indicates that the timer is the last in the list.
///
//***************************************************************************
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;
friend class intrusive_timer;
#if defined(ETL_IN_UNIT_TEST)
friend class etl_unit_test_intrusive_timer;
friend class etl_unit_test_intrusive_timer;
#endif
//*******************************************
/// Constructor.
//*******************************************
timer_node(const timer_config& config_) ETL_NOEXCEPT
: registered_next(unlinked())
, active_next(unlinked())
, expired_next(unlinked())
, owner(etl::timer::owner::No_Owner)
, config(config_)
, delta(config_.get_interval())
{
}
//*******************************************
/// Constructor.
//*******************************************
node(const config& config_) ETL_NOEXCEPT
: registered_next(unlinked())
, active_next(unlinked())
, expired_next(unlinked())
, owner(etl::timer::owner::No_Owner)
, config(config_)
, delta(config_.get_interval())
{
}
//*******************************************
/// Copy constructor.
//*******************************************
timer_node(const timer_node& node_) ETL_NOEXCEPT
: registered_next(unlinked())
, active_next(unlinked())
, expired_next(unlinked())
, owner(etl::timer::owner::No_Owner)
, config(node_.config)
, delta(node_.config.get_interval())
{
}
//*******************************************
/// Copy constructor.
//*******************************************
node(const node& node_) ETL_NOEXCEPT
: registered_next(unlinked())
, active_next(unlinked())
, expired_next(unlinked())
, owner(etl::timer::owner::No_Owner)
, config(node_.config)
, delta(node_.config.get_interval())
{
}
//*******************************************
/// Returns the configuration of the timer.
//*******************************************
const timer_config& get_config() const ETL_NOEXCEPT
{
return config;
}
//*******************************************
/// Destructor (virtual).
//*******************************************
virtual ~node() ETL_NOEXCEPT {}
//*******************************************
/// Returns the delta of the timer.
//*******************************************
ETL_CONSTEXPR uint32_t get_delta() const ETL_NOEXCEPT
{
return delta;
}
//*******************************************
/// Returns the configuration of the timer.
//*******************************************
const config& get_config() const ETL_NOEXCEPT
{
return config;
}
//*******************************************
/// Returns the interval of the timer.
//*******************************************
ETL_CONSTEXPR uint32_t get_interval() const ETL_NOEXCEPT
{
return config.get_interval();
}
//*******************************************
/// Returns the delta of the timer.
//*******************************************
ETL_CONSTEXPR uint32_t get_delta() const ETL_NOEXCEPT
{
return delta;
}
//*******************************************
/// Returns the mode of the timer.
//*******************************************
ETL_CONSTEXPR etl::timer::mode::type get_mode() const ETL_NOEXCEPT
{
return config.get_mode();
}
//*******************************************
/// Returns the interval of the timer.
//*******************************************
ETL_CONSTEXPR uint32_t get_interval() const ETL_NOEXCEPT
{
return config.get_interval();
}
//*******************************************
/// Returns the id of the timer.
//*******************************************
ETL_CONSTEXPR etl::timer::id::type get_id() const ETL_NOEXCEPT
{
return config.get_id();
}
//*******************************************
/// Returns the mode of the timer.
//*******************************************
ETL_CONSTEXPR etl::timer::mode::type 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();
}
//***************************************************************************
/// Returns a pointer to the static 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* end() ETL_NOEXCEPT
{
static etl::timer::node sentinel_node(etl::timer::config(etl::timer::interval::No_Interval, etl::timer::mode::Single_Shot));
return &sentinel_node;
}
private:
//*******************************************
/// Sets the configuration of the timer.
//*******************************************
void set_config(const config& config_) ETL_NOEXCEPT
{
set_interval(config_.get_interval());
set_mode(config_.get_mode());
}
//*******************************************
/// Sets the interval of the timer.
//*******************************************
void set_interval(uint32_t interval_) ETL_NOEXCEPT
{
config.interval = interval_;
}
//*******************************************
/// Sets the mode of the timer.
//*******************************************
void set_mode(etl::timer::mode::type mode_) ETL_NOEXCEPT
{
config.mode = mode_;
}
//*******************************************
/// Sets the ID of the timer.
//*******************************************
void set_id(etl::timer::id::type id_) ETL_NOEXCEPT
{
config.id = id_;
}
//*******************************************
/// Sets the owner of the timer.
//*******************************************
void set_owner(void* owner_) ETL_NOEXCEPT
{
owner = owner_;
}
//*******************************************
/// Returns a nullptr to indicate that the timer is not linked into any list.
//*******************************************
static etl::timer::node* unlinked() ETL_NOEXCEPT
{
return ETL_NULLPTR;
}
//*******************************************
/// Clear the node.
//*******************************************
void clear() ETL_NOEXCEPT
{
config.clear();
registered_next = unlinked();
active_next = unlinked();
expired_next = unlinked();
owner = etl::timer::owner::No_Owner;
delta = config.get_interval();
}
//*******************************************
/// Returns true if the timer is registered to the specified owner.
//*******************************************
bool is_registered_with(const void* owner_) const ETL_NOEXCEPT
{
return (registered_next != unlinked()) && (owner == owner_);
}
//*******************************************
/// Returns true if the timer is registered to an owner.
//*******************************************
bool is_registered() const ETL_NOEXCEPT
{
return (registered_next != unlinked()) && (owner != ETL_NULLPTR);
}
//*******************************************
/// Returns true if the timer is active.
//*******************************************
bool is_active() const ETL_NOEXCEPT
{
return active_next != unlinked();
}
//*******************************************
/// Returns true if the timer has expired.
//*******************************************
bool has_expired() const ETL_NOEXCEPT
{
return expired_next != unlinked();
}
//*******************************************
/// Invokes the timer's callback.
//*******************************************
virtual void invoke()
{
// Default implementation does nothing.
}
node& operator=(const node&) ETL_DELETE;
node* registered_next; ///< The next timer in the registered timer list. unlinked() if the timer is not registered.
node* active_next; ///< The next timer in the active timer list. unlinked() if the timer is not active.
node* expired_next; ///< The next timer in the expired timer list. unlinked() if the timer is not expired.
void* owner; ///< The owner of the timer.
config config; ///< The configuration of the timer.
uint32_t delta; ///< The time remaining until the timer expires.
};
//***************************************************************************
/// Returns a pointer to the static 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.
/// A timer node that invokes a callback type.
/// The callback is copied.
//***************************************************************************
static etl::timer_node* end() ETL_NOEXCEPT
template <typename TCallback>
struct callback_node : public etl::timer::node
{
static etl::timer_node sentinel_node(etl::timer_config(etl::timer::interval::No_Interval, etl::timer::mode::Single_Shot));
//*******************************************
/// Constructor.
//*******************************************
callback_node(const etl::timer::config& config_, TCallback callback_) ETL_NOEXCEPT
: node(config_)
, callback(callback_)
{
}
return &sentinel_node;
}
//*******************************************
/// Invokes the timer's callback.
//*******************************************
virtual void invoke() ETL_OVERRIDE
{
callback();
}
private:
TCallback callback; ///< The callback for the timer.
};
//*******************************************
/// Sets the configuration of the timer.
//*******************************************
void set_config(const timer_config& config_) ETL_NOEXCEPT
//***************************************************************************
/// A timer node that invokes a functor type.
/// Stores a reference to the functor.
//***************************************************************************
template <typename TCallback>
struct callback_ref_node : public etl::timer::node
{
set_interval(config_.get_interval());
set_mode(config_.get_mode());
}
//*******************************************
/// Constructor.
//*******************************************
callback_ref_node(const etl::timer::config& config_, TCallback& callback_) ETL_NOEXCEPT
: node(config_)
, callback(&callback_)
{
}
//*******************************************
/// Sets the interval of the timer.
//*******************************************
void set_interval(uint32_t interval_) ETL_NOEXCEPT
//*******************************************
/// Invokes the timer's callback.
//*******************************************
virtual void invoke() ETL_OVERRIDE
{
(*callback)();
}
TCallback* callback; ///< The callback for the timer.
};
//***************************************************************************
/// A timer node that invokes a message callback.
//***************************************************************************
template <typename TMessage>
struct message_node : public etl::timer::node
{
config.interval = interval_;
}
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "TMessage must derive from etl::imessage");
//*******************************************
/// Sets the mode of the timer.
//*******************************************
void set_mode(etl::timer::mode::type mode_) ETL_NOEXCEPT
{
config.mode = mode_;
}
//*******************************************
/// Constructor.
//*******************************************
message_node(const etl::timer::config& config_, etl::imessage_router& router_, TMessage message_) ETL_NOEXCEPT
: node(config_)
, router(&router_)
, message(message_)
{
}
//*******************************************
/// Sets the ID of the timer.
//*******************************************
void set_id(etl::timer::id::type id_) ETL_NOEXCEPT
{
config.id = id_;
}
//*******************************************
/// Invokes the timer's callback.
//*******************************************
virtual void invoke() ETL_OVERRIDE
{
router->receive(message);
}
//*******************************************
/// Sets the owner of the timer.
//*******************************************
void set_owner(void* owner_) ETL_NOEXCEPT
{
owner = owner_;
}
//*******************************************
/// Returns a nullptr to indicate that the timer is not linked into any list.
//*******************************************
static etl::timer_node* unlinked() ETL_NOEXCEPT
{
return ETL_NULLPTR;
}
//*******************************************
/// Clear the node.
//*******************************************
void clear() ETL_NOEXCEPT
{
config.clear();
registered_next = unlinked();
active_next = unlinked();
expired_next = unlinked();
owner = etl::timer::owner::No_Owner;
delta = config.get_interval();
}
//*******************************************
/// Returns true if the timer is registered to the specified owner.
//*******************************************
bool is_registered_with(const void* owner_) const ETL_NOEXCEPT
{
return (registered_next != unlinked()) && (owner == owner_);
}
//*******************************************
/// Returns true if the timer is registered to an owner.
//*******************************************
bool is_registered() const ETL_NOEXCEPT
{
return (registered_next != unlinked()) && (owner != ETL_NULLPTR);
}
//*******************************************
/// Returns true if the timer is active.
//*******************************************
bool is_active() const ETL_NOEXCEPT
{
return active_next != unlinked();
}
//*******************************************
/// Returns true if the timer has expired.
//*******************************************
bool has_expired() const ETL_NOEXCEPT
{
return expired_next != unlinked();
}
//*******************************************
/// Invokes the timer's callback.
//*******************************************
virtual void invoke()
{
// Default implementation does nothing.
}
timer_node& operator=(const timer_node&) ETL_DELETE;
timer_node* registered_next; ///< The next timer in the registered timer list. unlinked() if the timer is not registered.
timer_node* active_next; ///< The next timer in the active timer list. unlinked() if the timer is not active.
timer_node* expired_next; ///< The next timer in the expired timer list. unlinked() if the timer is not expired.
void* owner; ///< The owner of the timer.
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 type.
//***************************************************************************
template <typename TCallback>
struct timer_callback_node : public timer_node
{
//*******************************************
/// Constructor.
//*******************************************
timer_callback_node(const etl::timer_config& config_, TCallback callback_) ETL_NOEXCEPT
: timer_node(config_)
, callback(callback_)
{
}
//*******************************************
/// Invokes the timer's callback.
//*******************************************
virtual void invoke() ETL_OVERRIDE
{
callback();
}
TCallback callback; ///< The callback delegate for the timer.
};
//***************************************************************************
/// A timer node that invokes a message callback.
//***************************************************************************
template <typename TMessage>
struct timer_message_node : public timer_node
{
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "TMessage must derive from etl::imessage");
//*******************************************
/// Constructor.
//*******************************************
timer_message_node(const etl::timer_config& config_, etl::imessage_router& router_, TMessage message_) ETL_NOEXCEPT
: timer_node(config_)
, router(&router_)
, message(message_)
{
}
//*******************************************
/// Invokes the timer's callback.
//*******************************************
virtual void invoke() ETL_OVERRIDE
{
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.
};
etl::imessage_router* router; ///< The message router to send the message to.
TMessage message; ///< The message to send when the timer expires.
};
} // namespace timer
} // namespace etl
#endif

View File

@ -0,0 +1,57 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2017 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_NOTIFICATION_INCLUDED
#define ETL_TIMER_NOTIFICATION_INCLUDED
#include "platform.h"
//*****************************************************************************
// Definitions common to timers.
//*****************************************************************************
namespace etl
{
namespace timer
{
//***************************************************************************
/// Default class for time to next notification
//***************************************************************************
class time_to_next_notification
{
public:
virtual void invoke(uint32_t)
{
// Do nothing by default.
}
};
}; // namespace timer
} // namespace etl
#endif

View File

@ -0,0 +1,59 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2017 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_NOTIFICATION_INCLUDED
#define ETL_TIMER_NOTIFICATION_INCLUDED
#include "platform.h"
//*****************************************************************************
// Definitions common to timers.
//*****************************************************************************
namespace etl
{
namespace timer
{
//***************************************************************************
/// Default class for time to next notification
//***************************************************************************
class timer_time_to_next_notification
{
public:
virtual ~timer_time_to_next_notification() ETL_NOEXCEPT {}
virtual void invoke(uint32_t)
{
// Do nothing by default.
}
};
}; // namespace timer
} // namespace etl
#endif

View File

@ -33,6 +33,7 @@ SOFTWARE.
#include "etl/intrusive_timer.h"
#include "etl/message.h"
#include "etl/message_router.h"
#include "etl/delegate.h"
#include "etl/timer.h"
#include "etl/timer_node.h"
@ -56,13 +57,13 @@ namespace
/// A lock policy that counts the number of times it is locked and unlocked.
/// The lock count should always be 0 or 1.
//***************************************************************************
class LockPolicy : public etl::timer_lock_policy
class LockPolicy : public etl::timer::lock_policy
{
public:
//*******************************************
LockPolicy()
: timer_lock_policy()
: etl::timer::lock_policy()
, count(0)
{
}
@ -108,7 +109,7 @@ namespace
//*************************************************************************
using CallbackDelegate = etl::delegate<void()>;
using CallbackTimer = etl::timer_callback_node<CallbackDelegate>;
using CallbackTimer = etl::timer::callback_node<CallbackDelegate>;
//*************************************************************************
bool global_callback_called = false;
@ -164,8 +165,8 @@ namespace
{
}
int value;
const etl::timer_config* config;
int value;
const etl::timer::config* config;
};
class MessageProcessor : public etl::message_router<MessageProcessor, CallbackMessage>
@ -204,7 +205,7 @@ namespace
uint64_t message_call_count;
};
using MessageTimer = etl::timer_message_node<CallbackMessage>;
using MessageTimer = etl::timer::message_node<CallbackMessage>;
MessageProcessor message_processor;
CallbackMessage callback_message(42);
@ -218,7 +219,7 @@ namespace
/// A timer_time_to_next_notification that calls next_timer_notification().
/// Passed to the intrusive timer to notify the user of the time to the next timer that is due to expire.
//***********************************
class time_to_next_notification : public etl::timer_time_to_next_notification
class time_to_next_notification : public etl::timer::time_to_next_notification
{
public:
@ -251,9 +252,9 @@ namespace
etl::intrusive_timer timer_controller(lock_policy);
etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot));
etl::timer_node node2(etl::timer_config(200, etl::timer::mode::Repeating));
etl::timer_node node3(etl::timer_config(300, etl::timer::mode::Repeating));
etl::timer::node node1(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::node node2(etl::timer::config(200, etl::timer::mode::Repeating));
etl::timer::node node3(etl::timer::config(300, etl::timer::mode::Repeating));
CHECK_FALSE(timer_controller.is_registered(node1));
CHECK_FALSE(timer_controller.is_registered(node2));
@ -283,7 +284,7 @@ namespace
etl::intrusive_timer timer_controller1(lock_policy);
etl::intrusive_timer timer_controller2(lock_policy);
etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot));
etl::timer::node node1(etl::timer::config(100, etl::timer::mode::Single_Shot));
bool success = false;
@ -308,7 +309,7 @@ namespace
etl::intrusive_timer timer_controller1(lock_policy);
etl::intrusive_timer timer_controller2(lock_policy);
etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot));
etl::timer::node node1(etl::timer::config(100, etl::timer::mode::Single_Shot));
bool success = false;
@ -332,7 +333,7 @@ namespace
etl::intrusive_timer timer_controller(lock_policy);
etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot));
etl::timer::node node1(etl::timer::config(100, etl::timer::mode::Single_Shot));
// Start without registering.
CHECK_FALSE(timer_controller.start(node1));
@ -373,10 +374,10 @@ namespace
etl::intrusive_timer timer_controller(lock_policy);
etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Repeating));
etl::timer_node node2(etl::timer_config(200, etl::timer::mode::Repeating));
etl::timer_node node3(etl::timer_config(300, etl::timer::mode::Repeating));
etl::timer_node node4(etl::timer_config(400, etl::timer::mode::Repeating));
etl::timer::node node1(etl::timer::config(100, etl::timer::mode::Repeating));
etl::timer::node node2(etl::timer::config(200, etl::timer::mode::Repeating));
etl::timer::node node3(etl::timer::config(300, etl::timer::mode::Repeating));
etl::timer::node node4(etl::timer::config(400, etl::timer::mode::Repeating));
timer_controller.register_timer(node1);
timer_controller.register_timer(node2);
@ -392,7 +393,7 @@ namespace
CHECK_EQUAL(&node1, timer_controller.find_timer(node1.get_id()));
CHECK_EQUAL(&node2, timer_controller.find_timer(node2.get_id()));
CHECK_EQUAL(&node3, timer_controller.find_timer(node3.get_id()));
CHECK_EQUAL(etl::timer_node::end(), timer_controller.find_timer(node4.get_id()));
CHECK_EQUAL(etl::timer::node::end(), timer_controller.find_timer(node4.get_id()));
}
//*************************************************************************
@ -402,9 +403,9 @@ namespace
etl::intrusive_timer timer_controller(lock_policy);
etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot));
etl::timer_node node2(etl::timer_config(200, etl::timer::mode::Repeating));
etl::timer_node node3(etl::timer_config(300, etl::timer::mode::Repeating));
etl::timer::node node1(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::node node2(etl::timer::config(200, etl::timer::mode::Repeating));
etl::timer::node node3(etl::timer::config(300, etl::timer::mode::Repeating));
timer_controller.register_timer(node1);
timer_controller.register_timer(node2);
@ -428,9 +429,9 @@ namespace
etl::intrusive_timer timer_controller(lock_policy);
etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot));
etl::timer_node node2(etl::timer_config(200, etl::timer::mode::Repeating));
etl::timer_node node3(etl::timer_config(300, etl::timer::mode::Repeating));
etl::timer::node node1(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::node node2(etl::timer::config(200, etl::timer::mode::Repeating));
etl::timer::node node3(etl::timer::config(300, etl::timer::mode::Repeating));
timer_controller.register_timer(node1);
timer_controller.register_timer(node2);
@ -464,18 +465,18 @@ namespace
etl::intrusive_timer timer_controller(lock_policy);
etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot));
etl::timer_node node2(etl::timer_config(200, etl::timer::mode::Repeating));
etl::timer_node node3(etl::timer_config(300, etl::timer::mode::Repeating));
etl::timer::node node1(etl::timer::config(100, etl::timer::mode::Single_Shot));
etl::timer::node node2(etl::timer::config(200, etl::timer::mode::Repeating));
etl::timer::node node3(etl::timer::config(300, etl::timer::mode::Repeating));
timer_controller.register_timer(node1);
timer_controller.register_timer(node2);
timer_controller.register_timer(node3);
// Modify the timer configs.
etl::timer_config config1(150, etl::timer::mode::Repeating);
etl::timer_config config2(250, etl::timer::mode::Single_Shot);
etl::timer_config config3(350, etl::timer::mode::Single_Shot);
etl::timer::config config1(150, etl::timer::mode::Repeating);
etl::timer::config config2(250, etl::timer::mode::Single_Shot);
etl::timer::config config3(350, etl::timer::mode::Single_Shot);
timer_controller.set_config(node1, config1);
timer_controller.set_config(node2, config2);
@ -502,18 +503,18 @@ namespace
time_to_next.clear();
global_callback_clear();
etl::timer_config config1(37, etl::timer::mode::Single_Shot);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
etl::timer::config config1(37, etl::timer::mode::Single_Shot);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
object.clear();
etl::timer_config config2(23, etl::timer::mode::Single_Shot);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
etl::timer::config config2(23, etl::timer::mode::Single_Shot);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
message_processor.clear();
etl::timer_config config3(11, etl::timer::mode::Single_Shot);
MessageTimer callback_timer3(config3, message_processor, callback_message);
etl::timer::config config3(11, etl::timer::mode::Single_Shot);
MessageTimer callback_timer3(config3, message_processor, callback_message);
timer_controller.register_timer(callback_timer1);
timer_controller.register_timer(callback_timer2);
@ -566,18 +567,18 @@ namespace
time_to_next.clear();
global_callback_clear();
etl::timer_config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
etl::timer::config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
object.clear();
etl::timer_config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
etl::timer::config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
message_processor.clear();
etl::timer_config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
etl::timer::config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
timer_controller.register_timer(callback_timer1);
timer_controller.register_timer(callback_timer2);
@ -647,18 +648,18 @@ namespace
time_to_next.clear();
global_callback_clear();
etl::timer_config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
etl::timer::config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
object.clear();
etl::timer_config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
etl::timer::config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
message_processor.clear();
etl::timer_config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
etl::timer::config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
timer_controller.register_timer(callback_timer1);
timer_controller.register_timer(callback_timer2);
@ -727,18 +728,18 @@ namespace
time_to_next.clear();
global_callback_clear();
etl::timer_config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
etl::timer::config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
object.clear();
etl::timer_config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
etl::timer::config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
message_processor.clear();
etl::timer_config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
etl::timer::config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
timer_controller.register_timer(callback_timer2);
timer_controller.register_timer(callback_timer3);
@ -804,18 +805,18 @@ namespace
time_to_next.clear();
global_callback_clear();
etl::timer_config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
etl::timer::config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
object.clear();
etl::timer_config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
etl::timer::config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
message_processor.clear();
etl::timer_config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
etl::timer::config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
timer_controller.register_timer(callback_timer1);
timer_controller.register_timer(callback_timer2);
@ -888,18 +889,18 @@ namespace
time_to_next.clear();
global_callback_clear();
etl::timer_config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
etl::timer::config config1(37, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback);
CallbackTimer callback_timer1(config1, callback_delegate1);
object.clear();
etl::timer_config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
etl::timer::config config2(23, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create<Object, &Object::member, object>();
CallbackTimer callback_timer2(config2, callback_delegate2);
message_processor.clear();
etl::timer_config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
etl::timer::config config3(11, etl::timer::mode::Repeating);
MessageTimer callback_timer3(config3, message_processor, callback_message);
timer_controller.register_timer(callback_timer1);
timer_controller.register_timer(callback_timer2);
@ -959,6 +960,132 @@ namespace
}
//*************************************************************************
struct FunctorExternalCount
{
FunctorExternalCount(int& call_count_)
: call_count(&call_count_)
{
}
void operator()()
{
++(*call_count);
}
int* call_count;
};
TEST(test_intrusive_timer_with_functor_with_pointer_to_count)
{
int call_count = 0;
FunctorExternalCount timer_functor(call_count);
LockPolicy lock_policy;
etl::intrusive_timer timer_controller(lock_policy);
etl::timer::callback_node node1(etl::timer::config(1, etl::timer::mode::Single_Shot), timer_functor);
timer_controller.register_timer(node1);
timer_controller.enable(true);
timer_controller.start(node1);
timer_controller.tick(1);
CHECK_EQUAL(1, call_count);
}
//*************************************************************************
struct FunctorInternalCount
{
FunctorInternalCount()
: call_count(0)
{
}
void operator()()
{
++call_count;
}
int call_count;
};
TEST(test_intrusive_timer_with_functor_reference)
{
FunctorInternalCount timer_functor;
LockPolicy lock_policy;
etl::intrusive_timer timer_controller(lock_policy);
etl::timer::callback_ref_node node1(etl::timer::config(1, etl::timer::mode::Single_Shot), timer_functor);
timer_controller.register_timer(node1);
timer_controller.enable(true);
timer_controller.start(node1);
timer_controller.tick(1);
CHECK_EQUAL(1, timer_functor.call_count);
}
//*************************************************************************
TEST(test_intrusive_timer_with_lambda)
{
int call_count = 0;
auto timer_lambda = [&call_count]()
{
++call_count;
};
LockPolicy lock_policy;
etl::intrusive_timer timer_controller(lock_policy);
etl::timer::callback_node node1(etl::timer::config(1, etl::timer::mode::Single_Shot), timer_lambda);
timer_controller.register_timer(node1);
timer_controller.enable(true);
timer_controller.start(node1);
timer_controller.tick(1);
CHECK_EQUAL(1, call_count);
}
//*************************************************************************
struct Object
{
Object()
: call_count(0)
{
}
void Increment()
{
++call_count;
}
int call_count;
};
static Object object;
TEST(test_intrusive_timer_with_delegate)
{
auto delegate = etl::delegate<void()>::create<Object, &Object::Increment, object>();
etl::timer::config config(etl::timer::config(1, etl::timer::mode::Single_Shot));
etl::timer::callback_node node(config, delegate);
LockPolicy lock_policy;
etl::intrusive_timer timer_controller(lock_policy);
timer_controller.register_timer(node);
timer_controller.enable(true);
timer_controller.start(node);
timer_controller.tick(1);
CHECK_EQUAL(1, object.call_count);
}
//*************************************************************************
#if REALTIME_TEST
#if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently
@ -971,7 +1098,7 @@ namespace
#endif
//*************************************************************************
class semaphore_lock_policy : public etl::timer_lock_policy
class semaphore_lock_policy : public etl::timer::lock_policy
{
public:
@ -1014,17 +1141,17 @@ namespace
static void real_time_callback2();
static void real_time_callback3();
etl::timer_config config1(10, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(real_time_callback1);
CallbackTimer callback_timer1(config1, callback_delegate1);
etl::timer::config config1(10, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate1 = CallbackDelegate::create(real_time_callback1);
CallbackTimer callback_timer1(config1, callback_delegate1);
etl::timer_config config2(10, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create(real_time_callback2);
CallbackTimer callback_timer2(config2, callback_delegate2);
etl::timer::config config2(10, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate2 = CallbackDelegate::create(real_time_callback2);
CallbackTimer callback_timer2(config2, callback_delegate2);
etl::timer_config config3(10, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate3 = CallbackDelegate::create(real_time_callback3);
CallbackTimer callback_timer3(config3, callback_delegate3);
etl::timer::config config3(10, etl::timer::mode::Repeating);
CallbackDelegate callback_delegate3 = CallbackDelegate::create(real_time_callback3);
CallbackTimer callback_timer3(config3, callback_delegate3);
int real_time_callback_count1 = 0;
int real_time_callback_count2 = 0;

View File

@ -0,0 +1,78 @@
/******************************************************************************
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.
******************************************************************************/
#include "unit_test_framework.h"
#include "etl/timer_node.h"
namespace
{
SUITE(test_timer_config_and_node)
{
//*************************************************************************
TEST(test_timer_config)
{
constexpr etl::timer::config config1(100U, etl::timer::mode::Repeating);
CHECK_EQUAL(100U, config1.get_interval());
CHECK_EQUAL(etl::timer::mode::Repeating, config1.get_mode());
etl::timer::config config2(200U, etl::timer::mode::Single_Shot);
CHECK_EQUAL(200U, config2.get_interval());
CHECK_EQUAL(etl::timer::mode::Single_Shot, config2.get_mode());
etl::timer::config config3(config2);
CHECK_EQUAL(config2.get_interval(), config3.get_interval());
CHECK_EQUAL(etl::timer::mode::Single_Shot, config2.get_mode());
etl::timer::config config4 = etl::timer::config(500U, etl::timer::mode::Repeating);
CHECK_EQUAL(500U, config4.get_interval());
CHECK_EQUAL(etl::timer::mode::Repeating, config4.get_mode());
config2.clear();
CHECK_EQUAL(etl::timer::interval::No_Interval, config2.get_interval());
CHECK_EQUAL(etl::timer::mode::No_Mode, config2.get_mode());
}
//*************************************************************************
TEST(test_timer_node)
{
constexpr etl::timer::config config1(100U, etl::timer::mode::Repeating);
etl::timer::node node1(config1);
etl::timer::node node2(node1);
const etl::timer::config& config1_ref = node1.get_config();
CHECK_EQUAL(config1.get_interval(), node1.get_config().get_interval());
CHECK_EQUAL(config1.get_mode(), node1.get_config().get_mode());
CHECK_EQUAL(node1.get_config().get_interval(), node2.get_config().get_interval());
CHECK_EQUAL(node1.get_config().get_mode(), node2.get_config().get_mode());
}
}
} // namespace

View File

@ -39,7 +39,7 @@ namespace
public:
//*************************************************************************
void register_timer(etl::private_timer::timer_register_list& register_list, etl::timer_node& timer_)
void register_timer(etl::private_timer::register_list& register_list, etl::timer::node& timer_)
{
timer_.set_id(get_next_id(register_list));
register_list.insert(&timer_);
@ -47,11 +47,11 @@ namespace
}
//*******************************************
etl::timer::id::type get_next_id(etl::private_timer::timer_register_list& register_list) ETL_NOEXCEPT
etl::timer::id::type get_next_id(etl::private_timer::register_list& register_list) ETL_NOEXCEPT
{
etl::timer::id::type next_id = 0; // IDs start at 0
etl::timer_node* timer = register_list.first();
etl::timer::node* timer = register_list.first();
while (timer != register_list.end())
{
@ -81,18 +81,18 @@ namespace
//*************************************************************************
TEST(test_timer_register_list)
{
constexpr etl::timer_config timer1_config(100, etl::timer::mode::Repeating);
constexpr etl::timer_config timer2_config(65, etl::timer::mode::Repeating);
constexpr etl::timer_config timer3_config(85, etl::timer::mode::Repeating);
constexpr etl::timer_config timer4_config(130, etl::timer::mode::Repeating);
constexpr etl::timer_config timer5_config(85, etl::timer::mode::Repeating);
etl::timer_node timer1{timer1_config};
etl::timer_node timer2{timer2_config};
etl::timer_node timer3{timer3_config};
etl::timer_node timer4{timer4_config};
etl::timer_node timer5{timer5_config};
constexpr etl::timer::config timer1_config(100, etl::timer::mode::Repeating);
constexpr etl::timer::config timer2_config(65, etl::timer::mode::Repeating);
constexpr etl::timer::config timer3_config(85, etl::timer::mode::Repeating);
constexpr etl::timer::config timer4_config(130, etl::timer::mode::Repeating);
constexpr etl::timer::config timer5_config(85, etl::timer::mode::Repeating);
etl::timer::node timer1{timer1_config};
etl::timer::node timer2{timer2_config};
etl::timer::node timer3{timer3_config};
etl::timer::node timer4{timer4_config};
etl::timer::node timer5{timer5_config};
etl::private_timer::timer_register_list register_list;
etl::private_timer::register_list register_list;
CHECK_TRUE(register_list.empty());
CHECK_TRUE(register_list.first() == register_list.end());
@ -120,7 +120,7 @@ namespace
bool timer4_found = false;
bool timer5_found = false;
etl::timer_node* timer = register_list.first();
etl::timer::node* timer = register_list.first();
while (timer != register_list.end())
{
@ -164,21 +164,21 @@ namespace
//*************************************************************************
TEST(test_timer_active_list)
{
constexpr etl::timer_config timer1_config(100, etl::timer::mode::Repeating);
constexpr etl::timer_config timer2_config(65, etl::timer::mode::Repeating);
constexpr etl::timer_config timer3_config(85, etl::timer::mode::Repeating);
constexpr etl::timer_config timer4_config(130, etl::timer::mode::Repeating);
constexpr etl::timer_config timer5_config(85, etl::timer::mode::Repeating);
constexpr etl::timer_config timer6_config(85, etl::timer::mode::Repeating);
constexpr etl::timer::config timer1_config(100, etl::timer::mode::Repeating);
constexpr etl::timer::config timer2_config(65, etl::timer::mode::Repeating);
constexpr etl::timer::config timer3_config(85, etl::timer::mode::Repeating);
constexpr etl::timer::config timer4_config(130, etl::timer::mode::Repeating);
constexpr etl::timer::config timer5_config(85, etl::timer::mode::Repeating);
constexpr etl::timer::config timer6_config(85, etl::timer::mode::Repeating);
etl::timer_node timer1(timer1_config);
etl::timer_node timer2(timer2_config);
etl::timer_node timer3(timer3_config);
etl::timer_node timer4(timer4_config);
etl::timer_node timer5(timer5_config);
etl::timer_node timer6(timer6_config);
etl::timer::node timer1(timer1_config);
etl::timer::node timer2(timer2_config);
etl::timer::node timer3(timer3_config);
etl::timer::node timer4(timer4_config);
etl::timer::node timer5(timer5_config);
etl::timer::node timer6(timer6_config);
etl::private_timer::timer_active_list active_list;
etl::private_timer::active_list active_list;
CHECK_TRUE(active_list.empty());
CHECK_TRUE(active_list.first() == active_list.end());
@ -192,7 +192,7 @@ namespace
CHECK_FALSE(active_list.empty());
CHECK_TRUE(active_list.first() == &timer2);
etl::timer_node* timer = active_list.first();
etl::timer::node* timer = active_list.first();
// The timers should be in the order of their intervals.
CHECK_EQUAL(&timer2, timer);
@ -277,18 +277,18 @@ namespace
//*************************************************************************
TEST(test_timer_expired_list)
{
constexpr etl::timer_config timer1_config(100, etl::timer::mode::Repeating);
constexpr etl::timer_config timer2_config(65, etl::timer::mode::Repeating);
constexpr etl::timer_config timer3_config(85, etl::timer::mode::Repeating);
constexpr etl::timer_config timer4_config(130, etl::timer::mode::Repeating);
constexpr etl::timer_config timer5_config(85, etl::timer::mode::Repeating);
etl::timer_node timer1{timer1_config};
etl::timer_node timer2{timer2_config};
etl::timer_node timer3{timer3_config};
etl::timer_node timer4{timer4_config};
etl::timer_node timer5{timer5_config};
constexpr etl::timer::config timer1_config(100, etl::timer::mode::Repeating);
constexpr etl::timer::config timer2_config(65, etl::timer::mode::Repeating);
constexpr etl::timer::config timer3_config(85, etl::timer::mode::Repeating);
constexpr etl::timer::config timer4_config(130, etl::timer::mode::Repeating);
constexpr etl::timer::config timer5_config(85, etl::timer::mode::Repeating);
etl::timer::node timer1{timer1_config};
etl::timer::node timer2{timer2_config};
etl::timer::node timer3{timer3_config};
etl::timer::node timer4{timer4_config};
etl::timer::node timer5{timer5_config};
etl::private_timer::timer_expired_list expired_list;
etl::private_timer::expired_list expired_list;
CHECK_TRUE(expired_list.empty());
CHECK_TRUE(expired_list.first() == expired_list.end());
@ -304,7 +304,7 @@ namespace
CHECK_TRUE(expired_list.first() == &timer1);
// The timers should be in the order they were added.
etl::timer_node* timer = expired_list.first();
etl::timer::node* timer = expired_list.first();
CHECK_EQUAL(&timer1, timer);
timer = expired_list.next(timer);

View File

@ -37,19 +37,19 @@ namespace
//*************************************************************************
TEST(test_timer_config)
{
constexpr etl::timer_config config1(100U, etl::timer::mode::Repeating);
constexpr etl::timer::config config1(100U, etl::timer::mode::Repeating);
CHECK_EQUAL(100U, config1.get_interval());
CHECK_EQUAL(etl::timer::mode::Repeating, config1.get_mode());
etl::timer_config config2(200U, etl::timer::mode::Single_Shot);
etl::timer::config config2(200U, etl::timer::mode::Single_Shot);
CHECK_EQUAL(200U, config2.get_interval());
CHECK_EQUAL(etl::timer::mode::Single_Shot, config2.get_mode());
etl::timer_config config3(config2);
etl::timer::config config3(config2);
CHECK_EQUAL(config2.get_interval(), config3.get_interval());
CHECK_EQUAL(etl::timer::mode::Single_Shot, config2.get_mode());
etl::timer_config config4 = etl::timer_config(500U, etl::timer::mode::Repeating);
etl::timer::config config4 = etl::timer::config(500U, etl::timer::mode::Repeating);
CHECK_EQUAL(500U, config4.get_interval());
CHECK_EQUAL(etl::timer::mode::Repeating, config4.get_mode());
@ -61,12 +61,12 @@ namespace
//*************************************************************************
TEST(test_timer_node)
{
constexpr etl::timer_config config1(100U, etl::timer::mode::Repeating);
constexpr etl::timer::config config1(100U, etl::timer::mode::Repeating);
etl::timer_node node1(config1);
etl::timer_node node2(node1);
etl::timer::node node1(config1);
etl::timer::node node2(node1);
const etl::timer_config& config1_ref = node1.get_config();
const etl::timer::config& config1_ref = node1.get_config();
CHECK_EQUAL(config1.get_interval(), node1.get_config().get_interval());
CHECK_EQUAL(config1.get_mode(), node1.get_config().get_mode());

View File

@ -3561,6 +3561,8 @@
<ClInclude Include="..\..\include\etl\inplace_function.h" />
<ClInclude Include="..\..\include\etl\intrusive_timer.h" />
<ClInclude Include="..\..\include\etl\private\timer_lists.h" />
<ClInclude Include="..\..\include\etl\timer_config.h" />
<ClInclude Include="..\..\include\etl\timer_lock_policy.h" />
<ClInclude Include="..\..\include\etl\timer_node.h" />
<ClInclude Include="..\..\include\etl\invoke.h" />
<ClInclude Include="..\..\include\etl\lcm.h" />
@ -3735,6 +3737,7 @@
<ClInclude Include="..\..\include\etl\task.h" />
<ClInclude Include="..\..\include\etl\threshold.h" />
<ClInclude Include="..\..\include\etl\timer.h" />
<ClInclude Include="..\..\include\etl\timer_notification.h" />
<ClInclude Include="..\..\include\etl\to_arithmetic.h" />
<ClInclude Include="..\..\include\etl\to_string.h" />
<ClInclude Include="..\..\include\etl\to_u16string.h" />
@ -11453,6 +11456,7 @@
<ClCompile Include="..\test_task_scheduler.cpp" />
<ClCompile Include="..\test_threshold.cpp" />
<ClCompile Include="..\test_chrono_time_point.cpp" />
<ClCompile Include="..\test_timer_config.cpp" />
<ClCompile Include="..\test_timer_lists.cpp" />
<ClCompile Include="..\test_timer_node.cpp" />
<ClCompile Include="..\test_to_arithmetic.cpp" />

View File

@ -1572,12 +1572,21 @@
<ClInclude Include="..\..\include\etl\timer_node.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\timer_lists.h">
<Filter>ETL\Private</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\intrusive_timer.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\timer_lists.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\timer_lock_policy.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\timer_notification.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\timer_config.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\test_string_char.cpp">
@ -3857,6 +3866,9 @@
<ClCompile Include="..\test_intrusive_timer.cpp">
<Filter>Tests\Callback Timers</Filter>
</ClCompile>
<ClCompile Include="..\test_timer_config.cpp">
<Filter>Tests\Callback Timers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">