mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Modified the timer config and node classes
This commit is contained in:
parent
fe1bc0b029
commit
cf07fc69b5
518
include/etl/private/timer_lists.h
Normal file
518
include/etl/private/timer_lists.h
Normal file
@ -0,0 +1,518 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
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_LISTS_INCLUDED
|
||||||
|
#define ETL_TIMER_LISTS_INCLUDED
|
||||||
|
|
||||||
|
#include "../platform.h"
|
||||||
|
#include "../nullptr.h"
|
||||||
|
#include "../timer.h"
|
||||||
|
#include "../timer_node.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Definitions common to intrusive timers.
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
namespace etl
|
||||||
|
{
|
||||||
|
namespace private_timer
|
||||||
|
{
|
||||||
|
//*************************************************************************
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
timer_register_list() ETL_NOEXCEPT
|
||||||
|
: head(end())
|
||||||
|
, tail(end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return head == end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Adds the timer in to the list.
|
||||||
|
//*******************************
|
||||||
|
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
head = new_timer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tail->registered_next = new_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail = new_timer;
|
||||||
|
new_timer->registered_next = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
if (timer == head)
|
||||||
|
{
|
||||||
|
head = timer->registered_next;
|
||||||
|
|
||||||
|
if (head == end())
|
||||||
|
{
|
||||||
|
tail = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->registered_next = ETL_NULLPTR;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
etl::timer_node* previous = head;
|
||||||
|
|
||||||
|
// Step through the list until we find the timer to remove, or reach the end of the list.
|
||||||
|
while ((previous->registered_next != end()) && (previous->registered_next != timer))
|
||||||
|
{
|
||||||
|
previous = previous->registered_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we found the timer, remove it from the list.
|
||||||
|
if (previous->registered_next == timer)
|
||||||
|
{
|
||||||
|
previous->registered_next = timer->registered_next;
|
||||||
|
|
||||||
|
if (timer == tail)
|
||||||
|
{
|
||||||
|
tail = previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->registered_next = end();
|
||||||
|
|
||||||
|
return previous->registered_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Timer not found in the list.
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the first timer in the list.
|
||||||
|
/// If the list is empty, returns end().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* first() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the next timer in the list after the given timer.
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
if (timer != end())
|
||||||
|
{
|
||||||
|
return timer->registered_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the end of the list.
|
||||||
|
/// Always returns &etl::timer_node::sentinal().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* const end() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return etl::timer_node::sentinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Clear the list of entries.
|
||||||
|
//*******************************
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
|
||||||
|
while (timer != end())
|
||||||
|
{
|
||||||
|
timer = pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
head = end();
|
||||||
|
tail = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Removes the timer at the front of the list.
|
||||||
|
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* pop_front() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
head = timer->registered_next;
|
||||||
|
timer->registered_next = timer->unlinked();
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
timer_active_list() ETL_NOEXCEPT
|
||||||
|
: head(end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
bool empty() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return head == end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Inserts the timer at the correct delta position
|
||||||
|
//*******************************
|
||||||
|
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
// No entries yet.
|
||||||
|
head = new_timer;
|
||||||
|
new_timer->active_next = end();
|
||||||
|
}
|
||||||
|
else if (new_timer->config.delta < head->config.delta)
|
||||||
|
{
|
||||||
|
// Goes before the head.
|
||||||
|
head->config.delta -= new_timer->config.delta;
|
||||||
|
new_timer->active_next = head;
|
||||||
|
head = new_timer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We already have entries, and new_timer doesn't go before head.
|
||||||
|
timer_node* previous_timer = head;
|
||||||
|
timer_node* timer = head->active_next;
|
||||||
|
|
||||||
|
// Adjust the new_timer delta to take account of the head timer's delta.
|
||||||
|
new_timer->config.delta -= previous_timer->config.delta;
|
||||||
|
|
||||||
|
bool inserted = false;
|
||||||
|
|
||||||
|
while (!inserted && (timer != end()))
|
||||||
|
{
|
||||||
|
// Find the correct place to insert.
|
||||||
|
// The list is sorted by delta, so we need to find the first timer with a delta greater than the new timer's delta.
|
||||||
|
if (new_timer->config.delta < timer->config.delta)
|
||||||
|
{
|
||||||
|
// Insert after the previous timer.
|
||||||
|
previous_timer->active_next = new_timer;
|
||||||
|
new_timer->active_next = timer;
|
||||||
|
|
||||||
|
// Adjust the next delta for the new timer's delta.
|
||||||
|
timer->config.delta -= new_timer->config.delta;
|
||||||
|
|
||||||
|
inserted = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Adjust the new_timer delta to take account of the last timer's delta.
|
||||||
|
new_timer->config.delta -= timer->config.delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the next timer in the list.
|
||||||
|
previous_timer = timer;
|
||||||
|
timer = timer->active_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inserted)
|
||||||
|
{
|
||||||
|
// Reached the end so attach to the tail.
|
||||||
|
previous_timer->active_next = new_timer;
|
||||||
|
new_timer->active_next = end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Removes the selected timer from the list.
|
||||||
|
/// No action is taken if the timer is not found.
|
||||||
|
/// returns the next timer in the list after the removed timer, or end() if the removed timer was the last in the list.
|
||||||
|
/// The list does not do any checking of parameters as it is assumed that the timer service has already done this.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* remove(etl::timer_node* timer) ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
// Find the timer in the list.
|
||||||
|
etl::timer_node* current = head;
|
||||||
|
etl::timer_node* last = end();
|
||||||
|
|
||||||
|
while (current != timer && current != end())
|
||||||
|
{
|
||||||
|
last = current;
|
||||||
|
current = current->active_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found?
|
||||||
|
if (current == end())
|
||||||
|
{
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
|
||||||
|
etl::timer_node* next = current->active_next;
|
||||||
|
|
||||||
|
// Adjust the next delta.
|
||||||
|
if (next != end())
|
||||||
|
{
|
||||||
|
next->config.delta += current->config.delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove it from the list.
|
||||||
|
if (last == end())
|
||||||
|
{
|
||||||
|
head = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last->active_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the next pointer of the removed timer.
|
||||||
|
current->active_next = ETL_NULLPTR;
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the first timer in the list.
|
||||||
|
/// If the list is empty, returns end().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* first() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the next timer in the list after the given timer.
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
if (timer != end())
|
||||||
|
{
|
||||||
|
return timer->active_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the end of the list.
|
||||||
|
/// Always returns &etl::timer_node::sentinal().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* const end() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return etl::timer_node::sentinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Clear the list of entries.
|
||||||
|
//*******************************
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
|
||||||
|
while (timer != end())
|
||||||
|
{
|
||||||
|
timer = pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
head = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Removes the timer at the front of the list.
|
||||||
|
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* pop_front() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
head = timer->active_next;
|
||||||
|
timer->active_next = timer->unlinked();
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
etl::timer_node* head;
|
||||||
|
};
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// The list of timers that are registered.
|
||||||
|
//*************************************************************************
|
||||||
|
class timer_triggered_list
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
timer_triggered_list() ETL_NOEXCEPT
|
||||||
|
: head(end())
|
||||||
|
, tail(end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return head == end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Adds the timer in to the list.
|
||||||
|
//*******************************
|
||||||
|
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
new_timer->triggered_next = end();
|
||||||
|
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
head = new_timer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tail->triggered_next = new_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail = new_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the first timer in the list.
|
||||||
|
/// If the list is empty, returns nullptr.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* first() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the next timer in the list after the given timer.
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
if (timer != end())
|
||||||
|
{
|
||||||
|
return timer->triggered_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the end of the list.
|
||||||
|
/// Always returns &etl::timer_node::sentinal().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* const end() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return etl::timer_node::sentinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Clear the list of entries.
|
||||||
|
//*******************************
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
|
||||||
|
while (timer != end())
|
||||||
|
{
|
||||||
|
timer = pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
head = end();
|
||||||
|
tail = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Removes the timer at the front of the list.
|
||||||
|
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* pop_front() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
head = timer->triggered_next;
|
||||||
|
timer->triggered_next = timer->unlinked();
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
etl::timer_node* head;
|
||||||
|
etl::timer_node* tail;
|
||||||
|
};
|
||||||
|
} // namespace private_timer
|
||||||
|
} // namespace etl
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,588 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
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_DATA_INCLUDED
|
|
||||||
#define ETL_TIMER_DATA_INCLUDED
|
|
||||||
|
|
||||||
#include "platform.h"
|
|
||||||
#include "nullptr.h"
|
|
||||||
#include "timer.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// Definitions common to intrusive timers.
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
namespace etl
|
|
||||||
{
|
|
||||||
//***************************************************************************
|
|
||||||
/// Common definitions for the intrusive timer framework.
|
|
||||||
//***************************************************************************
|
|
||||||
class timer_config
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
friend class timer_register_list;
|
|
||||||
friend class timer_active_list;
|
|
||||||
friend class timer_triggered_list;
|
|
||||||
friend class intrusive_callback_timer;
|
|
||||||
|
|
||||||
//*******************************************
|
|
||||||
timer_config() ETL_NOEXCEPT
|
|
||||||
: period(etl::timer::state::Inactive)
|
|
||||||
, delta(etl::timer::state::Inactive)
|
|
||||||
, mode(etl::timer::mode::Repeating)
|
|
||||||
, registered_next(ETL_NULLPTR)
|
|
||||||
, active_next(ETL_NULLPTR)
|
|
||||||
, triggered_next(ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************************
|
|
||||||
timer_config(uint32_t period_, etl::timer::mode::type repeating_) ETL_NOEXCEPT
|
|
||||||
: period(period_)
|
|
||||||
, delta(period_)
|
|
||||||
, mode(repeating_)
|
|
||||||
, registered_next(ETL_NULLPTR)
|
|
||||||
, active_next(ETL_NULLPTR)
|
|
||||||
, triggered_next(ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************************
|
|
||||||
uint32_t get_period() const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
return period;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************************
|
|
||||||
uint32_t get_delta() const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
return delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************************
|
|
||||||
uint32_t get_mode() const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************************
|
|
||||||
void clear() ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
period = etl::timer::state::Inactive;
|
|
||||||
delta = etl::timer::state::Inactive;
|
|
||||||
mode = etl::timer::mode::Repeating;
|
|
||||||
registered_next = ETL_NULLPTR;
|
|
||||||
active_next = ETL_NULLPTR;
|
|
||||||
triggered_next = ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
uint32_t period; ///< The period of the timer.
|
|
||||||
uint32_t delta; ///< The time remaining until the timer expires.
|
|
||||||
timer_config* registered_next; ///< The next timer in the registered timer list. nullptr if the timer is not registered.
|
|
||||||
timer_config* active_next; ///< The next timer in the active timer list. nullptr if the timer is not active.
|
|
||||||
timer_config* triggered_next; ///< The next timer in the triggered timer list. nullptr if the timer is not triggered.
|
|
||||||
etl::timer::mode::type mode; ///< Whether the timer is repeating or single-shot.
|
|
||||||
};
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
/// A timer data structure that includes a callback delegate.
|
|
||||||
//***************************************************************************
|
|
||||||
template <typename TCallback>
|
|
||||||
struct callback_timer_config : public timer_config
|
|
||||||
{
|
|
||||||
callback_timer_config(etl::timer::id::type id_, TCallback callback_) ETL_NOEXCEPT
|
|
||||||
: timer_config()
|
|
||||||
, callback(callback_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TCallback callback; ///< The callback delegate for the timer.
|
|
||||||
};
|
|
||||||
|
|
||||||
//*************************************************************************
|
|
||||||
/// The list of timers that are registered.
|
|
||||||
//*************************************************************************
|
|
||||||
class timer_register_list
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
timer_register_list() ETL_NOEXCEPT
|
|
||||||
: head(ETL_NULLPTR)
|
|
||||||
, tail(ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return head == ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
// Adds the timer in to the list.
|
|
||||||
//*******************************
|
|
||||||
void insert(etl::timer_config* new_timer) ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
if (empty())
|
|
||||||
{
|
|
||||||
head = new_timer;
|
|
||||||
}
|
|
||||||
else if (head == new_timer)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Remove any existing timer.
|
|
||||||
etl::timer_config* previous = head;
|
|
||||||
|
|
||||||
// Step through the list until we find the timer to remove, or reach the end of the list.
|
|
||||||
while ((previous->registered_next != ETL_NULLPTR) && (previous->registered_next != new_timer))
|
|
||||||
{
|
|
||||||
previous = previous->registered_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we found the timer, remove it from the list.
|
|
||||||
if (previous->registered_next == new_timer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
tail->registered_next = new_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
tail = new_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
// 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_config* remove(etl::timer_config* timer) ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
if (timer == head)
|
|
||||||
{
|
|
||||||
head = timer->registered_next;
|
|
||||||
|
|
||||||
if (head == ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
tail = ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
timer->registered_next = ETL_NULLPTR;
|
|
||||||
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
etl::timer_config* previous = head;
|
|
||||||
|
|
||||||
// Step through the list until we find the timer to remove, or reach the end of the list.
|
|
||||||
while ((previous->registered_next != ETL_NULLPTR) && (previous->registered_next != timer))
|
|
||||||
{
|
|
||||||
previous = previous->registered_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we found the timer, remove it from the list.
|
|
||||||
if (previous->registered_next == timer)
|
|
||||||
{
|
|
||||||
previous->registered_next = timer->registered_next;
|
|
||||||
|
|
||||||
if (timer == tail)
|
|
||||||
{
|
|
||||||
tail = previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
timer->registered_next = ETL_NULLPTR;
|
|
||||||
|
|
||||||
return previous->registered_next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Timer not found in the list.
|
|
||||||
return ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Returns the first timer in the list.
|
|
||||||
/// If the list is empty, returns nullptr.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* first() const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Returns the next timer in the list after the given timer.
|
|
||||||
/// May be nullptr if the given timer is the last in the list.
|
|
||||||
/// If the given timer is nullptr, returns nullptr.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* next(etl::timer_config* timer) const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
if (timer != ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
return timer->registered_next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Clear the list of entries.
|
|
||||||
//*******************************
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
etl::timer_config* timer = head;
|
|
||||||
|
|
||||||
while (timer != ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
timer = pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
head = ETL_NULLPTR;
|
|
||||||
tail = ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
// Removes the timer at the front of the list.
|
|
||||||
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* pop_front() ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
etl::timer_config* timer = head;
|
|
||||||
head = timer->registered_next;
|
|
||||||
timer->registered_next = ETL_NULLPTR;
|
|
||||||
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
etl::timer_config* head;
|
|
||||||
etl::timer_config* tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
//*************************************************************************
|
|
||||||
/// The list of timers that are active.
|
|
||||||
//*************************************************************************
|
|
||||||
class timer_active_list
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
timer_active_list() ETL_NOEXCEPT
|
|
||||||
: head(ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
bool empty() const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
return head == ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
// Inserts the timer at the correct delta position
|
|
||||||
//*******************************
|
|
||||||
void insert(etl::timer_config* new_timer) ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
if (empty())
|
|
||||||
{
|
|
||||||
// No entries yet.
|
|
||||||
head = new_timer;
|
|
||||||
new_timer->active_next = ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
else if (new_timer->delta < head->delta)
|
|
||||||
{
|
|
||||||
// Goes before the head.
|
|
||||||
head->delta -= new_timer->delta;
|
|
||||||
new_timer->active_next = head;
|
|
||||||
head = new_timer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We already have entries, and new_timer doesn't go before head.
|
|
||||||
timer_config* previous_timer = head;
|
|
||||||
timer_config* timer = head->active_next;
|
|
||||||
|
|
||||||
// Adjust the new_timer delta to take account of the head timer's delta.
|
|
||||||
new_timer->delta -= previous_timer->delta;
|
|
||||||
|
|
||||||
bool inserted = false;
|
|
||||||
|
|
||||||
while (!inserted && (timer != ETL_NULLPTR))
|
|
||||||
{
|
|
||||||
// Find the correct place to insert.
|
|
||||||
// The list is sorted by delta, so we need to find the first timer with a delta greater than the new timer's delta.
|
|
||||||
if (new_timer->delta < timer->delta)
|
|
||||||
{
|
|
||||||
// Insert after the previous timer.
|
|
||||||
previous_timer->active_next = new_timer;
|
|
||||||
new_timer->active_next = timer;
|
|
||||||
|
|
||||||
// Adjust the next delta for the new timer's delta.
|
|
||||||
timer->delta -= new_timer->delta;
|
|
||||||
|
|
||||||
inserted = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Adjust the new_timer delta to take account of the last timer's delta.
|
|
||||||
new_timer->delta -= timer->delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to the next timer in the list.
|
|
||||||
previous_timer = timer;
|
|
||||||
timer = timer->active_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inserted)
|
|
||||||
{
|
|
||||||
// Reached the end so attach to the tail.
|
|
||||||
previous_timer->active_next = new_timer;
|
|
||||||
new_timer->active_next = ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
// Removes the selected timer from the list.
|
|
||||||
// No action is taken if the timer is not found.
|
|
||||||
// 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_config* remove(etl::timer_config* timer) ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
// Find the timer in the list.
|
|
||||||
etl::timer_config* current = head;
|
|
||||||
etl::timer_config* last = ETL_NULLPTR;
|
|
||||||
|
|
||||||
while (current != timer && current != ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
last = current;
|
|
||||||
current = current->active_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not found?
|
|
||||||
if (current == ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
return ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
etl::timer_config* next = current->active_next;
|
|
||||||
|
|
||||||
// Adjust the next delta.
|
|
||||||
if (next != ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
next->delta += current->delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove it from the list.
|
|
||||||
if (last == ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
head = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
last->active_next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the next pointer of the removed timer.
|
|
||||||
current->active_next = ETL_NULLPTR;
|
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Returns the first timer in the list.
|
|
||||||
/// If the list is empty, returns nullptr.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* first() const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Returns the next timer in the list after the given timer.
|
|
||||||
/// If the given timer is nullptr, returns nullptr.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* next(etl::timer_config* timer) const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
if (timer != ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
return timer->active_next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Clear the list of entries.
|
|
||||||
//*******************************
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
etl::timer_config* timer = head;
|
|
||||||
|
|
||||||
while (timer != ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
timer = pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
head = ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
// Removes the timer at the front of the list.
|
|
||||||
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* pop_front() ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
etl::timer_config* timer = head;
|
|
||||||
head = timer->active_next;
|
|
||||||
timer->active_next = ETL_NULLPTR;
|
|
||||||
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
etl::timer_config* head;
|
|
||||||
};
|
|
||||||
|
|
||||||
//*************************************************************************
|
|
||||||
/// The list of timers that are registered.
|
|
||||||
//*************************************************************************
|
|
||||||
class timer_triggered_list
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
timer_triggered_list() ETL_NOEXCEPT
|
|
||||||
: head(ETL_NULLPTR)
|
|
||||||
, tail(ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return head == ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
// Adds the timer in to the list.
|
|
||||||
//*******************************
|
|
||||||
void insert(etl::timer_config* new_timer) ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
new_timer->triggered_next = ETL_NULLPTR;
|
|
||||||
|
|
||||||
if (empty())
|
|
||||||
{
|
|
||||||
head = new_timer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tail->triggered_next = new_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
tail = new_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Returns the first timer in the list.
|
|
||||||
/// If the list is empty, returns nullptr.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* first() const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Returns the next timer in the list after the given timer.
|
|
||||||
/// May be nullptr if the given timer is the last in the list.
|
|
||||||
/// If the given timer is nullptr, returns nullptr.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* next(etl::timer_config* timer) const ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
if (timer != ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
return timer->triggered_next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
/// Clear the list of entries.
|
|
||||||
//*******************************
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
etl::timer_config* timer = head;
|
|
||||||
|
|
||||||
while (timer != ETL_NULLPTR)
|
|
||||||
{
|
|
||||||
timer = pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
head = ETL_NULLPTR;
|
|
||||||
tail = ETL_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//*******************************
|
|
||||||
// Removes the timer at the front of the list.
|
|
||||||
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
|
||||||
//*******************************
|
|
||||||
etl::timer_config* pop_front() ETL_NOEXCEPT
|
|
||||||
{
|
|
||||||
etl::timer_config* timer = head;
|
|
||||||
head = timer->triggered_next;
|
|
||||||
timer->triggered_next = ETL_NULLPTR;
|
|
||||||
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
etl::timer_config* head;
|
|
||||||
etl::timer_config* tail;
|
|
||||||
};
|
|
||||||
} // namespace etl
|
|
||||||
|
|
||||||
#endif
|
|
||||||
515
include/etl/timer_lists.h
Normal file
515
include/etl/timer_lists.h
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
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_LISTS_INCLUDED
|
||||||
|
#define ETL_TIMER_LISTS_INCLUDED
|
||||||
|
|
||||||
|
#include "../platform.h"
|
||||||
|
#include "../nullptr.h"
|
||||||
|
#include "../timer_node.h"
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Definitions common to intrusive timers.
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
namespace etl
|
||||||
|
{
|
||||||
|
namespace private_timer
|
||||||
|
{
|
||||||
|
//*************************************************************************
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
timer_register_list() ETL_NOEXCEPT
|
||||||
|
: head(end())
|
||||||
|
, tail(end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return head == end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Adds the timer in to the list.
|
||||||
|
//*******************************
|
||||||
|
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
head = new_timer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tail->registered_next = new_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail = new_timer;
|
||||||
|
new_timer->registered_next = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
if (timer == head)
|
||||||
|
{
|
||||||
|
head = timer->registered_next;
|
||||||
|
|
||||||
|
if (head == end())
|
||||||
|
{
|
||||||
|
tail = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->registered_next = ETL_NULLPTR;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
etl::timer_node* previous = head;
|
||||||
|
|
||||||
|
// Step through the list until we find the timer to remove, or reach the end of the list.
|
||||||
|
while ((previous->registered_next != end()) && (previous->registered_next != timer))
|
||||||
|
{
|
||||||
|
previous = previous->registered_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we found the timer, remove it from the list.
|
||||||
|
if (previous->registered_next == timer)
|
||||||
|
{
|
||||||
|
previous->registered_next = timer->registered_next;
|
||||||
|
|
||||||
|
if (timer == tail)
|
||||||
|
{
|
||||||
|
tail = previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->registered_next = end();
|
||||||
|
|
||||||
|
return previous->registered_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Timer not found in the list.
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the first timer in the list.
|
||||||
|
/// If the list is empty, returns end().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* first() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the next timer in the list after the given timer.
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
if (timer != end())
|
||||||
|
{
|
||||||
|
return timer->registered_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the end of the list.
|
||||||
|
/// Always returns &etl::timer_node::sentinal().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* const end() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return etl::timer_node::sentinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Clear the list of entries.
|
||||||
|
//*******************************
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
|
||||||
|
while (timer != end())
|
||||||
|
{
|
||||||
|
timer = pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
head = end();
|
||||||
|
tail = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Removes the timer at the front of the list.
|
||||||
|
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* pop_front() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
head = timer->registered_next;
|
||||||
|
timer->registered_next = timer->unlinked();
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
timer_active_list() ETL_NOEXCEPT
|
||||||
|
: head(end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
bool empty() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return head == end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Inserts the timer at the correct delta position
|
||||||
|
//*******************************
|
||||||
|
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
// No entries yet.
|
||||||
|
head = new_timer;
|
||||||
|
new_timer->active_next = end();
|
||||||
|
}
|
||||||
|
else if (new_timer->config.delta < head->config.delta)
|
||||||
|
{
|
||||||
|
// Goes before the head.
|
||||||
|
head->config.delta -= new_timer->config.delta;
|
||||||
|
new_timer->active_next = head;
|
||||||
|
head = new_timer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We already have entries, and new_timer doesn't go before head.
|
||||||
|
timer_node* previous_timer = head;
|
||||||
|
timer_node* timer = head->active_next;
|
||||||
|
|
||||||
|
// Adjust the new_timer delta to take account of the head timer's delta.
|
||||||
|
new_timer->config.delta -= previous_timer->config.delta;
|
||||||
|
|
||||||
|
bool inserted = false;
|
||||||
|
|
||||||
|
while (!inserted && (timer != end()))
|
||||||
|
{
|
||||||
|
// Find the correct place to insert.
|
||||||
|
// The list is sorted by delta, so we need to find the first timer with a delta greater than the new timer's delta.
|
||||||
|
if (new_timer->config.delta < timer->config.delta)
|
||||||
|
{
|
||||||
|
// Insert after the previous timer.
|
||||||
|
previous_timer->active_next = new_timer;
|
||||||
|
new_timer->active_next = timer;
|
||||||
|
|
||||||
|
// Adjust the next delta for the new timer's delta.
|
||||||
|
timer->config.delta -= new_timer->config.delta;
|
||||||
|
|
||||||
|
inserted = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Adjust the new_timer delta to take account of the last timer's delta.
|
||||||
|
new_timer->config.delta -= timer->config.delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the next timer in the list.
|
||||||
|
previous_timer = timer;
|
||||||
|
timer = timer->active_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inserted)
|
||||||
|
{
|
||||||
|
// Reached the end so attach to the tail.
|
||||||
|
previous_timer->active_next = new_timer;
|
||||||
|
new_timer->active_next = end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Removes the selected timer from the list.
|
||||||
|
/// No action is taken if the timer is not found.
|
||||||
|
/// returns the next timer in the list after the removed timer, or end() if the removed timer was the last in the list.
|
||||||
|
/// The list does not do any checking of parameters as it is assumed that the timer service has already done this.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* remove(etl::timer_node* timer) ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
// Find the timer in the list.
|
||||||
|
etl::timer_node* current = head;
|
||||||
|
etl::timer_node* last = end();
|
||||||
|
|
||||||
|
while (current != timer && current != end())
|
||||||
|
{
|
||||||
|
last = current;
|
||||||
|
current = current->active_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found?
|
||||||
|
if (current == end())
|
||||||
|
{
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
|
||||||
|
etl::timer_node* next = current->active_next;
|
||||||
|
|
||||||
|
// Adjust the next delta.
|
||||||
|
if (next != end())
|
||||||
|
{
|
||||||
|
next->config.delta += current->config.delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove it from the list.
|
||||||
|
if (last == end())
|
||||||
|
{
|
||||||
|
head = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last->active_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the next pointer of the removed timer.
|
||||||
|
current->active_next = ETL_NULLPTR;
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the first timer in the list.
|
||||||
|
/// If the list is empty, returns end().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* first() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the next timer in the list after the given timer.
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
if (timer != end())
|
||||||
|
{
|
||||||
|
return timer->active_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the end of the list.
|
||||||
|
/// Always returns &etl::timer_node::sentinal().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* const end() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return etl::timer_node::sentinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Clear the list of entries.
|
||||||
|
//*******************************
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
|
||||||
|
while (timer != end())
|
||||||
|
{
|
||||||
|
timer = pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
head = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Removes the timer at the front of the list.
|
||||||
|
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* pop_front() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
head = timer->active_next;
|
||||||
|
timer->active_next = timer->unlinked();
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
etl::timer_node* head;
|
||||||
|
};
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// The list of timers that are registered.
|
||||||
|
//*************************************************************************
|
||||||
|
class timer_triggered_list
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
timer_triggered_list() ETL_NOEXCEPT
|
||||||
|
: head(end())
|
||||||
|
, tail(end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return head == end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Adds the timer in to the list.
|
||||||
|
//*******************************
|
||||||
|
void insert(etl::timer_node* new_timer) ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
new_timer->triggered_next = end();
|
||||||
|
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
head = new_timer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tail->triggered_next = new_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail = new_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the first timer in the list.
|
||||||
|
/// If the list is empty, returns nullptr.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* first() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the next timer in the list after the given timer.
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
if (timer != end())
|
||||||
|
{
|
||||||
|
return timer->triggered_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Returns the end of the list.
|
||||||
|
/// Always returns &etl::timer_node::sentinal().
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* const end() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return etl::timer_node::sentinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
/// Clear the list of entries.
|
||||||
|
//*******************************
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
|
||||||
|
while (timer != end())
|
||||||
|
{
|
||||||
|
timer = pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
head = end();
|
||||||
|
tail = end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//*******************************
|
||||||
|
// Removes the timer at the front of the list.
|
||||||
|
// Returns the new head of the list, which may be nullptr if the list is now empty.
|
||||||
|
//*******************************
|
||||||
|
etl::timer_node* pop_front() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
etl::timer_node* timer = head;
|
||||||
|
head = timer->triggered_next;
|
||||||
|
timer->triggered_next = timer->unlinked();
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
etl::timer_node* head;
|
||||||
|
etl::timer_node* tail;
|
||||||
|
};
|
||||||
|
} // namespace private_timer
|
||||||
|
} // namespace etl
|
||||||
|
|
||||||
|
#endif
|
||||||
221
include/etl/timer_node.h
Normal file
221
include/etl/timer_node.h
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2026 John Wellbelove
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ETL_TIMER_NODE_INCLUDED
|
||||||
|
#define ETL_TIMER_NODE_INCLUDED
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "nullptr.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Definitions common to intrusive timers.
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
namespace etl
|
||||||
|
{
|
||||||
|
namespace private_timer
|
||||||
|
{
|
||||||
|
class timer_register_list;
|
||||||
|
class timer_active_list;
|
||||||
|
class timer_triggered_list;
|
||||||
|
|
||||||
|
class intrusive_callback_timer;
|
||||||
|
} // namespace private_timer
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// A timer configuration data structure.
|
||||||
|
//***************************************************************************
|
||||||
|
class timer_config
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
friend class private_timer::timer_register_list;
|
||||||
|
friend class private_timer::timer_active_list;
|
||||||
|
friend class private_timer::timer_triggered_list;
|
||||||
|
|
||||||
|
friend class intrusive_callback_timer;
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Constructor.
|
||||||
|
//*******************************************
|
||||||
|
ETL_CONSTEXPR timer_config(uint32_t period_, etl::timer::mode::type repeating_) ETL_NOEXCEPT
|
||||||
|
: period(period_)
|
||||||
|
, delta(period_)
|
||||||
|
, mode(repeating_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Returns the period of the timer.
|
||||||
|
//*******************************************
|
||||||
|
ETL_CONSTEXPR uint32_t get_period() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return period;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Returns the time remaining until the timer expires.
|
||||||
|
//*******************************************
|
||||||
|
ETL_CONSTEXPR uint32_t get_delta() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Returns the mode of the timer.
|
||||||
|
//*******************************************
|
||||||
|
ETL_CONSTEXPR uint32_t get_mode() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Clears the timer configuration.
|
||||||
|
//*******************************************
|
||||||
|
ETL_CONSTEXPR14 void clear() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
period = etl::timer::state::Inactive;
|
||||||
|
delta = etl::timer::state::Inactive;
|
||||||
|
mode = etl::timer::mode::Repeating;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint32_t period; ///< The period of the timer.
|
||||||
|
uint32_t delta; ///< The time remaining until the timer expires.
|
||||||
|
etl::timer::mode::type mode; ///< Whether the timer is repeating or single-shot.
|
||||||
|
};
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// A timer data structure that can be linked into the timer lists.
|
||||||
|
/// Contains a timer configuration.
|
||||||
|
//***************************************************************************
|
||||||
|
class timer_node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
friend class private_timer::timer_register_list;
|
||||||
|
friend class private_timer::timer_active_list;
|
||||||
|
friend class private_timer::timer_triggered_list;
|
||||||
|
|
||||||
|
friend class intrusive_callback_timer;
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Constructor.
|
||||||
|
//*******************************************
|
||||||
|
timer_node(const timer_config& config_) ETL_NOEXCEPT
|
||||||
|
: registered_next(unlinked())
|
||||||
|
, active_next(unlinked())
|
||||||
|
, triggered_next(unlinked())
|
||||||
|
, config(config_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Copy constructor.
|
||||||
|
//*******************************************
|
||||||
|
timer_node(const timer_node& node_) ETL_NOEXCEPT
|
||||||
|
: registered_next(unlinked())
|
||||||
|
, active_next(unlinked())
|
||||||
|
, triggered_next(unlinked())
|
||||||
|
, config(node_.config)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Returns the configuration of the timer.
|
||||||
|
//*******************************************
|
||||||
|
const timer_config& get_config() const ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Returns a nullptr to indicate that the timer is not linked into any list.
|
||||||
|
//*******************************************
|
||||||
|
static etl::timer_node* unlinked() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return ETL_NULLPTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
/// Returns a reference to the sentinel timer node used to mark the end of
|
||||||
|
/// the intrusive timer lists.
|
||||||
|
/// Implemented as a function-local static so that there is only ever one
|
||||||
|
/// instance, regardless of how many translation units include this header.
|
||||||
|
/// This avoids needing C++17 inline variables, so it remains compatible
|
||||||
|
/// with C++03 and C++11.
|
||||||
|
//***************************************************************************
|
||||||
|
static etl::timer_node* sentinal() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
static etl::timer_node timer_sentinel(etl::timer_config(0, 0));
|
||||||
|
|
||||||
|
return &timer_sentinel;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
/// Clear the next pointers.
|
||||||
|
//*******************************************
|
||||||
|
void clear() ETL_NOEXCEPT
|
||||||
|
{
|
||||||
|
registered_next = unlinked();
|
||||||
|
active_next = unlinked();
|
||||||
|
triggered_next = unlinked();
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_node& operator=(const timer_node&) ETL_DELETE;
|
||||||
|
|
||||||
|
timer_node* registered_next; ///< The next timer in the registered timer list. nullptr if the timer is not registered.
|
||||||
|
timer_node* active_next; ///< The next timer in the active timer list. nullptr if the timer is not active.
|
||||||
|
timer_node* triggered_next; ///< The next timer in the triggered timer list. nullptr if the timer is not triggered.
|
||||||
|
|
||||||
|
timer_config config; ///< The configuration of the timer.
|
||||||
|
};
|
||||||
|
|
||||||
|
////***************************************************************************
|
||||||
|
///// A timer data structure that includes a callback delegate.
|
||||||
|
////***************************************************************************
|
||||||
|
// template <typename TCallback>
|
||||||
|
// struct callback_timer_config : public timer_node
|
||||||
|
//{
|
||||||
|
// callback_timer_config(TCallback callback_) ETL_NOEXCEPT
|
||||||
|
// : timer_config()
|
||||||
|
// , callback(callback_)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// TCallback callback; ///< The callback delegate for the timer.
|
||||||
|
//};
|
||||||
|
} // namespace etl
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -28,25 +28,32 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include "unit_test_framework.h"
|
#include "unit_test_framework.h"
|
||||||
|
|
||||||
#include "etl/timer_config.h"
|
#include "etl/timer_node.h"
|
||||||
|
#include "etl/private/timer_lists.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
SUITE(test_timer_config)
|
SUITE(test_timer_lists)
|
||||||
{
|
{
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST(test_register_list)
|
TEST(test_timer_register_list)
|
||||||
{
|
{
|
||||||
etl::timer_config timer1;
|
constexpr etl::timer_config timer1_config(100, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer2;
|
constexpr etl::timer_config timer2_config(65, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer3;
|
constexpr etl::timer_config timer3_config(85, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer4;
|
constexpr etl::timer_config timer4_config(130, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer5;
|
constexpr etl::timer_config timer5_config(85, etl::timer::mode::Repeating);
|
||||||
|
|
||||||
etl::timer_register_list register_list;
|
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;
|
||||||
|
|
||||||
CHECK_TRUE(register_list.empty());
|
CHECK_TRUE(register_list.empty());
|
||||||
CHECK_TRUE(register_list.first() == ETL_NULLPTR);
|
CHECK_TRUE(register_list.first() == register_list.end());
|
||||||
|
|
||||||
// Add the timers to the list.
|
// Add the timers to the list.
|
||||||
register_list.insert(&timer1);
|
register_list.insert(&timer1);
|
||||||
@ -58,7 +65,7 @@ namespace
|
|||||||
CHECK_FALSE(register_list.empty());
|
CHECK_FALSE(register_list.empty());
|
||||||
CHECK_TRUE(register_list.first() == &timer1);
|
CHECK_TRUE(register_list.first() == &timer1);
|
||||||
|
|
||||||
etl::timer_config* timer = register_list.first();
|
etl::timer_node* timer = register_list.first();
|
||||||
|
|
||||||
// The timers should be in the order they were added.
|
// The timers should be in the order they were added.
|
||||||
CHECK_EQUAL(&timer1, timer);
|
CHECK_EQUAL(&timer1, timer);
|
||||||
@ -71,7 +78,7 @@ namespace
|
|||||||
timer = register_list.next(timer);
|
timer = register_list.next(timer);
|
||||||
CHECK_EQUAL(&timer5, timer);
|
CHECK_EQUAL(&timer5, timer);
|
||||||
timer = register_list.next(timer);
|
timer = register_list.next(timer);
|
||||||
CHECK_EQUAL(ETL_NULLPTR, timer);
|
CHECK_EQUAL(register_list.end(), timer);
|
||||||
|
|
||||||
// Remove timer3 from the list.
|
// Remove timer3 from the list.
|
||||||
register_list.remove(&timer3);
|
register_list.remove(&timer3);
|
||||||
@ -85,7 +92,7 @@ namespace
|
|||||||
|
|
||||||
timer = register_list.first();
|
timer = register_list.first();
|
||||||
|
|
||||||
while (timer != ETL_NULLPTR)
|
while (timer != register_list.end())
|
||||||
{
|
{
|
||||||
if (timer == &timer1)
|
if (timer == &timer1)
|
||||||
{
|
{
|
||||||
@ -121,23 +128,30 @@ namespace
|
|||||||
register_list.clear();
|
register_list.clear();
|
||||||
|
|
||||||
CHECK_TRUE(register_list.empty());
|
CHECK_TRUE(register_list.empty());
|
||||||
CHECK_TRUE(register_list.first() == ETL_NULLPTR);
|
CHECK_TRUE(register_list.first() == register_list.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST(test_active_list)
|
TEST(test_timer_active_list)
|
||||||
{
|
{
|
||||||
etl::timer_config timer1(100, etl::timer::mode::Repeating);
|
constexpr etl::timer_config timer1_config(100, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer2(65, etl::timer::mode::Repeating);
|
constexpr etl::timer_config timer2_config(65, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer3(85, etl::timer::mode::Repeating);
|
constexpr etl::timer_config timer3_config(85, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer4(130, etl::timer::mode::Repeating);
|
constexpr etl::timer_config timer4_config(130, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer5(85, etl::timer::mode::Repeating);
|
constexpr etl::timer_config timer5_config(85, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer6(85, etl::timer::mode::Repeating);
|
constexpr etl::timer_config timer6_config(85, etl::timer::mode::Repeating);
|
||||||
|
|
||||||
etl::timer_active_list active_list;
|
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;
|
||||||
|
|
||||||
CHECK_TRUE(active_list.empty());
|
CHECK_TRUE(active_list.empty());
|
||||||
CHECK_TRUE(active_list.first() == ETL_NULLPTR);
|
CHECK_TRUE(active_list.first() == active_list.end());
|
||||||
|
|
||||||
active_list.insert(&timer1);
|
active_list.insert(&timer1);
|
||||||
active_list.insert(&timer2);
|
active_list.insert(&timer2);
|
||||||
@ -148,7 +162,7 @@ namespace
|
|||||||
CHECK_FALSE(active_list.empty());
|
CHECK_FALSE(active_list.empty());
|
||||||
CHECK_TRUE(active_list.first() == &timer2);
|
CHECK_TRUE(active_list.first() == &timer2);
|
||||||
|
|
||||||
etl::timer_config* timer = active_list.first();
|
etl::timer_node* timer = active_list.first();
|
||||||
|
|
||||||
// The timers should be in the order of their deltas.
|
// The timers should be in the order of their deltas.
|
||||||
CHECK_EQUAL(&timer2, timer);
|
CHECK_EQUAL(&timer2, timer);
|
||||||
@ -161,14 +175,13 @@ namespace
|
|||||||
timer = active_list.next(timer);
|
timer = active_list.next(timer);
|
||||||
CHECK_EQUAL(&timer4, timer);
|
CHECK_EQUAL(&timer4, timer);
|
||||||
timer = active_list.next(timer);
|
timer = active_list.next(timer);
|
||||||
CHECK_EQUAL(ETL_NULLPTR, timer);
|
CHECK_EQUAL(active_list.end(), timer);
|
||||||
|
|
||||||
CHECK_EQUAL(timer2.get_period(), timer2.get_delta());
|
|
||||||
CHECK_EQUAL(timer3.get_period() - timer2.get_period(), timer3.get_delta());
|
|
||||||
CHECK_EQUAL(timer1.get_period() - timer3.get_period(), timer1.get_delta());
|
|
||||||
CHECK_EQUAL(timer4.get_period() - timer1.get_period(), timer4.get_delta());
|
|
||||||
CHECK_EQUAL(timer5.get_period() - timer3.get_period(), timer5.get_delta());
|
|
||||||
|
|
||||||
|
CHECK_EQUAL(timer2.get_config().get_period(), timer2.get_config().get_delta());
|
||||||
|
CHECK_EQUAL(timer3.get_config().get_period() - timer2.get_config().get_period(), timer3.get_config().get_delta());
|
||||||
|
CHECK_EQUAL(timer1.get_config().get_period() - timer3.get_config().get_period(), timer1.get_config().get_delta());
|
||||||
|
CHECK_EQUAL(timer4.get_config().get_period() - timer1.get_config().get_period(), timer4.get_config().get_delta());
|
||||||
|
CHECK_EQUAL(timer5.get_config().get_period() - timer3.get_config().get_period(), timer5.get_config().get_delta());
|
||||||
// Remove timer3 from the list.
|
// Remove timer3 from the list.
|
||||||
active_list.remove(&timer3);
|
active_list.remove(&timer3);
|
||||||
|
|
||||||
@ -181,7 +194,7 @@ namespace
|
|||||||
|
|
||||||
timer = active_list.first();
|
timer = active_list.first();
|
||||||
|
|
||||||
while (timer != ETL_NULLPTR)
|
while (timer != active_list.end())
|
||||||
{
|
{
|
||||||
if (timer == &timer1)
|
if (timer == &timer1)
|
||||||
{
|
{
|
||||||
@ -214,10 +227,10 @@ namespace
|
|||||||
CHECK_TRUE(timer5_found);
|
CHECK_TRUE(timer5_found);
|
||||||
|
|
||||||
// Check the deltas are still correct.
|
// Check the deltas are still correct.
|
||||||
CHECK_EQUAL(timer2.get_period(), timer2.get_delta());
|
CHECK_EQUAL(timer2.get_config().get_period(), timer2.get_config().get_delta());
|
||||||
CHECK_EQUAL(timer1.get_period() - timer3.get_period(), timer1.get_delta());
|
CHECK_EQUAL(timer1.get_config().get_period() - timer3.get_config().get_period(), timer1.get_config().get_delta());
|
||||||
CHECK_EQUAL(timer4.get_period() - timer1.get_period(), timer4.get_delta());
|
CHECK_EQUAL(timer4.get_config().get_period() - timer1.get_config().get_period(), timer4.get_config().get_delta());
|
||||||
CHECK_EQUAL(timer5.get_period() - timer2.get_period(), timer5.get_delta());
|
CHECK_EQUAL(timer5.get_config().get_period() - timer2.get_config().get_period(), timer5.get_config().get_delta());
|
||||||
|
|
||||||
// Remove a timer that is not in the list.
|
// Remove a timer that is not in the list.
|
||||||
active_list.remove(&timer6);
|
active_list.remove(&timer6);
|
||||||
@ -231,7 +244,7 @@ namespace
|
|||||||
|
|
||||||
timer = active_list.first();
|
timer = active_list.first();
|
||||||
|
|
||||||
while (timer != ETL_NULLPTR)
|
while (timer != active_list.end())
|
||||||
{
|
{
|
||||||
if (timer == &timer1)
|
if (timer == &timer1)
|
||||||
{
|
{
|
||||||
@ -258,31 +271,37 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the deltas are still correct.
|
// Check the deltas are still correct.
|
||||||
CHECK_EQUAL(timer2.get_period(), timer2.get_delta());
|
CHECK_EQUAL(timer2.get_config().get_period(), timer2.get_config().get_delta());
|
||||||
CHECK_EQUAL(timer1.get_period() - timer3.get_period(), timer1.get_delta());
|
CHECK_EQUAL(timer1.get_config().get_period() - timer3.get_config().get_period(), timer1.get_config().get_delta());
|
||||||
CHECK_EQUAL(timer4.get_period() - timer1.get_period(), timer4.get_delta());
|
CHECK_EQUAL(timer4.get_config().get_period() - timer1.get_config().get_period(), timer4.get_config().get_delta());
|
||||||
CHECK_EQUAL(timer5.get_period() - timer2.get_period(), timer5.get_delta());
|
CHECK_EQUAL(timer5.get_config().get_period() - timer2.get_config().get_period(), timer5.get_config().get_delta());
|
||||||
|
|
||||||
// Clear the list.
|
// Clear the list.
|
||||||
active_list.clear();
|
active_list.clear();
|
||||||
|
|
||||||
CHECK_TRUE(active_list.empty());
|
CHECK_TRUE(active_list.empty());
|
||||||
CHECK_TRUE(active_list.first() == ETL_NULLPTR);
|
CHECK_TRUE(active_list.first() == active_list.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST(test_triggered_list)
|
TEST(test_timer_triggered_list)
|
||||||
{
|
{
|
||||||
etl::timer_config timer1;
|
constexpr etl::timer_config timer1_config(100, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer2;
|
constexpr etl::timer_config timer2_config(65, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer3;
|
constexpr etl::timer_config timer3_config(85, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer4;
|
constexpr etl::timer_config timer4_config(130, etl::timer::mode::Repeating);
|
||||||
etl::timer_config timer5;
|
constexpr etl::timer_config timer5_config(85, etl::timer::mode::Repeating);
|
||||||
|
|
||||||
etl::timer_triggered_list triggered_list;
|
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_triggered_list triggered_list;
|
||||||
|
|
||||||
CHECK_TRUE(triggered_list.empty());
|
CHECK_TRUE(triggered_list.empty());
|
||||||
CHECK_TRUE(triggered_list.first() == ETL_NULLPTR);
|
CHECK_TRUE(triggered_list.first() == triggered_list.end());
|
||||||
|
|
||||||
// Add the timers to the list.
|
// Add the timers to the list.
|
||||||
triggered_list.insert(&timer1);
|
triggered_list.insert(&timer1);
|
||||||
@ -295,7 +314,7 @@ namespace
|
|||||||
CHECK_TRUE(triggered_list.first() == &timer1);
|
CHECK_TRUE(triggered_list.first() == &timer1);
|
||||||
|
|
||||||
// The timers should be in the order they were added.
|
// The timers should be in the order they were added.
|
||||||
etl::timer_config* timer = triggered_list.first();
|
etl::timer_node* timer = triggered_list.first();
|
||||||
|
|
||||||
CHECK_EQUAL(&timer1, timer);
|
CHECK_EQUAL(&timer1, timer);
|
||||||
timer = triggered_list.next(timer);
|
timer = triggered_list.next(timer);
|
||||||
@ -307,13 +326,13 @@ namespace
|
|||||||
timer = triggered_list.next(timer);
|
timer = triggered_list.next(timer);
|
||||||
CHECK_EQUAL(&timer5, timer);
|
CHECK_EQUAL(&timer5, timer);
|
||||||
timer = triggered_list.next(timer);
|
timer = triggered_list.next(timer);
|
||||||
CHECK_EQUAL(ETL_NULLPTR, timer);
|
CHECK_EQUAL(triggered_list.end(), timer);
|
||||||
|
|
||||||
// Clear the list.
|
// Clear the list.
|
||||||
triggered_list.clear();
|
triggered_list.clear();
|
||||||
|
|
||||||
CHECK_TRUE(triggered_list.empty());
|
CHECK_TRUE(triggered_list.empty());
|
||||||
CHECK_TRUE(triggered_list.first() == ETL_NULLPTR);
|
CHECK_TRUE(triggered_list.first() == triggered_list.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
85
test/test_timer_node.cpp
Normal file
85
test/test_timer_node.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
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_period());
|
||||||
|
CHECK_EQUAL(100U, config1.get_delta());
|
||||||
|
CHECK_EQUAL(etl::timer::mode::Repeating, config1.get_mode());
|
||||||
|
|
||||||
|
etl::timer_config config2(200U, etl::timer::mode::Single_Shot);
|
||||||
|
CHECK_EQUAL(200U, config2.get_period());
|
||||||
|
CHECK_EQUAL(200U, config2.get_delta());
|
||||||
|
CHECK_EQUAL(etl::timer::mode::Single_Shot, config2.get_mode());
|
||||||
|
|
||||||
|
etl::timer_config config3(config2);
|
||||||
|
CHECK_EQUAL(config2.get_period(), config3.get_period());
|
||||||
|
CHECK_EQUAL(config2.get_delta(), config3.get_delta());
|
||||||
|
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_period());
|
||||||
|
CHECK_EQUAL(500U, config4.get_delta());
|
||||||
|
CHECK_EQUAL(etl::timer::mode::Repeating, config4.get_mode());
|
||||||
|
|
||||||
|
config2.clear();
|
||||||
|
CHECK_EQUAL(etl::timer::state::Inactive, config2.get_period());
|
||||||
|
CHECK_EQUAL(etl::timer::state::Inactive, config2.get_delta());
|
||||||
|
CHECK_EQUAL(etl::timer::mode::Repeating, 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_period(), node1.get_config().get_period());
|
||||||
|
CHECK_EQUAL(config1.get_delta(), node1.get_config().get_delta());
|
||||||
|
CHECK_EQUAL(config1.get_mode(), node1.get_config().get_mode());
|
||||||
|
|
||||||
|
CHECK_EQUAL(node1.get_config().get_period(), node2.get_config().get_period());
|
||||||
|
CHECK_EQUAL(node1.get_config().get_delta(), node2.get_config().get_delta());
|
||||||
|
CHECK_EQUAL(node1.get_config().get_mode(), node2.get_config().get_mode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
@ -3559,7 +3559,8 @@
|
|||||||
<ClInclude Include="..\..\include\etl\generators\variant_pool_cpp03_generator.h" />
|
<ClInclude Include="..\..\include\etl\generators\variant_pool_cpp03_generator.h" />
|
||||||
<ClInclude Include="..\..\include\etl\index_of_type.h" />
|
<ClInclude Include="..\..\include\etl\index_of_type.h" />
|
||||||
<ClInclude Include="..\..\include\etl\inplace_function.h" />
|
<ClInclude Include="..\..\include\etl\inplace_function.h" />
|
||||||
<ClInclude Include="..\..\include\etl\timer_config.h" />
|
<ClInclude Include="..\..\include\etl\private\timer_lists.h" />
|
||||||
|
<ClInclude Include="..\..\include\etl\timer_node.h" />
|
||||||
<ClInclude Include="..\..\include\etl\invoke.h" />
|
<ClInclude Include="..\..\include\etl\invoke.h" />
|
||||||
<ClInclude Include="..\..\include\etl\lcm.h" />
|
<ClInclude Include="..\..\include\etl\lcm.h" />
|
||||||
<ClInclude Include="..\..\include\etl\math.h" />
|
<ClInclude Include="..\..\include\etl\math.h" />
|
||||||
@ -11450,7 +11451,8 @@
|
|||||||
<ClCompile Include="..\test_task_scheduler.cpp" />
|
<ClCompile Include="..\test_task_scheduler.cpp" />
|
||||||
<ClCompile Include="..\test_threshold.cpp" />
|
<ClCompile Include="..\test_threshold.cpp" />
|
||||||
<ClCompile Include="..\test_chrono_time_point.cpp" />
|
<ClCompile Include="..\test_chrono_time_point.cpp" />
|
||||||
<ClCompile Include="..\test_timer_data.cpp" />
|
<ClCompile Include="..\test_timer_lists.cpp" />
|
||||||
|
<ClCompile Include="..\test_timer_node.cpp" />
|
||||||
<ClCompile Include="..\test_to_arithmetic.cpp" />
|
<ClCompile Include="..\test_to_arithmetic.cpp" />
|
||||||
<ClCompile Include="..\test_to_arithmetic_u16.cpp" />
|
<ClCompile Include="..\test_to_arithmetic_u16.cpp" />
|
||||||
<ClCompile Include="..\test_to_arithmetic_u32.cpp" />
|
<ClCompile Include="..\test_to_arithmetic_u32.cpp" />
|
||||||
|
|||||||
@ -1569,9 +1569,12 @@
|
|||||||
<ClInclude Include="..\..\include\etl\format.h">
|
<ClInclude Include="..\..\include\etl\format.h">
|
||||||
<Filter>UnitTest++\Header Files</Filter>
|
<Filter>UnitTest++\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\include\etl\timer_config.h">
|
<ClInclude Include="..\..\include\etl\timer_node.h">
|
||||||
<Filter>ETL\Frameworks</Filter>
|
<Filter>ETL\Frameworks</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\include\etl\private\timer_lists.h">
|
||||||
|
<Filter>ETL\Private</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\test_string_char.cpp">
|
<ClCompile Include="..\test_string_char.cpp">
|
||||||
@ -3842,8 +3845,11 @@
|
|||||||
<ClCompile Include="..\test_vector_member_function_pointer_external_buffer.cpp">
|
<ClCompile Include="..\test_vector_member_function_pointer_external_buffer.cpp">
|
||||||
<Filter>Tests\Containers</Filter>
|
<Filter>Tests\Containers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\test_timer_data.cpp">
|
<ClCompile Include="..\test_timer_node.cpp">
|
||||||
<Filter>Tests\Timer support</Filter>
|
<Filter>Tests\Callback Timers</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\test_timer_lists.cpp">
|
||||||
|
<Filter>Tests\Callback Timers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user