Understanding HumpflickerF

in the following:

template<int HUMP_WIDTH>
class HumpFlickerF {
public:
  void run(BladeBase* blade) {
    int num_leds_ = blade->num_leds();
    pos_ = random(num_leds_);
  }
  int getInteger(int led) {
    return clampi32(abs(led - pos_) * 32768 / HUMP_WIDTH, 0, 32768);
  }

It looks like this should be able to take a Function ( Int<> ) for the Hump Width in the blade style… but it doesn’t because it’s a type/value mismatch error?

You would need to make a HumFlickerFX, something like:

template<class HUMP_WIDTH>
class HumpFlickerFX {
public:
  void run(BladeBase* blade) {
    hum_width_.run(blade);
    int num_leds_ = blade->num_leds();
    pos_ = random(num_leds_);
    width_  = hump_width_.calculate(blade);
  }
  int getInteger(int led) {
    return clampi32(abs(led - pos_) * 32768 / width_, 0, 32768);
  }
private:
  int width_;
  PONUA SVFWrapper<HUMP_PWIDTH> hump_width_;
}

Because of how C++ works, it’s not possible to have a template that can accept an integer OR a class (like Int<>)

Sweet.
Now, to not break other things throughout the OS like styles/hump_flicker.h, and to maintain backward compatibility, we would then want to cover use of the original template via a new templated using statement like

template<int HUMP_WIDTH> using HumpFlickerF = HumpFlickerFX<Int<HUMP_WIDTH>>;

yes?

And since the hump_flicker style file includes the bump.h file at the top, by the time we get to the call to the regular version ` using HumpFlickerL = AlphaL<B, HumpFlickerF<HUMP_WIDTH>>;’ it should be already known by it’s new version.
Am I right?

Normally, this is exactly what we do.
However, because HumpFlickerFX needs an extra variable compared to HumpFlickerF (width_), I would probably keep both in this case for maximum memory efficiency.

well leaving both as is here causes a shadowed template parameter.
I think either the int or class named HUMP_WIDTH need to change

template<int HUMP_WIDTH>
class HumpFlickerF {
public:
  void run(BladeBase* blade) {
    int num_leds_ = blade->num_leds();
    pos_ = random(num_leds_);
  }
  int getInteger(int led) {
    return clampi32(abs(led - pos_) * 32768 / HUMP_WIDTH, 0, 32768);
  }

template<class HUMP_WIDTH>
class HumpFlickerFX {
public:
  void run(BladeBase* blade) {
    hump_width_.run(blade);
    int num_leds_ = blade->num_leds();
    pos_ = random(num_leds_);
    width_  = hump_width_.calculate(blade);
  }
  int getInteger(int led) {
    return clampi32(abs(led - pos_) * 32768 / width_, 0, 32768);
  }
private:
  int width_;
  PONUA SVFWrapper<HUMP_WIDTH> hump_width_;
  int pos_;
};

template<int HUMP_WIDTH> using HumpFlickerF = HumpFlickerFX<Int<HUMP_WIDTH>>;

oops I see my mistake
cut off the old ending. lost it’s private :open_mouth:
Plus, didn’t lose the using.
How’s this? working over here.

template<int HUMP_WIDTH>
class HumpFlickerF {
public:
  void run(BladeBase* blade) {
    int num_leds_ = blade->num_leds();
    pos_ = random(num_leds_);
  }
  int getInteger(int led) {
    return clampi32(abs(led - pos_) * 32768 / HUMP_WIDTH, 0, 32768);
  }
private:
  int pos_;
};

template<class HUMP_WIDTH>
class HumpFlickerFX {
public:
  void run(BladeBase* blade) {
    hump_width_.run(blade);
    int num_leds_ = blade->num_leds();
    pos_ = random(num_leds_);
    width_  = hump_width_.calculate(blade);
  }
  int getInteger(int led) {
    return clampi32(abs(led - pos_) * 32768 / width_, 0, 32768);
  }
private:
  int width_;
  PONUA SVFWrapper<HUMP_WIDTH> hump_width_;
  int pos_;
};

Looks good to me.

Adding that code block plus this one basic piece of test code
AlphaL<Red,HumpFlickerFX<Int<50>>>
totals 50 bytes difference
vs
AlphaL<Red,HumpFlickerF<50>>

Actually, when I think about it, it might be better to write it like this:

emplate<class HUMP_WIDTH>
class HumpFlickerFX {
public:
  void run(BladeBase* blade) {
    hump_width_.run(blade);
    int num_leds_ = blade->num_leds();
    pos_ = random(num_leds_);
  }
  int getInteger(int led) {
    return clampi32(abs(led - pos_) * 32768 / hum_width_.getInteger(led), 0, 32768);
  }
private:
  PONUA HUMP_WIDTH hump_width_;
  int pos_;
};

This doesn’t have the extra variable, and if it’s passed an Int<>, it should generate the same code as before, so we should be able to use an alias to replace HumpFlickerF. If HUMP_WIDTH is an SVF, then the SingleValueAdapter will add the extra variable, and the result will be the same as the version that had the width_ variable. If HUMP_WIDTH is not an SVF, it will generate per-pixel code which could cause some weird (but maybe cool?) effects.

Cool!
Well, I’ll try to wrap my head around your SVF post in the meanwhile to try to understand why it might or might not be an SVF.
masterpiece-theater-presents SVF

And… the bonus is that with that latest code, and replacing the original HumpFlickerF with just the using template,
the total compiled bytes is 32 less than when we started!

So are you making a pull request, or should I?

1 Like