-
Notifications
You must be signed in to change notification settings - Fork 84
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
add ComboBlade and associated wrappers #668
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
#ifndef BLADES_COMBO_BLADE_H | ||
#define BLADES_COMBO_BLADE_H | ||
|
||
/* | ||
Usage: ComboBlade(blade1, blade2) | ||
This allows multiple blades to be combined into a single linear blade even if | ||
they use different data lines for control. | ||
|
||
The resulting blade will have a length of the number of LEDs in the first and | ||
second blade combined. When the style is running, the second blade's LEDs will | ||
be controlled as though they were in line and after the first blade's LEDs | ||
|
||
For a simple example, if you have a saber with 2 crystal LEDs running on different | ||
data lines rather than in line with one another, you might often do the following. | ||
|
||
{ 0, | ||
WS281XBladePtr<128, bladePin, Color8::GRB, PowerPINS<bladePowerPin2, bladePowerPin3> >(), | ||
WS281XBladePtr<1, blade4Pin, Color8::GRB, PowerPINS<bladePowerPin2, bladePowerPin3> >(), | ||
WS281XBladePtr<1, blade3Pin, Color8::GRB, PowerPINS<bladePowerPin2, bladePowerPin3> >(), | ||
} | ||
|
||
The above way allows us to assign either the same style or different styles to | ||
both LEDs | ||
|
||
However, if we assign the same style the LEDs will do the same thing since they | ||
are both seen as the first LED in a 1 LED longht blade. To avoid this, we can | ||
use ComboBlade, which will result in the style being run against an intermediate | ||
blade with a length of 2, rainbow and stripe styles to move between the two | ||
|
||
{ 0, | ||
WS281XBladePtr<128, bladePin, Color8::GRB, PowerPINS<bladePowerPin2, bladePowerPin3> >(), | ||
ComboBlade(WS281XBladePtr<1, blade4Pin, Color8::GRB, PowerPINS<bladePowerPin2, bladePowerPin3> >(), | ||
WS281XBladePtr<1, blade3Pin, Color8::GRB, PowerPINS<bladePowerPin2, bladePowerPin3>>()), | ||
|
||
In the above example we must reduce the NUM_BLADES by 1 since the ComboBlade itself | ||
is the only thing that counts as an entry in the blade array. | ||
|
||
*/ | ||
|
||
class ComboBladeWrapper : public BladeWrapper, BladeStyle { | ||
public: | ||
ComboBladeWrapper(BladeBase* blade1, BladeBase* blade2): | ||
blade1_num_leds_(blade1->num_leds()), | ||
blade2_num_leds_(blade2->num_leds()), | ||
blade2_(blade2), | ||
real_style_(nullptr), | ||
blade2_cache_(new OverDriveColor[blade2_num_leds_]) | ||
{ | ||
blade_ = blade1; | ||
} | ||
|
||
// BladeStyle implementation | ||
virtual void activate() override { | ||
real_style_->activate(); | ||
} | ||
virtual void deactivate() override { | ||
real_style_->deactivate(); | ||
} | ||
virtual void run(BladeBase* blade) override { | ||
if (blade == blade_) { | ||
real_style_->run(this); | ||
} else { | ||
// On blade2_ we just apply cached values from when blade_ was run | ||
for (int i = 0; i < blade2_num_leds_; i++){ | ||
if (blade2_cache_[i].overdrive) { | ||
blade2_->set_overdrive(i, blade2_cache_[i].c); | ||
} else { | ||
blade2_->set(i, blade2_cache_[i].c); | ||
} | ||
} | ||
} | ||
} | ||
|
||
bool NoOnOff() override { | ||
return real_style_->NoOnOff(); | ||
} | ||
|
||
profezzorn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
virtual bool Charging() { return real_style_->Charging(); } | ||
|
||
bool IsHandled(HandledFeature effect) override { | ||
return real_style_->IsHandled(effect); | ||
} | ||
|
||
OverDriveColor getColor(int i) override { return real_style_->getColor(i); } | ||
|
||
int get_max_arg(int arg) override { return real_style_->get_max_arg(arg); } | ||
|
||
// BladeBase implementation | ||
int num_leds() const override { | ||
return blade1_num_leds_ + blade2_num_leds_; | ||
} | ||
void set(int led, Color16 c) override { | ||
if (led < blade1_num_leds_) { | ||
return blade_->set(led, c); | ||
profezzorn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else { | ||
blade2_cache_[led - blade1_num_leds_].c = c; | ||
blade2_cache_[led - blade1_num_leds_].overdrive = false; | ||
} | ||
} | ||
|
||
void set_overdrive(int led, Color16 c) override { | ||
if (led < blade1_num_leds_) { | ||
return blade_->set_overdrive(led, c); | ||
} else { | ||
blade2_cache_[led - blade1_num_leds_].c = c; | ||
blade2_cache_[led - blade1_num_leds_].overdrive = true; | ||
} | ||
} | ||
|
||
void allow_disable() override { | ||
blade_->allow_disable(); | ||
blade2_->allow_disable(); | ||
} | ||
|
||
void clear() override { | ||
blade_->clear(); | ||
blade2_->clear(); | ||
} | ||
|
||
void Activate(int blade_number) override { | ||
blade_->Activate(blade_number); | ||
blade2_->Activate(blade_number); | ||
} | ||
|
||
void Deactivate() override { | ||
blade_->Deactivate(); | ||
blade2_->Deactivate(); | ||
} | ||
|
||
void SetStyle(BladeStyle* style) override { | ||
real_style_ = style; | ||
blade_->SetStyle(this); | ||
blade2_->SetStyle(this); | ||
} | ||
|
||
BladeStyle* UnSetStyle() override { | ||
BladeStyle* ret = real_style_; | ||
if (ret) { | ||
ret->deactivate(); | ||
} | ||
real_style_ = nullptr; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should also call blade_ / blade2_ -> UnSetStyle() here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure why, but it actually seems like I get a crash due to a null pointer somewhere when I tried this, willing to explore more if you think this idea is still worth pursuing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you have a config file that crashes (and instructions for how to make it crash if needed) I can run it with a debugger to see exactly where the crash occurs. |
||
return ret; | ||
} | ||
|
||
BladeStyle* current_style() const override { | ||
return real_style_; | ||
} | ||
|
||
private: | ||
int blade1_num_leds_; | ||
int blade2_num_leds_; | ||
BladeBase* blade2_; | ||
BladeStyle* real_style_; | ||
OverDriveColor *blade2_cache_; | ||
}; | ||
|
||
BladeBase* ComboBlade(BladeBase* blade1, BladeBase* blade2) | ||
{ | ||
return new ComboBladeWrapper(blade1, blade2); | ||
} | ||
|
||
#endif |
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.
Needs a destructor that deletes the blade2_cache_