Reorganized effect selection stuff: No longer a big case clause comparing CRC32. Instead an array of structs. Much nicer. Also, other code can now see which effects there are.

This commit is contained in:
Fabian Schlenz 2019-10-02 06:16:07 +02:00
parent 3f6d4cb0be
commit 083564caef
6 changed files with 77 additions and 51 deletions

View File

@ -95,7 +95,6 @@ If you enabled `DEBUG`, log messages will be sent to `MQTT_TOPIC/log`.
| FastLED (with small modifications) | Daniel Garcia & Mark Kriegsman | https://fastled.io
| NTPClient (with modifications) | | https://github.com/arduino-libraries/NTPClient
| ESP8266WebServer | | https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer
| ErriezCRC32 | Erriez | https://github.com/Erriez/ErriezCRC32
| ESPAsyncTCP | me-no-dev | https://github.com/me-no-dev/ESPAsyncTCP
### Inspirations and stuff

View File

@ -8,6 +8,7 @@ private:
Effect* effect = NULL;
uint16_t effect_id = -1;
unsigned long effectSince = 0;
uint8_t _effects_count;
public:
CycleEffect();
~CycleEffect();

View File

@ -1,17 +1,20 @@
#ifndef effects_H
#define effects_H
#pragma once
#include "Effect.h"
#include "effect_clock.h"
extern const char* cycle_effects[];
extern uint8_t cycle_effects_count;
struct EffectEntry {
const char* name;
bool use_in_cycle;
std::function<Effect*()> create;
};
extern const EffectEntry effects[];
extern const uint8_t effects_size;
extern Effect* current_effect;
extern ClockEffect effect_clock;
Effect* select_effect(uint32_t c);
Effect* select_effect(char* name);
Effect* select_effect(uint8_t id);
bool change_current_effect(String s);
void setup_effects();
#endif

View File

@ -18,7 +18,6 @@ lib_deps =
https://github.com/fabianonline/FastLED.git
https://github.com/fabianonline/NTPClient.git
ESP8266WebServer
ErriezCRC32
ESPAsyncTCP
[env:ota]

View File

@ -3,6 +3,11 @@
#include <ErriezCRC32.h>
CycleEffect::CycleEffect() {
_effects_count = 0;
for (uint8_t i=0; i<effects_size; i++) {
if (effects[i].use_in_cycle) _effects_count++;
}
LOGln("Cycle * Found %d effects to use in cycle.", _effects_count);
changeEffect();
}
@ -14,17 +19,28 @@ void CycleEffect::changeEffect() {
uint8_t new_id;
if (settings.effects.cycle.random && _effects_count>1) {
do {
new_id = random8(cycle_effects_count);
new_id = random8(_effects_count);
} while (new_id == effect_id);
} else {
new_id = (effect_id + 1) % cycle_effects_count;
new_id = (effect_id + 1) % _effects_count;
}
LOGln("CycleEffect * Changing effect from #%d to #%d", effect_id, new_id);
delay(25);
if (effect) delete effect;
LOGln("CycleEffect * Searching for new effect '%s'", cycle_effects[new_id]);
delay(25);
effect = select_effect( crc32String(cycle_effects[new_id]) );
LOGln("CycleEffect * Searching for new effect #%d", new_id);
for (uint8_t i=0; i<effects_size; i++) {
if (effects[i].use_in_cycle) {
if (new_id == 0) {
effect = effects[i].create();
break;
} else {
new_id--;
}
}
}
if (effect) {
effect_id = new_id;
effectSince = millis();
@ -47,7 +63,7 @@ void CycleEffect::loop(uint16_t ms) {
// Don't use EVERY_N_SECONDS(config_effect_cycle_time) here because that function isn't relly made
// to be used with changing values.
EVERY_N_SECONDS(1) {
if (effectSince + EFFECT_CYCLE_TIME*1000 < millis()) {
if (effectSince + settings.effects.cycle.time*1000 < millis()) {
changeEffect();
}
}

View File

@ -1,7 +1,6 @@
#include "effects.h"
#include "config.h"
#include "my_fastled.h"
#include <ErriezCRC32.h>
#include "effect_bell.h"
#include "effect_sinematrix3.h"
#include "effect_big_clock.h"
@ -28,41 +27,50 @@ Effect* current_effect;
ClockEffect effect_clock;
Effect* select_effect(uint32_t code) {
switch (code) {
// use e.g. https://crccalc.com/ for the conversion of name to crc.
case 0: case 0xD682E3C8 /* sinematrix3 */ : return new Sinematrix3Effect();
case 1: case 0x90A887DA /* big_clock */ : return new BigClockEffect();
case 2: case 0xBE7BBE92 /* clock */ : return new ClockEffect();
case 3: case 0x733BE087 /* bell */ : return new BellEffect(); //(new AnimationEffect("/bell.pia", 0x000000, 0, 0))->setFgColor(0xFFFF00);
case 4: case 0x2BBC5D43 /* off */ : return new StaticEffect(0x000000);
case 5: case 0x1D84F231 /* koopa */ : return new AnimationEffect("/koopa.pia", CRGB(0x000000), 0, 0);
case 6: case 0xAC43BCF1 /* couple_rain */ : return new AnimationEffect("/couple_rain.pia", CRGB(0x000000), -8, -16);
case 7: case 0xF1B117F7 /* single_dynamic */ : return new SingleDynamicEffect();
case 8: case 0xF52F2804 /* multi_dynamic */ : return new MultiDynamicEffect();
case 9: case 0xF83341CF /* matrix */ : return new MatrixEffect();
case 10: case 0xD2B79DD0 /* rainbow_matrix */ : return new RainbowMatrixEffect();
case 11: case 0xE8DD3433 /* random_matrix */ : return new RandomMatrixEffect();
case 12: case 0xB086D193 /* cycle */ : return new CycleEffect();
case 13: case 0x2293EF9F /* twirl */ : return new TwirlEffect();
case 14: case 0x60ECC3E6 /* heart */ : return new AnimationEffect("/heart.pia", CRGB(0x000000), 0, 0);
case 15: case 0x42090A49 /* confetti */ : return new ConfettiEffect();
case 16: case 0x516D6B9E /* snake */ : return new SnakeEffect();
case 17: case 0x58DE09CF /* fire */ : return new FireEffect();
case 18: case 0x08BA9C08 /* firework */ : return new FireworkEffect();
case 19: case 0x14B85EAC /* gol */ : return new GolEffect();
case 20: case 0xFA13015D /* cake */ : return new AnimationEffect("/cake.pia", CRGB(0x000000), 0, 0);
case 21: case 0xA2B0D68B /* pixel_clock */ : return new PixelClockEffect();
case 22: case 0x2C0E6962 /* big_dynamic */ : return new BigDynamicEffect();
case 23: case 0xDA6F31A5 /* random_confetti */ : return new RandomConfettiEffect();
case 24: case 0x8325C1DF /* dvd */ : return new DvdEffect();
case 25: case 0x8CA97519 /* analog_clock */ : return new AnalogClockEffect();
case 26: case 0xADB18CC5 /* sines */ : return new SinesEffect();
case 27: case 0x0407881E /* blur2d */ : return new Blur2DEffect();
case 28: case 0x935CFA7C /* marquee */ : return new MarqueeEffect();
case 29: case 0xE27D739E /* night_clock */ : return new NightClockEffect();
default : return NULL;
};
const EffectEntry effects[] = {
/* 0 */ {"sinematrix3", true, [](){ return new Sinematrix3Effect(); }},
/* 1 */ {"big_clock", true, [](){ return new BigClockEffect(); }},
/* 2 */ {"clock", false, [](){ return new ClockEffect(); }},
/* 3 */ {"bell", false, [](){ return new BellEffect(); }},
/* 4 */ {"off", false, [](){ return new StaticEffect(0x000000); }},
/* 5 */ {"single_dynamic", true, [](){ return new SingleDynamicEffect(); }},
/* 6 */ {"multi_dynamic", true, [](){ return new MultiDynamicEffect(); }},
/* 7 */ {"big_dynamic", true, [](){ return new BigDynamicEffect(); }},
/* 8 */ {"matrix", true, [](){ return new MatrixEffect(); }},
/* 9 */ {"random_matrix", true, [](){ return new RandomMatrixEffect(); }},
/* 10 */ {"rainbow_matrix", true, [](){ return new RainbowMatrixEffect(); }},
/* 11 */ {"cycle", false, [](){ return new CycleEffect(); }},
/* 12 */ {"twirl", true, [](){ return new TwirlEffect(); }},
/* 13 */ {"confetti", true, [](){ return new ConfettiEffect(); }},
/* 14 */ {"random_confetti", true, [](){ return new RandomConfettiEffect(); }},
/* 15 */ {"snake", true, [](){ return new SnakeEffect(); }},
/* 16 */ {"firework", true, [](){ return new FireworkEffect(); }},
/* 17 */ {"gol", true, [](){ return new GolEffect(); }},
/* 18 */ {"pixel_clock", false, [](){ return new PixelClockEffect(); }},
/* 19 */ {"dvd", false, [](){ return new DvdEffect(); }},
/* 20 */ {"analog_clock", false, [](){ return new AnalogClockEffect(); }},
/* 21 */ {"sines", true, [](){ return new SinesEffect(); }},
/* 22 */ {"blur2d", true, [](){ return new Blur2DEffect(); }},
/* 23 */ {"marquee", 0, [](){ return new MarqueeEffect(); }},
/* 24 */ {"night_clock", false, [](){ return new NightClockEffect(); }}
};
const uint8_t effects_size = 25;
Effect* select_effect(const char* name) {
for(int i=0; i<effects_size; i++) {
if (strcmp(effects[i].name, name)==0) {
return effects[i].create();
}
}
return NULL;
}
Effect* select_effect(uint8_t id) {
if (id < effects_size) {
return effects[id].create();
}
return NULL;
}
bool change_current_effect(String payload) {
@ -75,7 +83,7 @@ bool change_current_effect(String payload) {
LOGln("Effects * Cleaned effect name: %s", payload.c_str());
}
Effect* new_effect = select_effect( crc32String(payload.c_str()) );
Effect* new_effect = select_effect( payload.c_str() );
if (new_effect == NULL) {
LOGln("Effects * Could not find effect with name %s", payload.c_str());
return false;