Conversation
robertlipe
left a comment
There was a problem hiding this comment.
This is just really hard to review because I think it includes pieces of two other sweeping changes (new audio math, new config system) and there are changes unrelated to the goal mixed in. There are thus some entire files I just didn't look at in this PR.
For what I think is the focal point, I like the direction, but I'd like to peel some of the preprocessing away even more. While the templates are thick, the call sites and the flexibility offered in configurations are pretty nice.
It's a good step forward. This PR specifically is messy, but once I ignore the construction mess, I like the direction.
|
|
||
| // Adds a default and JSON effect factory, but the default effect will be disabled upon creation. | ||
| template<typename TEffect, typename... Args> | ||
| inline EffectFactories::NumberedFactory& AddEffectDisabled(EffectFactories& factories, Args&&... args) |
There was a problem hiding this comment.
Optional food for thought: Is is really worth having separate AddEffectDisabled()s for all of these? Should there perhaps be an additional argument that defaults to kEnabled?
Alternately, use the Named Paramater Idiom so you could invoke AddEffect(blah, arg1, arg2, arg3).disabled()
There was a problem hiding this comment.
No idea. I'll defer to Rutger on that!
There was a problem hiding this comment.
Short answer: no. Particularly with the Disabled() decorator that one would use with RegisterAll(), the separate Add...Disabled() functions are unnecessary.
In my effectid-template branch, I've already removed them.
There was a problem hiding this comment.
As (partially) mentioned already in an out-of-band exchange, I think the switch to a template-based approach is an improvement.
I'm approving with some important side notes, and I do think we should make some further changes after this PR is merged.
Specifically:
- I did not review changes that are part of PR #746 - I've commented on those changes there (the empty soundanalyzer.cpp probably being the one exception...)
- There is a number of effects that do not yet adopt the new approach - I think all those that are not currently pulled into an effect set in effects.cpp. I think we should apply this pattern comprehensively if we choose to apply it.
- There are quite a few whitespace-glitches in the modified effects code (Copilot somehow always seems to struggle with this, even when specifically instructed to fix it.) I didn't comment on these; a comprehensive white-spacing clean-up is part of the branch I will mention in my next point.
- The per-effect declaration and definition of the effect-specific
kIdandeffectId()members causes a lot of repetitive code, which relies on developer discipline and is prone to copy/paste errors. I've created aeffectid-templatebranch in my fork that proposes a template-based approach for setting an effect's EffectId, which I think is cleaner. - With the increased flexibility in effect set compositions, I think the simple approach of an integer version number is no longer the way to distinguish between a persisted effect set and the "standard" set. I've created a
factories_hashbranch in my fork to propose a hash-based approach instead.
Both branches I just mentioned can be turned into PRs independently after this PR has been merged; I'll happily take care of any merge conflicts that arise if we do indeed adopt both of them - I'm pretty sure there would be some in effectsupport.h.
| class PatternAlienText : public LEDStripEffect | ||
| { | ||
| public: | ||
| static constexpr EffectId kId = idMatrixAlienText; |
There was a problem hiding this comment.
I know this is a matter of preference and opinions vary, but I'd prefer kId to be called Id, or something else without the k - adding it seems like a disclosure of a class-internal implementation decision to me.
This obviously applies to all other effects as well.
| { | ||
| public: | ||
| PatternRainbowFlag() : LEDStripEffect(EFFECT_MATRIX_RAINBOW_FLAG, "RainbowFlag") | ||
| PatternRainbowFlag() : LEDStripEffect(idMatrixRainbowFlag, "RainbowFlag") |
There was a problem hiding this comment.
The kId/effectId() combo is missing here, which you get away with because the effect is currently not included in any effect set.
| public: | ||
|
|
||
| PatternPulse() : LEDStripEffect(EFFECT_MATRIX_PULSE, "Pulse") | ||
| PatternPulse() : LEDStripEffect(idMatrixPulse, "Pulse") |
There was a problem hiding this comment.
Missing kId/effectId() combo.
| public: | ||
|
|
||
| PatternQR() : LEDStripEffect(EFFECT_MATRIX_QR, "QR") | ||
| PatternQR() : LEDStripEffect(idMatrixQR, "QR") |
There was a problem hiding this comment.
Missing kId/effectId() block.
|
|
||
| public: | ||
| PatternSpiro() : LEDStripEffect(EFFECT_MATRIX_SPIRO, "Spiro") | ||
| PatternSpiro() : LEDStripEffect(idMatrixSpiro, "Spiro") |
There was a problem hiding this comment.
kId/effectId() pair is missing.
|
|
||
| // Adds a default and JSON effect factory, but the default effect will be disabled upon creation. | ||
| template<typename TEffect, typename... Args> | ||
| inline EffectFactories::NumberedFactory& AddEffectDisabled(EffectFactories& factories, Args&&... args) |
There was a problem hiding this comment.
Short answer: no. Particularly with the Disabled() decorator that one would use with RegisterAll(), the separate Add...Disabled() functions are unnecessary.
In my effectid-template branch, I've already removed them.
| return false; | ||
| } | ||
|
|
||
| // Helper functions for known setting types, as defined in SettingSpec::SettingType |
There was a problem hiding this comment.
@robertlipe assuming you're talking about std::variant, maybe. With all the testing of which reference is held by the variant and having to align that with the template parameters for the types that are supported, I'm not exactly sure how much cleaner, or clearer, the code would be.
And we're not talking about a dozen overloads, but seven. :)
Migrate macros to templates, simplify effects table, add effectId() to all derived effects
mainas the target branch.