Compare commits

..

No commits in common. "5b7051157040e51d634e64ad8bffbc2cc7a960cc" and "cb4afa504332c59045742f02fcbb52126108d49d" have entirely different histories.

29 changed files with 102 additions and 381 deletions

View File

@ -41,7 +41,7 @@ protected:
unsigned long currentFrameSince; unsigned long currentFrameSince;
uint8_t currentFrame = 0; uint8_t currentFrame = 0;
uint8_t* animation_data; uint8_t* animation_data;
CRGB** _colors = NULL; CRGB** _colors;
CRGB* fgColor = NULL; CRGB* fgColor = NULL;
CRGB* bgColor = new CRGB(0x000000); CRGB* bgColor = new CRGB(0x000000);
int8_t xOffset = 0; int8_t xOffset = 0;
@ -51,11 +51,11 @@ protected:
Window* _window; Window* _window;
uint8_t _width; uint8_t _width;
uint8_t _height; uint8_t _height;
uint8_t _frame_count = 0; uint8_t _frame_count;
uint8_t _color_count = 0; uint8_t _color_count;
uint16_t* _frame_times = NULL; uint16_t* _frame_times;
uint16_t* _frame_data_lengths = NULL; uint16_t* _frame_data_lengths;
uint8_t** _frame_data = NULL; uint8_t** _frame_data;
bool _data_valid = false; bool _data_valid = false;
virtual CRGB* getColor(uint8_t color_index); virtual CRGB* getColor(uint8_t color_index);
@ -65,8 +65,8 @@ protected:
bool _load_from_file(const char* c); bool _load_from_file(const char* c);
public: public:
Animation(const char* filename, Window* win); Animation(const char* filename, Window* win);
void setFgColor(uint32_t c); void setFgColor(CRGB*);
void setBgColor(uint32_t c); void setBgColor(CRGB* bg_color);
bool invert(); bool invert();
void setOffsets(int8_t x, int8_t y); void setOffsets(int8_t x, int8_t y);
void setStartFrame(uint8_t sf); void setStartFrame(uint8_t sf);

View File

@ -17,7 +17,6 @@ public:
void setWindow(Window* win) { void setWindow(Window* win) {
window = win; window = win;
}; };
virtual void apply_option(String key, String value) {};
}; };
#endif #endif

View File

@ -18,7 +18,6 @@ public:
void clear(CRGB* color); void clear(CRGB* color);
void setPixel(uint8_t x, uint8_t y, CRGB* color); void setPixel(uint8_t x, uint8_t y, CRGB* color);
void setPixelByIndex(uint16_t index, CRGB* color); void setPixelByIndex(uint16_t index, CRGB* color);
void raisePixel(uint8_t x, uint8_t y, CRGB* color);
void line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, CRGB* color); void line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, CRGB* color);
void lineWithAngle(uint8_t x, uint8_t y, uint8_t angle, uint8_t length, CRGB* color); void lineWithAngle(uint8_t x, uint8_t y, uint8_t angle, uint8_t length, CRGB* color);
void lineWithAngle(uint8_t x, uint8_t y, uint8_t angle, uint8_t startdist, uint8_t length, CRGB* color); void lineWithAngle(uint8_t x, uint8_t y, uint8_t angle, uint8_t startdist, uint8_t length, CRGB* color);

View File

@ -56,8 +56,6 @@
#define EFFECT_SINGLE_DYNAMIC_LOOP_TIME 40 #define EFFECT_SINGLE_DYNAMIC_LOOP_TIME 40
#define EFFECT_MULTI_DYNAMIC_LOOP_TIME 1400 #define EFFECT_MULTI_DYNAMIC_LOOP_TIME 1400
#define EFFECT_BIG_DYNAMIC_LOOP_TIME 50
#define EFFECT_BIG_DYNAMIC_SIZE 3
#define EFFECT_CONFETTI_PIXELS_PER_LOOP 2 #define EFFECT_CONFETTI_PIXELS_PER_LOOP 2
@ -75,9 +73,6 @@
#define EFFECT_GOL_BLEND_SPEED 10 #define EFFECT_GOL_BLEND_SPEED 10
#define EFFECT_GOL_RESTART_AFTER_STEPS 100 #define EFFECT_GOL_RESTART_AFTER_STEPS 100
#define EFFECT_DVD_WIDTH 3
#define EFFECT_DVD_HEIGHT 2
// Stop editing here // Stop editing here
#ifdef DEBUG #ifdef DEBUG

View File

@ -8,13 +8,13 @@
class AnimationEffect : public Effect { class AnimationEffect : public Effect {
private: private:
Animation *animation; Animation *animation;
CRGB *bg_color;
uint16_t xOffset; uint16_t xOffset;
uint16_t yOffset; uint16_t yOffset;
public: public:
AnimationEffect(const char* name) : AnimationEffect(name, 0x000000, 0, 0) {} AnimationEffect(const char* name) : AnimationEffect(name, new CRGB(0x000000), 0, 0) {}
AnimationEffect(const char* name, uint32_t bg_color) : AnimationEffect(name, bg_color, 0, 0) {} AnimationEffect(const char* name, CRGB* background_color) : AnimationEffect(name, background_color, 0, 0) {}
AnimationEffect(const char* name, uint32_t bg_color, int x, int y); AnimationEffect(const char* name, CRGB* bg_color, int x, int y);
~AnimationEffect(); ~AnimationEffect();
AnimationEffect* setFgColor(uint32_t c);
void loop(); void loop();
}; };

View File

@ -10,7 +10,6 @@ private:
Window* window = new Window(0, LED_HEIGHT - 6, LED_WIDTH, 6); Window* window = new Window(0, LED_HEIGHT - 6, LED_WIDTH, 6);
public: public:
~ClockEffect();
void loop(); void loop();
void loop(boolean invert, CRGB fg_color, CRGB bg_color); void loop(boolean invert, CRGB fg_color, CRGB bg_color);
}; };

View File

@ -5,16 +5,8 @@
#include "my_fastled.h" #include "my_fastled.h"
class ConfettiEffect : public Effect { class ConfettiEffect : public Effect {
protected:
virtual CRGB _getColor();
public:
void loop(); void loop();
boolean can_be_shown_with_clock(); boolean can_be_shown_with_clock();
}; };
class RandomConfettiEffect : public ConfettiEffect {
protected:
CRGB _getColor() override;
};
#endif #endif

View File

@ -1,17 +0,0 @@
#pragma once
#include "Effect.h"
class DvdEffect : public Effect {
private:
Window* window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
uint8_t _x = 0;
uint8_t _y = 0;
int8_t _x_dir = 1;
int8_t _y_dir = 1;
CRGB _color;
public:
DvdEffect();
~DvdEffect();
void loop() override;
bool can_be_shown_with_clock() override;
};

View File

@ -21,11 +21,3 @@ class MultiDynamicEffect : public SingleDynamicEffect {
public: public:
void loop(); void loop();
}; };
class BigDynamicEffect : public Effect {
private:
Window* window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
public:
void loop();
~BigDynamicEffect();
};

View File

@ -9,23 +9,16 @@
class MatrixEffectColumn { class MatrixEffectColumn {
protected: protected:
Window* window; Window* window;
uint8_t x, y; int x, y;
uint8_t length = 1; int length = 1;
uint8_t _direction = 2;
bool _random_direction = false;
virtual CRGB _getColor(uint8_t height); virtual CRGB _getColor(uint8_t height);
virtual void restart(bool completely_random); virtual void restart();
private: private:
uint16_t speed; uint16_t speed;
boolean running; boolean running;
unsigned long last_move = 0; unsigned long last_move = 0;
public: public:
static const uint8_t DIR_NORTH = 0; MatrixEffectColumn(Window* win, int xPos);
static const uint8_t DIR_EAST = 1;
static const uint8_t DIR_SOUTH = 2;
static const uint8_t DIR_WEST = 3;
MatrixEffectColumn(Window* win, uint8_t direction=0, bool random_direction=false);
virtual ~MatrixEffectColumn() {}; virtual ~MatrixEffectColumn() {};
void advance(); void advance();
void draw(); void draw();
@ -36,16 +29,16 @@ class RainbowMatrixEffectColumn : public MatrixEffectColumn {
protected: protected:
CRGB _getColor(uint8_t height) override; CRGB _getColor(uint8_t height) override;
public: public:
RainbowMatrixEffectColumn(Window* win, uint8_t dir, bool rnd=false) : MatrixEffectColumn(win, dir, rnd) {}; RainbowMatrixEffectColumn(Window* win, int xPos) : MatrixEffectColumn(win, xPos) {};
}; };
class RandomMatrixEffectColumn : public MatrixEffectColumn { class RandomMatrixEffectColumn : public MatrixEffectColumn {
protected: protected:
uint8_t _hue = 42; uint8_t _hue = 42;
CRGB _getColor(uint8_t height) override; CRGB _getColor(uint8_t height) override;
void restart(bool completely_random) override; void restart() override;
public: public:
RandomMatrixEffectColumn(Window* win, uint8_t dir, bool rnd=false) : MatrixEffectColumn(win, dir, rnd) {}; RandomMatrixEffectColumn(Window* win, int xPos) : MatrixEffectColumn(win, xPos) {};
}; };
class MatrixEffect : public Effect { class MatrixEffect : public Effect {

View File

@ -17,7 +17,6 @@ private:
bool is_direction_okay(uint8_t direction); bool is_direction_okay(uint8_t direction);
public: public:
SnakeEffect(); SnakeEffect();
~SnakeEffect();
void loop(); void loop();
boolean valid_position(Coords c); boolean valid_position(Coords c);
Coords update_position(Coords c, uint8_t direction); Coords update_position(Coords c, uint8_t direction);

View File

@ -11,7 +11,7 @@ extern uint8_t cycle_effects_count;
extern Effect* current_effect; extern Effect* current_effect;
extern ClockEffect effect_clock; extern ClockEffect effect_clock;
Effect* select_effect(uint32_t c); Effect* string_to_effect(String s);
bool change_current_effect(String s); bool change_current_effect(String s);
void setup_effects(); void setup_effects();

View File

@ -1,6 +0,0 @@
#pragma once
namespace tests {
void run();
void test_effects_for_memory_leaks();
}

View File

@ -160,14 +160,12 @@ Animation::Animation(const char* filename, Window* win) {
} }
} }
void Animation::setFgColor(uint32_t c) { void Animation::setFgColor(CRGB* fg_color) {
if (this->fgColor) delete this->fgColor; this->fgColor = fg_color;
this->fgColor = new CRGB(c);
} }
void Animation::setBgColor(uint32_t c) { void Animation::setBgColor(CRGB* bg_color) {
if (this->bgColor) delete this->bgColor; this->bgColor = bg_color;
this->bgColor = new CRGB(c);
} }
bool Animation::invert() { bool Animation::invert() {
@ -207,27 +205,15 @@ void Animation::setSingleFrame(uint8_t frame) {
Animation::~Animation() { Animation::~Animation() {
for (int i=0; i<_color_count; i++) delete _colors[i]; for (int i=0; i<_color_count; i++) delete _colors[i];
LOGln("Deleting _colors..."); delete [] _colors;
if (_colors) delete [] _colors; if (fgColor) delete fgColor;
LOGln("Deleting fgColor..."); delete bgColor;
delete [] _frame_data_lengths;
if (fgColor != NULL) delete fgColor; delete [] _frame_times;
LOGln("Deleting bgColor...");
if (bgColor != NULL) delete bgColor;
LOGln("Deleting _frame_data_lengths...");
if (_frame_data_lengths) delete [] _frame_data_lengths;
LOGln("Deleting _frame_times...");
if (_frame_times) delete [] _frame_times;
for (int i=0; i<_frame_count; i++) { for (int i=0; i<_frame_count; i++) {
delete [] _frame_data[i]; delete [] _frame_data[i];
} }
LOGln("Deleting _frame_data..."); delete [] _frame_data;
if (_frame_data) delete [] _frame_data;
LOGln("Deleteion done.");
} }
void Animation::draw() { void Animation::draw() {
@ -244,7 +230,7 @@ void Animation::drawFrame(uint8_t frame_index) {
CRGB red(0xFF0000); CRGB red(0xFF0000);
CRGB black(0x000000); CRGB black(0x000000);
for (int x=0; x<_window->width; x++) for (int y=0; y<_window->height; y++) { for (int x=0; x<_window->width; x++) for (int y=0; y<_window->height; y++) {
_window->setPixel(x, y, (y*_window->width+x + y) % 2 ? &red : &black); _window->setPixel(x, y, (y*_window->width+x) % 2 ? &red : &black);
} }
return; return;
} }

View File

@ -11,11 +11,6 @@ void Window::setPixel(uint8_t x, uint8_t y, CRGB* color) {
leds[this->coordsToGlobalIndex(x, y)] = *color; leds[this->coordsToGlobalIndex(x, y)] = *color;
} }
void Window::raisePixel(uint8_t x, uint8_t y, CRGB* color) {
if (x>=this->width || y>=this->height) return;
leds[this->coordsToGlobalIndex(x, y)] |= *color;
}
void Window::setPixelByIndex(uint16_t index, CRGB* color) { void Window::setPixelByIndex(uint16_t index, CRGB* color) {
uint8_t x = index % this->width; uint8_t x = index % this->width;
uint8_t y = index / this->width; uint8_t y = index / this->width;

View File

@ -1,20 +1,16 @@
#include "effect_animation.h" #include "effect_animation.h"
#include "functions.h" #include "functions.h"
AnimationEffect::AnimationEffect(const char* name, uint32_t bg, int x, int y) { AnimationEffect::AnimationEffect(const char* name, CRGB* bg, int x, int y) {
this->bg_color = bg;
this->xOffset = x; this->xOffset = x;
this->yOffset = y; this->yOffset = y;
this->animation = new Animation(name, window); this->animation = new Animation(name, window);
this->animation->setBgColor(bg); this->animation->setBgColor(this->bg_color);
this->animation->setOffsets(this->xOffset, this->yOffset); this->animation->setOffsets(this->xOffset, this->yOffset);
} }
AnimationEffect* AnimationEffect::setFgColor(uint32_t c) {
animation->setFgColor(c);
return this;
}
AnimationEffect::~AnimationEffect() { AnimationEffect::~AnimationEffect() {
delete this->animation; delete this->animation;
} }

View File

@ -40,7 +40,3 @@ void ClockEffect::loop(boolean invert, CRGB fg_color, CRGB bg_color) {
window->setPixel(7, 4, &fg_color); window->setPixel(7, 4, &fg_color);
} }
} }
ClockEffect::~ClockEffect() {
delete window;
}

View File

@ -6,17 +6,9 @@
void ConfettiEffect::loop() { void ConfettiEffect::loop() {
window->fadeToBlackBy(3); window->fadeToBlackBy(3);
for (int i=0; i<EFFECT_CONFETTI_PIXELS_PER_LOOP; i++) { for (int i=0; i<EFFECT_CONFETTI_PIXELS_PER_LOOP; i++) {
CRGB color = _getColor(); CRGB color(CHSV(baseHue + random8(64), 200, 255));
window->addPixelColor(random16(LED_COUNT), &color); window->addPixelColor(random16(LED_COUNT), &color);
} }
} }
CRGB ConfettiEffect::_getColor() {
return CHSV(baseHue + random8(64), 255, 255);
}
CRGB RandomConfettiEffect::_getColor() {
return CHSV(random8(), 255, 255);
}
boolean ConfettiEffect::can_be_shown_with_clock() { return true; }; boolean ConfettiEffect::can_be_shown_with_clock() { return true; };

View File

@ -1,6 +1,5 @@
#include "effect_cycle.h" #include "effect_cycle.h"
#include "effects.h" #include "effects.h"
#include <ErriezCRC32.h>
CycleEffect::CycleEffect() { CycleEffect::CycleEffect() {
changeEffect(); changeEffect();
@ -24,7 +23,7 @@ void CycleEffect::changeEffect() {
if (effect) delete effect; if (effect) delete effect;
LOGln("CycleEffect * Searching for new effect '%s'", cycle_effects[new_id]); LOGln("CycleEffect * Searching for new effect '%s'", cycle_effects[new_id]);
delay(25); delay(25);
effect = select_effect( crc32String(cycle_effects[new_id]) ); effect = string_to_effect(cycle_effects[new_id]);
effect_id = new_id; effect_id = new_id;
effectSince = millis(); effectSince = millis();
} }

View File

@ -1,37 +0,0 @@
#include "effect_dvd.h"
#include "my_fastled.h"
void DvdEffect::loop() {
bool dir_changed = false;
EVERY_N_MILLISECONDS( 250 ) {
_x += _x_dir;
_y += _y_dir;
if (_x == 0 || _x + EFFECT_DVD_WIDTH >= window->width) {
_x_dir = -_x_dir;
dir_changed = true;
}
if (_y == 0 || _y + EFFECT_DVD_HEIGHT >= window->height) {
_y_dir = -_y_dir;
dir_changed = true;
}
}
window->clear();
for (int x=0; x<EFFECT_DVD_WIDTH; x++) for (int y=0; y<EFFECT_DVD_HEIGHT; y++) {
window->setPixel(_x + x, _y + y, (CRGB*)&_color);
}
if (dir_changed) _color = (CRGB)CHSV(random8(), 255, 255);
}
bool DvdEffect::can_be_shown_with_clock() { return true; }
DvdEffect::DvdEffect() {
_color = CHSV(random8(), 255, 255);
}
DvdEffect::~DvdEffect() {
delete window;
}

View File

@ -34,28 +34,3 @@ void MultiDynamicEffect::loop() {
} }
this->draw(); this->draw();
} }
BigDynamicEffect::~BigDynamicEffect() {
delete window;
}
void BigDynamicEffect::loop() {
EVERY_N_MILLISECONDS( EFFECT_BIG_DYNAMIC_LOOP_TIME ) {
uint8_t x = random8(0, window->width - EFFECT_BIG_DYNAMIC_SIZE + 1);
uint8_t y = random8(0, window->height - EFFECT_BIG_DYNAMIC_SIZE + 1);
CRGB color = CHSV(random8(), 255, 255);
CRGB black(0x000000);
for (uint8_t ix=0; ix<EFFECT_BIG_DYNAMIC_SIZE; ix++) for (uint8_t iy=0; iy<EFFECT_BIG_DYNAMIC_SIZE; iy++) {
window->setPixel(x+ix, y+iy, &color);
}
/*for (uint8_t ix=0; ix<EFFECT_BIG_DYNAMIC_SIZE+2; ix++) {
window->setPixel(x-1+ix, y-1, &black);
window->setPixel(x-1+ix, y+EFFECT_BIG_DYNAMIC_SIZE+1, &black);
}
for (uint8_t iy=0; iy<EFFECT_BIG_DYNAMIC_SIZE+2; iy++) {
window->setPixel(x-1, y-1+iy, &black);
window->setPixel(x+EFFECT_BIG_DYNAMIC_SIZE+1, y-1+iy, &black);
}*/
}
}

View File

@ -26,7 +26,6 @@ void GolEffect::_initialize() {
GolEffect::~GolEffect() { GolEffect::~GolEffect() {
delete[] _data; delete[] _data;
delete[] _old; delete[] _old;
delete window;
} }
void GolEffect::loop() { void GolEffect::loop() {

View File

@ -2,80 +2,29 @@
#include "my_color_palettes.h" #include "my_color_palettes.h"
#include "functions.h" #include "functions.h"
MatrixEffectColumn::MatrixEffectColumn(Window* win, uint8_t dir, bool rand) { MatrixEffectColumn::MatrixEffectColumn(Window* win, int xPos) {
window = win; window = win;
_direction = dir; x = xPos;
_random_direction = rand; restart();
restart(true); y = random8(0, window->height);
} }
void MatrixEffectColumn::restart(bool completely_random) { void MatrixEffectColumn::restart() {
if (_random_direction) { y=-1;
_direction = random8(4);
}
if (completely_random) {
x = random8(window->width);
y = random8(window->height);
} else {
switch(_direction) {
case DIR_NORTH:
x = random8(window->width);
y = window->height - 1;
break;
case DIR_EAST:
x = 0;
y = random8(window->height);
break;
case DIR_SOUTH:
x = random8(window->width);
y = 0;
break;
case DIR_WEST:
x = window->width - 1;
y = random8(window->height);
break;
}
}
length = random8(EFFECT_MATRIX_LENGTH_MIN, EFFECT_MATRIX_LENGTH_MAX); length = random8(EFFECT_MATRIX_LENGTH_MIN, EFFECT_MATRIX_LENGTH_MAX);
running = true; running = true;
speed = random8(EFFECT_MATRIX_SPEED_MIN, EFFECT_MATRIX_SPEED_MAX); speed = random8(EFFECT_MATRIX_SPEED_MIN, EFFECT_MATRIX_SPEED_MAX);
} }
void MatrixEffectColumn::advance() { void MatrixEffectColumn::advance() {
switch(_direction) { y++;
case DIR_NORTH: if (y-length > window->height) running = false;
y--;
if (y > window->height && y + length > window->height) running=false;
break;
case DIR_EAST:
x++;
if (x - length > window->width) running=false;
break;
case DIR_SOUTH:
y++;
if (y - length > window->height) running=false;
break;
case DIR_WEST:
x--;
if (x > window->width && y + length > window->width) running=false;
break;
}
} }
void MatrixEffectColumn::draw() { void MatrixEffectColumn::draw() {
int8_t xdir = 0;
int8_t ydir = 0;
switch (_direction) {
case DIR_NORTH: ydir = 1; break;
case DIR_EAST: xdir = 1; break;
case DIR_SOUTH: ydir = -1; break;
case DIR_WEST: xdir = -1; break;
}
for(int i=0; i<length; i++) { for(int i=0; i<length; i++) {
CRGB color = _getColor(i); CRGB color = _getColor(i);
window->raisePixel(x+(xdir*i), y+(ydir*i), &color); window->setPixel(x, y-i, &color);
} }
} }
@ -83,7 +32,7 @@ void MatrixEffectColumn::loop() {
if (!running) { if (!running) {
if (random8() < 20) { if (random8() < 20) {
// Start the column again. // Start the column again.
restart(false); restart();
} }
} else { } else {
if (millis() - last_move > speed) { if (millis() - last_move > speed) {
@ -126,8 +75,8 @@ CRGB RandomMatrixEffectColumn::_getColor(uint8_t i) {
return color; return color;
} }
void RandomMatrixEffectColumn::restart(bool completely_random) { void RandomMatrixEffectColumn::restart() {
MatrixEffectColumn::restart(completely_random); MatrixEffectColumn::restart();
_hue = random8(); _hue = random8();
} }
@ -148,15 +97,15 @@ MatrixEffect::MatrixEffect() {
} }
void MatrixEffect::_init() { void MatrixEffect::_init() {
for (int i=0; i<window->width; i++) _columns[i] = new MatrixEffectColumn(window, MatrixEffectColumn::DIR_SOUTH); for (int i=0; i<window->width; i++) _columns[i] = new MatrixEffectColumn(window, i);
} }
void RandomMatrixEffect::_init() { void RandomMatrixEffect::_init() {
for (int i=0; i<window->width; i++) _columns[i] = new RandomMatrixEffectColumn(window, random8(4), true); for (int i=0; i<window->width; i++) _columns[i] = new RandomMatrixEffectColumn(window, i);
} }
void RainbowMatrixEffect::_init() { void RainbowMatrixEffect::_init() {
for (int i=0; i<window->width; i++) _columns[i] = new RainbowMatrixEffectColumn(window, MatrixEffectColumn::DIR_SOUTH); for (int i=0; i<window->width; i++) _columns[i] = new RainbowMatrixEffectColumn(window, i);
} }
MatrixEffect::~MatrixEffect() { MatrixEffect::~MatrixEffect() {

View File

@ -10,7 +10,6 @@ PixelClockEffect::PixelClockEffect() {
PixelClockEffect::~PixelClockEffect() { PixelClockEffect::~PixelClockEffect() {
delete _color_seconds; delete _color_seconds;
delete _color_minutes; delete _color_minutes;
delete window;
} }
void PixelClockEffect::loop() { void PixelClockEffect::loop() {

View File

@ -6,10 +6,6 @@ SnakeEffect::SnakeEffect() {
this->window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6); this->window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
} }
SnakeEffect::~SnakeEffect() {
delete window;
}
void SnakeEffect::loop() { void SnakeEffect::loop() {
if (run++ % EFFECT_SNAKE_SLOWDOWN == 0) { // Change the coordinates only on every n-th run. if (run++ % EFFECT_SNAKE_SLOWDOWN == 0) { // Change the coordinates only on every n-th run.
if (random8(EFFECT_SNAKE_DIRECTION_CHANGE)==0 || is_turn_needed()) turn_random(); if (random8(EFFECT_SNAKE_DIRECTION_CHANGE)==0 || is_turn_needed()) turn_random();

View File

@ -17,77 +17,46 @@
#include "effect_firework.h" #include "effect_firework.h"
#include "effect_gol.h" #include "effect_gol.h"
#include "effect_pixelclock.h" #include "effect_pixelclock.h"
#include "effect_dvd.h"
Effect* current_effect; Effect* current_effect;
ClockEffect effect_clock; ClockEffect effect_clock;
Effect* select_effect(uint32_t code) { Effect* string_to_effect(String name) {
switch (code) { uint32_t crc = crc32String(name.c_str());
switch (crc) {
// use e.g. https://crccalc.com/ for the conversion of name to crc. // use e.g. https://crccalc.com/ for the conversion of name to crc.
case 0: case 0xD682E3C8 /* sinematrix3 */ : return new Sinematrix3Effect(); case 0xD682E3C8 /* sinematrix3 */ : return new Sinematrix3Effect();
case 1: case 0x90A887DA /* big_clock */ : return new BigClockEffect(); case 0x90A887DA /* big_clock */ : return new BigClockEffect();
case 2: case 0xBE7BBE92 /* clock */ : return new ClockEffect(); case 0xBE7BBE92 /* clock */ : return new ClockEffect();
case 3: case 0x733BE087 /* bell */ : return new BellEffect(); //(new AnimationEffect("/bell.pia", 0x000000, 0, 0))->setFgColor(0xFFFF00); case 0x733BE087 /* bell */ : return new BellEffect();
case 4: case 0x2BBC5D43 /* off */ : return new StaticEffect(0x000000); case 0x2BBC5D43 /* off */ : return new StaticEffect(0x000000);
case 5: case 0x1D84F231 /* koopa */ : return new AnimationEffect("/koopa.pia", CRGB(0x000000), 0, 0); case 0x1D84F231 /* koopa */ : return new AnimationEffect("/koopa.pia", new CRGB(0x000000), 0, 0);
case 6: case 0xAC43BCF1 /* couple_rain */ : return new AnimationEffect("/couple_rain.pia", CRGB(0x000000), -8, -16); case 0xAC43BCF1 /* couple_rain */ : return new AnimationEffect("/couple_rain.pia", new CRGB(0x000000), -8, -16);
case 7: case 0xF1B117F7 /* single_dynamic */ : return new SingleDynamicEffect(); case 0xF1B117F7 /* single_dynamic */ : return new SingleDynamicEffect();
case 8: case 0xF52F2804 /* multi_dynamic */ : return new MultiDynamicEffect(); case 0xF52F2804 /* multi_dynamic */ : return new MultiDynamicEffect();
case 9: case 0xF83341CF /* matrix */ : return new MatrixEffect(); case 0xF83341CF /* matrix */ : return new MatrixEffect();
case 10: case 0xD2B79DD0 /* rainbow_matrix */ : return new RainbowMatrixEffect(); case 0xD2B79DD0 /* rainbow_matrix */ : return new RainbowMatrixEffect();
case 11: case 0xE8DD3433 /* random_matrix */ : return new RandomMatrixEffect(); case 0xE8DD3433 /* random_matrix */ : return new RandomMatrixEffect();
case 12: case 0xB086D193 /* cycle */ : return new CycleEffect(); case 0xB086D193 /* cycle */ : return new CycleEffect();
case 13: case 0x2293EF9F /* twirl */ : return new TwirlEffect(); case 0x2293EF9F /* twirl */ : return new TwirlEffect();
case 14: case 0x60ECC3E6 /* heart */ : return new AnimationEffect("/heart.pia", CRGB(0x000000), 0, 0); case 0x60ECC3E6 /* heart */ : return new AnimationEffect("/heart.pia", new CRGB(0x000000), 0, 0);
case 15: case 0x42090A49 /* confetti */ : return new ConfettiEffect(); case 0x42090A49 /* confetti */ : return new ConfettiEffect();
case 16: case 0x516D6B9E /* snake */ : return new SnakeEffect(); case 0x516D6B9E /* snake */ : return new SnakeEffect();
case 17: case 0x58DE09CF /* fire */ : return new FireEffect(); case 0x58DE09CF /* fire */ : return new FireEffect();
case 18: case 0x08BA9C08 /* firework */ : return new FireworkEffect(); case 0x08BA9C08 /* firework */ : return new FireworkEffect();
case 19: case 0x14B85EAC /* gol */ : return new GolEffect(); case 0x14B85EAC /* gol */ : return new GolEffect();
case 20: case 0xFA13015D /* cake */ : return new AnimationEffect("/cake.pia", CRGB(0x000000), 0, 0); case 0xFA13015D /* cake */ : return new AnimationEffect("/cake.pia", new CRGB(0x000000), 0, 0);
case 21: case 0xA2B0D68B /* pixel_clock */ : return new PixelClockEffect(); 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();
default : return NULL; default : return NULL;
}; };
} }
bool change_current_effect(String payload) { bool change_current_effect(String name) {
int pos = payload.indexOf(","); Effect* new_effect = string_to_effect(name);
String options = ""; if (new_effect == NULL) return false;
if (pos != -1) {
LOGln("Effects * Effect comes with options.");
options = payload.substring(pos+1);
payload.remove(pos);
LOGln("Effects * Cleaned effect name: %s", payload.c_str());
}
Effect* new_effect = select_effect( crc32String(payload.c_str()) );
if (new_effect == NULL) {
LOGln("Effects * Could not find effect with name %s", payload.c_str());
return false;
}
delete current_effect; delete current_effect;
current_effect = new_effect; current_effect = new_effect;
if (options.length() > 0) {
LOGln("Effects * Parsing options: %s", options.c_str());
options += ",";
int p_colon;
while ((p_colon = options.indexOf(",")) >= 0) {
int p_equal = options.indexOf("=");
if (p_equal >= 0 && p_equal < p_colon) {
String key = options.substring(0, p_equal);
String value = options.substring(p_equal + 1, p_colon);
LOGln("Effects * Applying option: %s = %s", key.c_str(), value.c_str());
current_effect->apply_option(key, value);
}
options.remove(0, p_colon + 1);
}
}
return true; return true;
} }

View File

@ -10,7 +10,6 @@
#include "Effect.h" #include "Effect.h"
#include "effects.h" #include "effects.h"
#include "functions.h" #include "functions.h"
#include "tests.h"
WiFiClient wifi; WiFiClient wifi;
PubSubClient mqtt_client(wifi); PubSubClient mqtt_client(wifi);
@ -58,20 +57,12 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
if(topic.compareTo("mode")==0) { if(topic.compareTo("mode")==0) {
LOGln("MQTT * Changing mode..."); LOGln("MQTT * Changing mode...");
bool result = change_current_effect(payload); change_current_effect(payload);
if (result) {
LOGln("MQTT * Effect changed.");
} else {
LOGln("MQTT * Could not change effect.");
}
return; return;
} else if (topic.compareTo("reboot")==0) { } else if (topic.compareTo("reboot")==0) {
LOGln("MQTT * Rebooting"); LOGln("MQTT * Rebooting");
ESP.restart(); ESP.restart();
return; // Will never be reached, but anyway... return; // Will never be reached, but anyway...
} else if (topic.compareTo("run_tests")==0) {
tests::run();
return;
} }
long value = payload.toInt(); long value = payload.toInt();
LOGln("MQTT * Payload as number: %d", value); LOGln("MQTT * Payload as number: %d", value);
@ -90,12 +81,10 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
} }
boolean mqtt_connect() { boolean mqtt_connect() {
LOGln("MQTT * Connecting to MQTT server with client id %s", hostname); LOG("MQTT * Connecting to MQTT server with client id %s", hostname);
if (mqtt_client.connect(hostname, MQTT_USER, MQTT_PASS, MQTT_TOPIC "status", 0, true, "OFFLINE", true)) { if (mqtt_client.connect(hostname, MQTT_USER, MQTT_PASS, MQTT_TOPIC "status", 0, true, "OFFLINE", true)) {
LOGln("MQTT * Connected."); LOGln("MQTT * Connected.");
char buffer[40]; mqtt_client.publish(MQTT_TOPIC "status", "ONLINE", true);
snprintf(buffer, 40, "ONLINE %s %s", hostname, WiFi.localIP().toString().c_str());
mqtt_client.publish(MQTT_TOPIC "status", buffer, true);
mqtt_client.subscribe(MQTT_TOPIC "+"); mqtt_client.subscribe(MQTT_TOPIC "+");
mqtt_client.subscribe(MQTT_TOPIC_WEATHER "#"); mqtt_client.subscribe(MQTT_TOPIC_WEATHER "#");
} }

View File

@ -1,4 +1,5 @@
#include <Arduino.h> #include <Arduino.h>
#include <SimpleList.h>
#include "ntp.h" #include "ntp.h"
#include "config.h" #include "config.h"

View File

@ -1,28 +0,0 @@
#include "tests.h"
#include "effects.h"
namespace tests {
void run() {
LOGln("Tests * Running test for memory leaks...");
test_effects_for_memory_leaks();
}
void test_effects_for_memory_leaks() {
int i=0;
Effect* effect;
int32_t diffs[3] = {0, 0, 0};
int32_t usage = 0;
while (1) {
for (int j=0; j<3; j++) {
int free_at_start = ESP.getFreeHeap();
effect = select_effect(i);
if (j==0) usage = free_at_start - ESP.getFreeHeap();
if (effect == NULL) return;
delete effect;
diffs[j] = free_at_start - ESP.getFreeHeap();
}
LOGln("Tests * Memory usage of effect #%d: %d, leakage %d, %d, %d", i, usage, diffs[0], diffs[1], diffs[2]);
i++;
}
}
}