As an OOP tutorial held up to novices, the article is highly opinionated, dubious even, in places.
Agreed. It's my opinion, it's the way I write things, it's a specific way I use OO with arduino (specifically: giving everything a setup and a loop). Maybe I should put a caveat to that effect towards the beginning.
- Neglecting to mention the cost of OOP.
- Overuse of private properties
- brightnessClicker 'should' [not] be a property of headlamp - Breaks the MVC pattern.
- Calling millis() repeatedly
- Blocking a refresh method for 800,000 clock cycles.
I don't see what's wrong with making things private.
And it doesn't make sense to complain that OOP is expensive, and to be peevish that I don't use MVC everywhere. Yes, you can do make event queues and whatnot that malloc space for event objects. Not worth it. And in any case, I state repeatedly that this sort of stuff is not suitable for anything where cycles are important.
As to not making brightness clicker part of headlamp by direct composition - I just disagree. It's a fine way to do (some) things. Direct composition doesn't in itself break MVC. If this sort of composition does break MVC and composition by reference doesn't, isn't it a little odd that the syntax and method calls you need to make are otherwise identical?
Not sure that calling millis() repeatedly is a problem. How much work is it, compared to passing it around on the stack or leaving it in a sketch-scoped variable? I would have thought that millis() talks pretty directly to the chip somewhere, straight to a hardware port.
I used to take millis() once and pass it into the loop() for everyone, but eventually decided that the whole point is that these things shouldn't need to synchronize.
"The problem is
that there are then two places [where a click is started]"
The redundancy can be reduced logically, by sticking to a read/modify/write pattern.
Yes, my code doesn't strictly adhere to a pattern. I like using an enum for states and having a loop that is strictly that switch statement and nothing else.
Maybe I should pull out and make explicit that some methods are smalltalk-style 'messages' intended to be called by other things, that they comprise an interface to the object.
I see no tangible benefit in the Runnable class. As such, the class adds unnecessary complexity, consuming RAM and clock cycles needlessly.
Well, there are intangible benefits to it. Helps clarify what you are doing, I think. Actually, the real reason is that Runnable and its automatically-populated queue in effect provide a higher-level framework than the sturdy old setup() and loop() methods on their own.
Personally I would not call simple inheritance polymorphism, even with virtual functions - It's simply, inheritance. Multiple inheritance and overriding methods, would be examples of polymorphism, to my mind.
Perhaps I need to point out that the benefit of the polymorphic button class is that you could write a class that does something different on a long click and short click, and that you wouldn't need to rewrite the "debounce/short/long click" logic again.
"It's called 'time-slicing'"
No, not really. Time-slicing is an established term, which implies pre-empting, by a scheduler.
Wikipedia agrees. What do you call multitasking by way of yielding control, then? Actually, I'll ask wikipedia. … Hmm, "co-operative multitasking" seems to be the thing to call it.