Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Longer delays for Ticker and some internal updates #8625

Merged
merged 14 commits into from
Nov 1, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ void updateSensor(sensorType &sensor) {
SSEBroadcastState(sensor.name, sensor.value, newVal); // only broadcast if state is different
}
sensor.value = newVal;
sensor.update.once(rand() % 20 + 10, std::bind(updateSensor, sensor)); // randomly update sensor
sensor.update.once(rand() % 20 + 10, [&]() {
updateSensor(sensor);
}); // randomly update sensor
}

void handleSubscribe() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ public:
ExampleClass(int pin, int duration)
: _pin(pin), _duration(duration) {
pinMode(_pin, OUTPUT);
_myTicker.attach_ms(_duration, std::bind(&ExampleClass::classBlink, this));
_myTicker.attach_ms(_duration,
[this]() {
classBlink();
});
}
~ExampleClass(){};

int _pin, _duration;
Ticker _myTicker;
Expand Down Expand Up @@ -53,7 +55,7 @@ void setup() {
scheduledTicker.attach_ms_scheduled(100, scheduledBlink);

pinMode(LED4, OUTPUT);
parameterTicker.attach_ms(100, std::bind(parameterBlink, LED4));
parameterTicker.attach_ms(100, parameterBlink, LED4);

pinMode(LED5, OUTPUT);
lambdaTicker.attach_ms(100, []() {
Expand Down
106 changes: 85 additions & 21 deletions libraries/Ticker/src/Ticker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,49 +23,113 @@
#include "eagle_soc.h"
#include "osapi.h"

#include <Arduino.h>
#include "Ticker.h"

Ticker::Ticker()
: _timer(nullptr) {}
// ETSTimer is part of the instance, and we don't have any state besides
// the things required for the callback. Allow copies and moves, but
// disable any member copies and default-init + detach() instead.

Ticker::~Ticker()
{
detach();
}

void Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, void* arg)
Ticker::Ticker(const Ticker&)
{
if (_timer)
{
}

Ticker& Ticker::operator=(const Ticker&)
{
detach();
return *this;
}

Ticker::Ticker(Ticker&& other) noexcept
{
other.detach();
}

Ticker& Ticker::operator=(Ticker&& other) noexcept
{
other.detach();
detach();
return *this;
}

void Ticker::_attach(Ticker::Milliseconds milliseconds, bool repeat)
{
if (_timer) {
os_timer_disarm(_timer);
} else {
_timer = &_timer_internal;
}
else
{
_timer = &_etsTimer;

os_timer_setfn(_timer,
[](void* ptr) {
reinterpret_cast<Ticker*>(ptr)->_static_callback();
}, this);

_repeat = repeat;

// whenever duration excedes this limit, make timer repeatable N times
// in case it is really repeatable, it will reset itself and continue as usual
size_t total = 0;
if (milliseconds > DurationMax) {
total = 1;
while (milliseconds > DurationMax) {
total *= 2;
milliseconds /= 2;
}
_tick.reset(new callback_tick_t{
.total = total,
.count = 0,
});
repeat = true;
}

os_timer_setfn(_timer, callback, arg);
os_timer_arm(_timer, milliseconds, repeat);
os_timer_arm(_timer, milliseconds.count(), repeat);
}

void Ticker::detach()
{
if (!_timer)
return;

os_timer_disarm(_timer);
_timer = nullptr;
_callback_function = nullptr;
if (_timer) {
os_timer_disarm(_timer);
_timer = nullptr;
_tick.reset(nullptr);
_callback = std::monostate{};
}
}

bool Ticker::active() const
{
return _timer;
return _timer != nullptr;
}

void Ticker::_static_callback(void* arg)
void Ticker::_static_callback()
{
Ticker* _this = reinterpret_cast<Ticker*>(arg);
if (_this && _this->_callback_function)
_this->_callback_function();
if (_tick) {
++_tick->count;
if (_tick->count < _tick->total) {
return;
}
}

std::visit([](auto&& callback) {
using T = std::decay_t<decltype(callback)>;
if constexpr (std::is_same_v<T, callback_ptr_t>) {
callback.func(callback.arg);
} else if constexpr (std::is_same_v<T, callback_function_t>) {
callback();
}
}, _callback);

if (_repeat) {
if (_tick) {
_tick->count = 0;
}
return;
}

detach();
}
Loading