One of the most used (and abused) functions in the Arduino world is the notorious delay()
This function is as simple to use as harmful and deleterious for our projects because it's blocking and while the microcontroller is busy executing the delay() instruction, it will do absolutely nothing else and usually we don't need this excpet for very simple projects.
In my opionion, there are very few situations in which it occurs that something like this may be necessary or it is the best solution within a software algorithm.
Then, what do you think about a very small class that performs an action after a time that can be set in a non-blocking way?
The use, as you can see from this example, is quite straightforward: define a callback function to be called after a delay and call SetTimeout() method.
As alternative you can also use a bool variable and poll the actual state inside the main loop()
On an ESP32 delay() is transformed into vTaskDelay() which is a non-blocking delay. If freeRTOS is being used and there is no code in loop() then blocking does not occur.
And this is why it is essential to know what hardware a poster is running when evaluating their code - delay() isn't universally to be avoided, but if the poster has a Uno, the context of use is much more important.
The vTaskDelay() instruction pauses the task from which it is invoked, so in the case of Arduino, if I call delay() inside loop() it will pause most of the things.
Calling delay() in any function on a Uno will pause program execution. Calling delay on a ESP32 that is using tasks and there is no code in loop() will cause a task switch.
Ok, but beginners usually don't use "advanced" task features of FreeRTOS.
And unfortunately FreeRTOS is not available on all hardware platforms
The point, however, is that the inappropriate use of delay() function, as usually in the library examples, accustoms users to think algorithms exclusively sequentially and as soon as they need do more than one thing with a microcontroller, they do not have the correct "mindset" to address the problem.
@cotestatnt You need to write an example that uses a few of those objects.
I haven't figured out what all this could ever do for me. Certainly pressing both buttons at once seems to not be handled.
Also "button is pressed" would be more accurate than "button was pressed", which to me reads like "button went down".
I don't think it will help with the typical mess noobs get into when they come to complain about some consequence or other accruing from a liberal reliance on dealy() in naive code.
Maybe you have made a clever and useful tool, but I do not believe anyone will get much of anywhere using it without having been able to write more-or-less the same thing by themselves using basic principles which should be understood by everyone doing anything even mildly serious.
I don't think this matter can be wrapped up and solved in the same manner as, say, an LCD library or a button debounce library. And in the case of a button debounce library, I would still argue that most everyone ought to know how to do that, even if they use a library.
Um. A task switch is normally considered a form of “blocking”, isn’t it? Some other task may run, but YOUR task has blocked (and stays blocked until the scheduler runs it again.)
Please keep in mind that whatever solution you propose must look fairly simple to a beginner who has not yet understood why delay causes problems. If they are just about to discover this fact then the depths of C++ will still be in their far future. I also very much believe you need to know how to create non blocking time intervals yourself before using any kind of pre made code to do so.