-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor Touch class to extract Brush and Rub classes as their own touch features #26
base: development
Are you sure you want to change the base?
Conversation
// Large movement -> integrate with 0 | ||
else if(std::abs(movement) > 1) | ||
{ | ||
integrate(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took this from the OG algorithm, but tbh I'm not entirely sure why we're ignoring values above 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll let Edu take the descision about the code semantics, here are just a few comments about the code. Thanks for this great patch !
* @param new_tie Pointer to the external value to tie the feature to. | ||
* @return True if the tie was successful; false if `new_tie` is null. | ||
*/ | ||
bool tie(float* new_tie) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this, maybe we should bass a reference to the float instead of a pointer. This way, the language itself prevents the null case as a reference must always point to something.
It would simply become
void tie(float& new_tie) {
tied_data = &new_tie;
}
as now we don't need a boolean to record if this worked :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah of course, great one!
class TouchFeature | ||
{ | ||
public: | ||
TouchFeature() = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if all these constructors are even needed, it should be equivalent to just not declare them as per rule-of-zero
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the issue is that if we want a constructor for the tied value (see the protected
section), and I think we want one, then we also need at least a default one, and then might as well have all of them right. We could also rely on users explicitly calling tie
to tie a value but that's a bit awkward
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm basically copying what was done (I think by you lol) here:
explicit Jab(double* tied) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope, that was me 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But maybe simplifying might be good, there are indeed too many constructors
assert(start >= 0 && end >= start); | ||
|
||
float sum{}; | ||
for(int i = start; i < end; ++i) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const float sum = std::reduce(array + start, array + end);
likely it will also give some performance boost as it may parallelize operations / use SIMD or funky stuff like that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm personally reluctant to include
anything that isn't necessary in embedded projects, so here <numeric>
, but I guess it's all tradeoffs -- @edumeneses what do you think?
template <typename T> | ||
float arrayAverage(const T* array, int start, int end) | ||
{ | ||
static_assert(std::is_arithmetic<T>::value, "T must be an arithmetic type!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually with concepts this can be done in a very built-in way:
#include <concepts>
float arrayAverage(const std::arithmetic auto* array, int start, int end) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideal code in an ideal world:
#include <concepts>
#include <numeric>
#include <print>
template<typename T>
concept arithmetic = std::integral<T> || std::floating_point<T>;
float arrayAverage(const arithmetic auto* array, int start, int end)
// in a couple years, with C++ contracts (https://www.modernescpp.com/index.php/contracts-in-c26/)
// pre(start >= 0)
// pre(end >= start)
// until then it's asserts...
{
return std::reduce(array + start, array + end) / float(end - start);
}
int main()
{
{
int foo[3]{0, 10, 20};
std::println("{}", arrayAverage(foo, 0, 3));
}
{
std::string foo[3]{"foo", "bar", "baz"};
// build error since std::string is not arithmetic
// std::println("{}", arrayAverage(foo, 0, 3));
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(std::arithmetic seems to be missing from stdlib)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right... so in an ideal world concepts would be supported by the toolchain that platformIO uses, but for now they aren't 😅
ecc7782
to
d8ce298
Compare
…e, make everything else more agnostic, and address PR comments
d8ce298
to
12b67f1
Compare
Fixes #22 and #23.