diff --git a/src/internal/Animation.cpp b/src/internal/Animation.cpp index e74a26b..118cea7 100644 --- a/src/internal/Animation.cpp +++ b/src/internal/Animation.cpp @@ -12,6 +12,10 @@ Animation::~Animation() { if (this->liveStream != nullptr && this->isOneTimeLiveStream) { delete this->liveStream; } + + if (this->playedIndexes != nullptr) { + delete[] this->playedIndexes; + } } bool Animation::hasFinished() { @@ -36,16 +40,21 @@ void Animation::addScene(Stream &stream, byte fps, int frames) { void Animation::registerScene(Scene *scene) { Scene **newScenes = new Scene *[this->addIndex + 1]; + bool *newPlayedIndexes = new bool[this->addIndex + 1]; for (int i = 0; i < this->addIndex; i++) { newScenes[i] = this->scenes[i]; + newPlayedIndexes[i] = this->playedIndexes[i]; } newScenes[this->addIndex] = scene; + newPlayedIndexes[this->addIndex] = false; delete[] this->scenes; + delete[] this->playedIndexes; this->scenes = newScenes; + this->playedIndexes = newPlayedIndexes; this->addIndex++; } @@ -65,9 +74,14 @@ void Animation::setScene(byte index) { byte prevIndex = this->playIndex; this->playIndex = index; + this->playedIndexes[index] = true; this->scene = this->scenes[index]; this->scene->reset(); + if (this->allScenesPlayed()) { + this->resetPlayedScenes(); + } + if (this->sceneCallback) { this->sceneCallback(prevIndex, index); } @@ -77,7 +91,9 @@ void Animation::setRandomScene() { byte randomIndex = 0; if (this->addIndex > 1) { - randomIndex = random(this->addIndex); + do { + randomIndex = random(this->addIndex); + } while (this->playedIndexes[randomIndex]); } this->setScene(randomIndex); @@ -94,6 +110,12 @@ void Animation::resetScene() { } } +void Animation::resetPlayedScenes() { + for (int i = 0; i < this->addIndex; i++) { + this->playedIndexes[i] = false; + } +} + void Animation::play() { if (!this->hasScenes() || !this->modeIsIn(2, MODE_DEFAULT, MODE_PAUSE)) { return; @@ -190,6 +212,20 @@ byte Animation::getPlayIndex() { return this->playIndex; } +bool Animation::scenePlayed(int index) { + return this->playedIndexes[index]; +} + +bool Animation::allScenesPlayed() { + for (int i = 0; i < this->addIndex; i++) { + if (!this->playedIndexes[i]) { + return false; + } + } + + return true; +} + void Animation::run(unsigned long currentMicros) { switch (this->mode) { case MODE_PLAY: diff --git a/src/internal/Animation.h b/src/internal/Animation.h index fde8b7b..6eb67d7 100644 --- a/src/internal/Animation.h +++ b/src/internal/Animation.h @@ -46,6 +46,8 @@ class Animation { bool hasFinished(); bool hasScenes(); + bool scenePlayed(int index); + bool allScenesPlayed(); Scene *getCurrentScene(); @@ -58,6 +60,7 @@ class Animation { AnimationData *liveStream = nullptr; bool isOneTimeLiveStream = false; + bool *playedIndexes = nullptr; mcb modeCallback = nullptr; scb sceneCallback = nullptr; @@ -75,6 +78,7 @@ class Animation { void setScene(byte index); void setRandomScene(); void resetScene(); + void resetPlayedScenes(); bool modeIsIn(byte modeAmount, ...); }; diff --git a/test/animation/test_play_random/test_play_random.cpp b/test/animation/test_play_random/test_play_random.cpp index 20b55fa..ef92e6c 100644 --- a/test/animation/test_play_random/test_play_random.cpp +++ b/test/animation/test_play_random/test_play_random.cpp @@ -18,14 +18,20 @@ void test_play_random(void) { animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, animation.getMode()); + TEST_ASSERT_FALSE(animation.scenePlayed(0)); + TEST_ASSERT_FALSE(animation.scenePlayed(1)); + TEST_ASSERT_FALSE(animation.scenePlayed(2)); - When(OverloadedMethod(ArduinoFake(), random, long(long))).Return(1, 0, 2); + When(OverloadedMethod(ArduinoFake(), random, long(long))).Return(1, 0, 0, 2); animation.playRandom(); TEST_ASSERT_EQUAL(Animation::MODE_PLAY_RANDOM, animation.getMode()); TEST_ASSERT_NOT_EQUAL(nullptr, animation.getCurrentScene()); TEST_ASSERT_EQUAL(1, animation.getPlayIndex()); + TEST_ASSERT_FALSE(animation.scenePlayed(0)); + TEST_ASSERT_TRUE(animation.scenePlayed(1)); + TEST_ASSERT_FALSE(animation.scenePlayed(2)); for (int i = 0; i < ANIMATION_MICROS; i += FRAME_MICROS) { animation.run(i); @@ -33,6 +39,9 @@ void test_play_random(void) { TEST_ASSERT_EQUAL(Animation::MODE_PLAY_RANDOM, animation.getMode()); TEST_ASSERT_EQUAL(0, animation.getPlayIndex()); + TEST_ASSERT_TRUE(animation.scenePlayed(0)); + TEST_ASSERT_TRUE(animation.scenePlayed(1)); + TEST_ASSERT_FALSE(animation.scenePlayed(2)); for (long i = 0; i < ANIMATION_MICROS; i += FRAME_MICROS) { animation.run(i); @@ -41,6 +50,9 @@ void test_play_random(void) { TEST_ASSERT_EQUAL(Animation::MODE_PLAY_RANDOM, animation.getMode()); TEST_ASSERT_EQUAL(2, animation.getPlayIndex()); TEST_ASSERT_EQUAL(20, logIndex); + TEST_ASSERT_FALSE(animation.scenePlayed(0)); + TEST_ASSERT_FALSE(animation.scenePlayed(1)); + TEST_ASSERT_FALSE(animation.scenePlayed(2)); } void test_without_scenes(void) {