From 83cc85d8f99e0b61937e9e6595279574f7de20d7 Mon Sep 17 00:00:00 2001 From: Tim Hendriks Date: Mon, 15 Jan 2024 17:59:24 +0100 Subject: [PATCH] merge live and progmem stream into animation data --- examples/SerialLiveMode/SerialLiveMode.ino | 7 +-- .../WebSocketLiveMode/WebSocketLiveMode.ino | 15 ++--- platformio.ini | 2 +- src/BlenderServoAnimation.h | 3 +- src/internal/Animation.cpp | 24 ++++--- src/internal/Animation.h | 3 +- src/internal/AnimationData.cpp | 62 +++++++++++++++++++ src/internal/AnimationData.h | 43 +++++++++++++ src/internal/LiveStream.cpp | 49 --------------- src/internal/LiveStream.h | 29 --------- src/internal/ProgmemStream.cpp | 37 ----------- src/internal/ProgmemStream.h | 30 --------- src/internal/Scene.cpp | 33 +++------- src/internal/Scene.h | 14 ++--- src/internal/ServoManager.cpp | 8 +-- src/internal/ServoManager.h | 3 +- test/animation/test_live/test_live.cpp | 4 +- test/animation/test_loop/test_loop.cpp | 13 ++-- .../test_mode_callback/test_mode_callback.cpp | 21 ++++--- test/animation/test_pause/test_pause.cpp | 13 ++-- test/animation/test_play/test_play.cpp | 6 ++ .../test_play_random/test_play_random.cpp | 13 ++-- .../test_play_single/test_play_single.cpp | 14 +++-- test/animation/test_stop/test_stop.cpp | 31 +++++++--- test/helper.h | 24 +++++++ .../test_animation_data.cpp | 50 +++++++++++++++ test/test_live_stream/test_live_stream.cpp | 48 -------------- .../test_progmem_stream.cpp | 28 --------- test/test_scene/test_scene.cpp | 22 +++---- .../test_servo_manager/test_servo_manager.cpp | 26 ++++---- 30 files changed, 321 insertions(+), 354 deletions(-) create mode 100644 src/internal/AnimationData.cpp create mode 100644 src/internal/AnimationData.h delete mode 100644 src/internal/LiveStream.cpp delete mode 100644 src/internal/LiveStream.h delete mode 100644 src/internal/ProgmemStream.cpp delete mode 100644 src/internal/ProgmemStream.h create mode 100644 test/test_animation_data/test_animation_data.cpp delete mode 100644 test/test_live_stream/test_live_stream.cpp delete mode 100644 test/test_progmem_stream/test_progmem_stream.cpp diff --git a/examples/SerialLiveMode/SerialLiveMode.ino b/examples/SerialLiveMode/SerialLiveMode.ino index 972240d..a7a56c6 100644 --- a/examples/SerialLiveMode/SerialLiveMode.ino +++ b/examples/SerialLiveMode/SerialLiveMode.ino @@ -35,11 +35,8 @@ void setup() { // Set the position callback animation.onPositionChange(move); - // Add a new scene with the Serial stream - we can omit fps and frames - animation.addScene(Serial); - - // Trigger the animation play mode - animation.play(); + // Trigger the animation live mode + animation.live(Serial); } void loop() { diff --git a/examples/WebSocketLiveMode/WebSocketLiveMode.ino b/examples/WebSocketLiveMode/WebSocketLiveMode.ino index 15b459d..29766ad 100644 --- a/examples/WebSocketLiveMode/WebSocketLiveMode.ino +++ b/examples/WebSocketLiveMode/WebSocketLiveMode.ino @@ -24,10 +24,6 @@ AsyncWebSocket ws("/"); // Servo object to send positions Servo myServo; -// LiveStream instance acting as a middleware between web socket and animation -// instance -BlenderServoAnimation::LiveStream liveStream; - // Callback function which is called whenever a servo needs to be moved void move(byte servoID, int position) { // Ignore the servoID (there is only one servo) and write the current position @@ -37,6 +33,10 @@ void move(byte servoID, int position) { // Animation object to represent the original Blender animation BlenderServoAnimation::Animation animation; +// AnimationData instance acting as a middleware between web socket and +// animation instance +BlenderServoAnimation::AnimationData liveStream; + // Handler function writing data to the live stream instance when receiving data void onWebSocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { @@ -71,11 +71,8 @@ void setup() { // Set the position callback animation.onPositionChange(move); - // Add a new scene with the LiveStream - we can omit fps and frames - animation.addScene(liveStream); - - // Trigger the animation play mode - animation.play(); + // Trigger the animation live mode + animation.live(liveStream); } void loop() { diff --git a/platformio.ini b/platformio.ini index 630e358..ca0300d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -3,6 +3,6 @@ platform = native test_build_src = yes build_flags = -Wno-deprecated-declarations -debug_test = test_servo_manager +debug_test = animation/test_pause lib_deps = ArduinoFake diff --git a/src/BlenderServoAnimation.h b/src/BlenderServoAnimation.h index 2c2d964..3f0f66f 100644 --- a/src/BlenderServoAnimation.h +++ b/src/BlenderServoAnimation.h @@ -1,4 +1,3 @@ #include "internal/Animation.h" -#include "internal/LiveStream.h" -#include "internal/Scene.h" +#include "internal/AnimationData.h" #include diff --git a/src/internal/Animation.cpp b/src/internal/Animation.cpp index 12187d6..8ae1398 100644 --- a/src/internal/Animation.cpp +++ b/src/internal/Animation.cpp @@ -1,5 +1,5 @@ #include "Animation.h" -#include "ProgmemStream.h" +#include "AnimationData.h" #include using namespace BlenderServoAnimation; @@ -10,6 +10,10 @@ Animation::~Animation() { delete this->scenes[i]; } } + + if (this->liveStream) { + delete this->liveStream; + } } int Animation::countScenes() { @@ -29,15 +33,14 @@ bool Animation::hasScene(byte index) { } void Animation::addScene(const byte *data, int size, byte fps, int frames) { - ProgmemStream *stream = new ProgmemStream(data, size); - Scene *scene = new Scene(this->servoManager, fps, frames); - scene->setProgmemData(stream); + AnimationData *animationData = new AnimationData(data, size); + Scene *scene = new Scene(&this->servoManager, animationData, fps, frames); this->registerScene(scene); } void Animation::addScene(Stream &data, byte fps, int frames) { - Scene *scene = new Scene(this->servoManager, fps, frames); - scene->setData(&data); + AnimationData *animationData = new AnimationData(&data); + Scene *scene = new Scene(&this->servoManager, animationData, fps, frames); this->registerScene(scene); } @@ -118,7 +121,8 @@ void Animation::loop() { } void Animation::pause() { - if (!this->scene || this->modeIsIn(4, MODE_DEFAULT, MODE_PAUSE, MODE_STOP)) { + if (!this->scene || + this->modeIsIn(4, MODE_DEFAULT, MODE_PAUSE, MODE_STOP, MODE_LIVE)) { return; } @@ -126,7 +130,7 @@ void Animation::pause() { } void Animation::stop() { - if (!this->scene || this->modeIsIn(2, MODE_DEFAULT, MODE_STOP)) { + if (this->modeIsIn(2, MODE_DEFAULT, MODE_STOP)) { return; } @@ -138,7 +142,7 @@ void Animation::live(Stream &stream) { return; } - this->liveStream = &stream; + this->liveStream = new AnimationData(&stream); this->changeMode(MODE_LIVE); } @@ -226,7 +230,7 @@ void Animation::handleStopMode(unsigned long currentMicros) { } void Animation::handleLiveMode() { - this->servoManager.parseStream(this->liveStream, false); + this->servoManager.parseData(this->liveStream, false); } Scene *Animation::getCurrentScene() { diff --git a/src/internal/Animation.h b/src/internal/Animation.h index bce5de2..b8af1b5 100644 --- a/src/internal/Animation.h +++ b/src/internal/Animation.h @@ -1,3 +1,4 @@ +#include "AnimationData.h" #include "Scene.h" #include "ServoManager.h" #include "typedefs.h" @@ -58,7 +59,7 @@ class Animation { Scene *scenes[MAX_SCENE_COUNT] = {nullptr}; Scene *scene = nullptr; - Stream *liveStream; + AnimationData *liveStream = nullptr; mcb modeCallback = nullptr; scb sceneCallback = nullptr; diff --git a/src/internal/AnimationData.cpp b/src/internal/AnimationData.cpp new file mode 100644 index 0000000..f9422b9 --- /dev/null +++ b/src/internal/AnimationData.cpp @@ -0,0 +1,62 @@ +#include "AnimationData.h" +#include + +using namespace BlenderServoAnimation; + +AnimationData::AnimationData() { +} + +AnimationData::AnimationData(const byte *data, int dataSize) { + this->data = data; + this->dataSize = dataSize; +} + +AnimationData::AnimationData(Stream *stream) { + this->stream = stream; +} + +bool AnimationData::isAvailable() { + if (this->stream) { + return this->stream->available() > 0; + } else if (this->data) { + return this->dataSize - this->dataPosition > 0; + } else { + return this->readIndex != this->writeIndex; + } +} + +byte AnimationData::getNextByte() { + if (this->stream) { + return this->stream->read(); + } else if (this->data) { + return this->readProgmem(); + } else { + return this->readBuffer(); + } +} + +byte AnimationData::readProgmem() { + if (this->dataPosition < this->dataSize) { + return pgm_read_byte(this->data + this->dataPosition++); + } else { + return -1; + } +} + +byte AnimationData::readBuffer() { + byte value = this->buffer[this->readIndex++]; + + if (this->readIndex >= BUFFER_SIZE) { + this->readIndex = 0; + } + + return value; +} + +void AnimationData::writeByte(byte value) { + this->buffer[this->writeIndex++] = value; + + if (this->writeIndex >= BUFFER_SIZE) { + this->writeIndex = 0; + } +} diff --git a/src/internal/AnimationData.h b/src/internal/AnimationData.h new file mode 100644 index 0000000..2ce81e7 --- /dev/null +++ b/src/internal/AnimationData.h @@ -0,0 +1,43 @@ +#include + +#ifndef BlenderServoAnimation_AnimationData_H +#define BlenderServoAnimation_AnimationData_H + +namespace BlenderServoAnimation { + +class AnimationData { + +public: + static const byte LINE_BREAK = 0xA; + + AnimationData(); + AnimationData(const byte *data, int dataSize); + AnimationData(Stream *stream); + + bool isAvailable(); + + byte getNextByte(); + + void writeByte(byte value); + +private: + static const byte BUFFER_SIZE = 64; + + int dataSize = 0; + int dataPosition = 0; + + const byte *data = nullptr; + + Stream *stream = nullptr; + + byte buffer[BUFFER_SIZE] = {0}; + byte writeIndex = 0; + byte readIndex = 0; + + byte readProgmem(); + byte readBuffer(); +}; + +} // namespace BlenderServoAnimation + +#endif \ No newline at end of file diff --git a/src/internal/LiveStream.cpp b/src/internal/LiveStream.cpp deleted file mode 100644 index 77f73bc..0000000 --- a/src/internal/LiveStream.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "LiveStream.h" -#include - -using namespace BlenderServoAnimation; - -int LiveStream::available() { - if (this->writeIndex >= this->readIndex) { - return this->writeIndex - this->readIndex; - } else { - return BUFFER_SIZE - this->readIndex + this->writeIndex; - } -} - -int LiveStream::peek() { - if (this->available()) { - return this->buffer[this->readIndex]; - } else { - return -1; - } -} - -int LiveStream::read() { - int value = this->buffer[this->readIndex++]; - - if (this->readIndex >= BUFFER_SIZE) { - this->readIndex = 0; - } - - return value; -} - -size_t LiveStream::write(uint8_t value) { - this->buffer[this->writeIndex++] = value; - - if (this->writeIndex >= BUFFER_SIZE) { - this->writeIndex = 0; - } - - return 1; -} - -void LiveStream::flush() { - for (int i = 0; i < BUFFER_SIZE; i++) { - this->buffer[i] = 0; - } - - this->readIndex = 0; - this->writeIndex = 0; -} diff --git a/src/internal/LiveStream.h b/src/internal/LiveStream.h deleted file mode 100644 index 9801b06..0000000 --- a/src/internal/LiveStream.h +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#ifndef BlenderServoAnimation_LiveStream_H -#define BlenderServoAnimation_LiveStream_H - -namespace BlenderServoAnimation { - -class LiveStream : public Stream { - -public: - int available(); - int read(); - int peek(); - - size_t write(uint8_t); - - void flush(); - -private: - static const byte BUFFER_SIZE = 64; - - byte buffer[BUFFER_SIZE] = {0}; - byte writeIndex = 0; - byte readIndex = 0; -}; - -} // namespace BlenderServoAnimation - -#endif \ No newline at end of file diff --git a/src/internal/ProgmemStream.cpp b/src/internal/ProgmemStream.cpp deleted file mode 100644 index e2826a9..0000000 --- a/src/internal/ProgmemStream.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "ProgmemStream.h" -#include - -using namespace BlenderServoAnimation; - -ProgmemStream::ProgmemStream(const byte *data, size_t size) { - this->data = data; - this->size = size; -} - -int ProgmemStream::read() { - if (this->position < this->size) { - return pgm_read_byte(this->data + this->position++); - } else { - return -1; - } -} - -int ProgmemStream::available() { - return size - position; -} - -int ProgmemStream::peek() { - if (position < size) { - return pgm_read_byte(this->data + this->position); - } else { - return -1; - } -} - -size_t ProgmemStream::write(uint8_t value) { - return 0; -} - -void ProgmemStream::flush() { - this->position = 0; -} diff --git a/src/internal/ProgmemStream.h b/src/internal/ProgmemStream.h deleted file mode 100644 index 8c2dfd5..0000000 --- a/src/internal/ProgmemStream.h +++ /dev/null @@ -1,30 +0,0 @@ -#include - -#ifndef BlenderServoAnimation_ProgmemStream_H -#define BlenderServoAnimation_ProgmemStream_H - -namespace BlenderServoAnimation { - -class ProgmemStream : public Stream { - -public: - ProgmemStream(const byte *data, size_t size); - - int available(); - int read(); - int peek(); - - size_t write(uint8_t); - - void flush(); - -private: - const byte *data = nullptr; - - size_t size = 0; - size_t position = 0; -}; - -} // namespace BlenderServoAnimation - -#endif \ No newline at end of file diff --git a/src/internal/Scene.cpp b/src/internal/Scene.cpp index 310b669..9e4ee34 100644 --- a/src/internal/Scene.cpp +++ b/src/internal/Scene.cpp @@ -1,13 +1,14 @@ #include "Scene.h" #include "Command.h" -#include "ProgmemStream.h" #include "Servo.h" #include using namespace BlenderServoAnimation; -Scene::Scene(ServoManager &servoManager, byte fps, int frames) { - this->servoManager = &servoManager; +Scene::Scene(ServoManager *servoManager, AnimationData *data, byte fps, + int frames) { + this->servoManager = servoManager; + this->data = data; this->fps = fps; this->frames = frames; this->frameMicros = round((float)Scene::SECOND_IN_MICROS / (float)fps); @@ -15,24 +16,14 @@ Scene::Scene(ServoManager &servoManager, byte fps, int frames) { } Scene::~Scene() { - if (this->progmemData) { - delete this->progmemData; + if (this->data) { + delete this->data; } } -void Scene::setData(Stream *data) { - this->data = data; -} - -void Scene::setProgmemData(ProgmemStream *data) { - this->progmemData = data; -} - void Scene::play(unsigned long currentMicros) { - Stream *data = this->getAnimationData(); - if (this->frames == 0) { - this->servoManager->parseStream(data); + this->servoManager->parseData(this->data); return; } @@ -52,7 +43,7 @@ void Scene::play(unsigned long currentMicros) { this->lastMicros += this->diffPerSecond; } - this->servoManager->parseStream(data); + this->servoManager->parseData(this->data); } void Scene::stop(unsigned long currentMicros) { @@ -96,11 +87,3 @@ int Scene::getFrame() { int Scene::getFrames() { return this->frames; } - -Stream *Scene::getAnimationData() { - if (this->progmemData) { - return this->progmemData; - } - - return this->data; -} diff --git a/src/internal/Scene.h b/src/internal/Scene.h index 42ef220..73d5c2c 100644 --- a/src/internal/Scene.h +++ b/src/internal/Scene.h @@ -1,4 +1,4 @@ -#include "ProgmemStream.h" +#include "AnimationData.h" #include "ServoManager.h" #include @@ -10,11 +10,9 @@ namespace BlenderServoAnimation { class Scene { public: - Scene(ServoManager &servoManager, byte fps, int frames); + Scene(ServoManager *servoManager, AnimationData *data, byte fps, int frames); ~Scene(); - void setData(Stream *data); - void setProgmemData(ProgmemStream *data); void play(unsigned long currentMicros); void stop(unsigned long currentMicros); @@ -40,17 +38,13 @@ class Scene { unsigned long lastMicros = 0; - ServoManager *servoManager; + ServoManager *servoManager = nullptr; - Stream *data = nullptr; - - ProgmemStream *progmemData = nullptr; + AnimationData *data = nullptr; bool isNewFrame(unsigned long currentMicros); unsigned int getMicrosDiff(unsigned long currentMicros); - - Stream *getAnimationData(); }; } // namespace BlenderServoAnimation diff --git a/src/internal/ServoManager.cpp b/src/internal/ServoManager.cpp index 5f37227..874f75a 100644 --- a/src/internal/ServoManager.cpp +++ b/src/internal/ServoManager.cpp @@ -34,15 +34,15 @@ void ServoManager::setThreshold(byte servoId, byte value) { } } -void ServoManager::parseStream(Stream *stream, bool considerLineBreaks) { - if (!stream || !this->hasPositionCallback()) { +void ServoManager::parseData(AnimationData *data, bool considerLineBreaks) { + if (!data || !this->hasPositionCallback()) { return; } Command command; - while (stream->available() > 0) { - byte value = stream->read(); + while (data->isAvailable()) { + byte value = data->getNextByte(); if (considerLineBreaks && value == Command::LINE_BREAK) { break; diff --git a/src/internal/ServoManager.h b/src/internal/ServoManager.h index 816a69a..bb35fcc 100644 --- a/src/internal/ServoManager.h +++ b/src/internal/ServoManager.h @@ -1,3 +1,4 @@ +#include "AnimationData.h" #include "Command.h" #include "Servo.h" #include "typedefs.h" @@ -16,7 +17,7 @@ class ServoManager { void setPositionCallback(pcb positionCallback); void setDefaultThreshold(byte value); void setThreshold(byte servoId, byte value); - void parseStream(Stream *stream, bool considerLineBreaks = true); + void parseData(AnimationData *data, bool considerLineBreaks = true); void moveAllTowardsNeutral(); bool hasPositionCallback(); diff --git a/test/animation/test_live/test_live.cpp b/test/animation/test_live/test_live.cpp index 9c9eacc..5d17be3 100644 --- a/test/animation/test_live/test_live.cpp +++ b/test/animation/test_live/test_live.cpp @@ -11,7 +11,7 @@ void setUp(void) { void test_prevented(void) { Animation animation; - Serial_ mock; + StreamMock mock; animation.addScene(mock); When(OverloadedMethod(ArduinoFake(), random, long(long))).Return(0); @@ -46,7 +46,7 @@ void test_prevented(void) { } void test_allowed(void) { - Serial_ mock; + StreamMock mock; Animation animation; animation.addScene(mock); diff --git a/test/animation/test_loop/test_loop.cpp b/test/animation/test_loop/test_loop.cpp index 2d5694e..e43e028 100644 --- a/test/animation/test_loop/test_loop.cpp +++ b/test/animation/test_loop/test_loop.cpp @@ -1,6 +1,5 @@ #include "../test/helper.h" #include "internal/Animation.h" -#include "internal/LiveStream.h" #include using namespace BlenderServoAnimation; @@ -51,10 +50,10 @@ void test_without_scenes(void) { } void test_prevented(void) { - LiveStream stream; + StreamMock mock; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); When(OverloadedMethod(ArduinoFake(), random, long(long))).Return(0); @@ -76,13 +75,17 @@ void test_prevented(void) { TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); animation.loop(); TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); + animation.run(10000); + animation.live(mock); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); + animation.loop(); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); } void test_allowed(void) { - LiveStream stream; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, animation.getMode()); animation.loop(); diff --git a/test/animation/test_mode_callback/test_mode_callback.cpp b/test/animation/test_mode_callback/test_mode_callback.cpp index 3648d54..0e1fc25 100644 --- a/test/animation/test_mode_callback/test_mode_callback.cpp +++ b/test/animation/test_mode_callback/test_mode_callback.cpp @@ -1,6 +1,5 @@ #include "../test/helper.h" #include "internal/Animation.h" -#include "internal/LiveStream.h" #include @@ -20,12 +19,11 @@ void onModeChange(byte prevArg, byte newArg) { } void test_different_mode(void) { - LiveStream stream; Animation animation; animation.onPositionChange(move); animation.onModeChange(onModeChange); - animation.addScene(stream, FPS, FRAMES); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); TEST_ASSERT_EQUAL(-1, prevMode); TEST_ASSERT_EQUAL(-1, newMode); @@ -39,11 +37,10 @@ void test_different_mode(void) { } void test_same_mode(void) { - LiveStream stream; Animation animation; animation.onPositionChange(move); animation.onModeChange(onModeChange); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); animation.loop(); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, prevMode); @@ -54,11 +51,11 @@ void test_same_mode(void) { } void test_all_modes(void) { - LiveStream stream; + StreamMock mock; Animation animation; animation.onPositionChange(move); animation.onModeChange(onModeChange); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); animation.play(); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, prevMode); @@ -86,6 +83,14 @@ void test_all_modes(void) { TEST_ASSERT_EQUAL(Animation::MODE_LOOP, prevMode); TEST_ASSERT_EQUAL(Animation::MODE_STOP, newMode); TEST_ASSERT_EQUAL(0, animation.getPlayIndex()); + animation.run(10000); + TEST_ASSERT_EQUAL(Animation::MODE_STOP, prevMode); + TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, newMode); + TEST_ASSERT_EQUAL(0, animation.getPlayIndex()); + animation.live(mock); + TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, prevMode); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, newMode); + TEST_ASSERT_EQUAL(0, animation.getPlayIndex()); } int main(int argc, char **argv) { diff --git a/test/animation/test_pause/test_pause.cpp b/test/animation/test_pause/test_pause.cpp index f720fb0..bc1297f 100644 --- a/test/animation/test_pause/test_pause.cpp +++ b/test/animation/test_pause/test_pause.cpp @@ -1,6 +1,5 @@ #include "../test/helper.h" #include "internal/Animation.h" -#include "internal/LiveStream.h" #include using namespace BlenderServoAnimation; @@ -91,10 +90,10 @@ void test_pause_play_random(void) { } void test_prevented(void) { - LiveStream stream; + StreamMock mock; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, animation.getMode()); animation.pause(); @@ -104,13 +103,17 @@ void test_prevented(void) { TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); animation.pause(); TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); + animation.run(10000); + animation.live(mock); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); + animation.pause(); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); } void test_allowed(void) { - LiveStream stream; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); animation.play(); TEST_ASSERT_EQUAL(Animation::MODE_PLAY, animation.getMode()); diff --git a/test/animation/test_play/test_play.cpp b/test/animation/test_play/test_play.cpp index 5fb69e6..7622fa9 100644 --- a/test/animation/test_play/test_play.cpp +++ b/test/animation/test_play/test_play.cpp @@ -49,6 +49,7 @@ void test_without_scenes(void) { } void test_prevented(void) { + StreamMock mock; Animation animation; animation.onPositionChange(move); animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); @@ -73,6 +74,11 @@ void test_prevented(void) { TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); animation.play(); TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); + animation.run(10000); + animation.live(mock); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); + animation.play(); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); } void test_allowed(void) { diff --git a/test/animation/test_play_random/test_play_random.cpp b/test/animation/test_play_random/test_play_random.cpp index 314f003..90c9b89 100644 --- a/test/animation/test_play_random/test_play_random.cpp +++ b/test/animation/test_play_random/test_play_random.cpp @@ -1,6 +1,5 @@ #include "../test/helper.h" #include "internal/Animation.h" -#include "internal/LiveStream.h" #include using namespace BlenderServoAnimation; @@ -53,10 +52,10 @@ void test_without_scenes(void) { } void test_prevented(void) { - LiveStream stream; + StreamMock mock; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); animation.loop(); TEST_ASSERT_EQUAL(Animation::MODE_LOOP, animation.getMode()); @@ -76,13 +75,17 @@ void test_prevented(void) { TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); animation.playRandom(); TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); + animation.run(10000); + animation.live(mock); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); + animation.playRandom(); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); } void test_allowed(void) { - LiveStream stream; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, animation.getMode()); animation.playRandom(); diff --git a/test/animation/test_play_single/test_play_single.cpp b/test/animation/test_play_single/test_play_single.cpp index 3a6c07d..05f9006 100644 --- a/test/animation/test_play_single/test_play_single.cpp +++ b/test/animation/test_play_single/test_play_single.cpp @@ -1,6 +1,5 @@ #include "../test/helper.h" #include "internal/Animation.h" -#include "internal/LiveStream.h" #include using namespace BlenderServoAnimation; @@ -12,7 +11,6 @@ void setUp(void) { } void test_play_single(void) { - LiveStream stream; Animation animation; animation.onPositionChange(move); animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); @@ -43,10 +41,10 @@ void test_without_scenes(void) { } void test_prevented(void) { - LiveStream stream; + StreamMock mock; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); When(OverloadedMethod(ArduinoFake(), random, long(long))).Return(0); @@ -68,13 +66,17 @@ void test_prevented(void) { TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); animation.playSingle(0); TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); + animation.run(10000); + animation.live(mock); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); + animation.playSingle(0); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); } void test_allowed(void) { - LiveStream stream; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, animation.getMode()); animation.playSingle(0); diff --git a/test/animation/test_stop/test_stop.cpp b/test/animation/test_stop/test_stop.cpp index b750ec8..6b29a56 100644 --- a/test/animation/test_stop/test_stop.cpp +++ b/test/animation/test_stop/test_stop.cpp @@ -1,7 +1,5 @@ #include "../test/helper.h" #include "internal/Animation.h" -#include "internal/LiveStream.h" -#include "internal/ProgmemStream.h" #include "internal/Scene.h" #include @@ -14,10 +12,11 @@ void setUp(void) { } void test_stop(byte mode) { - LiveStream stream; + StreamMock mock; + mock.availableValue = 0; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, animation.getMode()); @@ -34,6 +33,9 @@ void test_stop(byte mode) { case Animation::MODE_LOOP: animation.loop(); break; + case Animation::MODE_LIVE: + animation.live(mock); + break; } TEST_ASSERT_EQUAL(mode, animation.getMode()); @@ -42,6 +44,10 @@ void test_stop(byte mode) { animation.run(i); } + if (mode != Animation::MODE_LIVE) { + TEST_ASSERT_EQUAL(2, animation.getCurrentScene()->getFrame()); + } + animation.stop(); TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); @@ -70,11 +76,14 @@ void test_stop_play_random(void) { test_stop(Animation::MODE_PLAY_RANDOM); } +void test_stop_live(void) { + test_stop(Animation::MODE_LIVE); +} + void test_prevented(void) { - LiveStream stream; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); TEST_ASSERT_EQUAL(Animation::MODE_DEFAULT, animation.getMode()); animation.stop(); @@ -82,10 +91,10 @@ void test_prevented(void) { } void test_allowed(void) { - LiveStream stream; + StreamMock mock; Animation animation; animation.onPositionChange(move); - animation.addScene(stream, FPS, FRAMES); + animation.addScene(PROGMEM_DATA, DATA_SIZE, FPS, FRAMES); animation.play(); TEST_ASSERT_EQUAL(Animation::MODE_PLAY, animation.getMode()); @@ -106,6 +115,11 @@ void test_allowed(void) { TEST_ASSERT_EQUAL(Animation::MODE_LOOP, animation.getMode()); animation.stop(); TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); + animation.run(10000); + animation.live(mock); + TEST_ASSERT_EQUAL(Animation::MODE_LIVE, animation.getMode()); + animation.stop(); + TEST_ASSERT_EQUAL(Animation::MODE_STOP, animation.getMode()); } int main(int argc, char **argv) { @@ -114,6 +128,7 @@ int main(int argc, char **argv) { RUN_TEST(test_stop_play_single); RUN_TEST(test_stop_play_random); RUN_TEST(test_stop_loop); + RUN_TEST(test_stop_live); RUN_TEST(test_prevented); RUN_TEST(test_allowed); UNITY_END(); diff --git a/test/helper.h b/test/helper.h index 00f63ca..0c673f2 100644 --- a/test/helper.h +++ b/test/helper.h @@ -38,3 +38,27 @@ const byte PROGMEM PROGMEM_DATA[DATA_SIZE] = { 1, 1, 123, 62, 10, 60, 0, 1, 124, 62, 60, 1, 1, 127, 62, 10, 60, 0, 1, 128, 62, 60, 1, 1, 132, 62, 10, }; + +class StreamMock : public Stream { +public: + int availableValue = 1; + + int available() { + return this->availableValue; + } + + int read() { + return 123; + } + + int peek() { + return 1; + } + + void flush() { + } + + size_t write(uint8_t) { + return 1; + } +}; diff --git a/test/test_animation_data/test_animation_data.cpp b/test/test_animation_data/test_animation_data.cpp new file mode 100644 index 0000000..3f6deb4 --- /dev/null +++ b/test/test_animation_data/test_animation_data.cpp @@ -0,0 +1,50 @@ +#include "../test/helper.h" +#include "internal/AnimationData.h" +#include + +using namespace BlenderServoAnimation; + +const byte PROGMEM values[5] = {60, 3, 1, 119, 62}; + +void test_progmem_data(void) { + AnimationData data(values, 5); + TEST_ASSERT_TRUE(data.isAvailable()); + + for (byte i = 0; i < 5; i++) { + TEST_ASSERT_EQUAL(values[i], data.getNextByte()); + } + + TEST_ASSERT_FALSE(data.isAvailable()); +} + +void test_stream_data(void) { + StreamMock stream; + AnimationData data(&stream); + TEST_ASSERT_TRUE(data.isAvailable()); + TEST_ASSERT_EQUAL(123, data.getNextByte()); +} + +void test_buffer_data(void) { + AnimationData data; + TEST_ASSERT_FALSE(data.isAvailable()); + + for (byte i = 0; i < 5; i++) { + data.writeByte(values[i]); + } + + TEST_ASSERT_TRUE(data.isAvailable()); + + for (byte i = 0; i < 5; i++) { + TEST_ASSERT_EQUAL(values[i], data.getNextByte()); + } + + TEST_ASSERT_FALSE(data.isAvailable()); +} + +int main(int argc, char **argv) { + UNITY_BEGIN(); + RUN_TEST(test_progmem_data); + RUN_TEST(test_stream_data); + RUN_TEST(test_buffer_data); + UNITY_END(); +} diff --git a/test/test_live_stream/test_live_stream.cpp b/test/test_live_stream/test_live_stream.cpp deleted file mode 100644 index 50557a3..0000000 --- a/test/test_live_stream/test_live_stream.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "internal/LiveStream.h" -#include - -using namespace BlenderServoAnimation; - -void test_read_write(void) { - LiveStream stream; - - TEST_ASSERT_FALSE(stream.available()); - - for (int i = 0; i < 200; i += 20) { - for (int x = i; x < i + 20; x++) { - TEST_ASSERT_EQUAL(1, stream.write(x)); - } - - TEST_ASSERT_EQUAL(20, stream.available()); - TEST_ASSERT_EQUAL(i, stream.peek()); - - for (int x = i; x < i + 20; x++) { - TEST_ASSERT_EQUAL(x, stream.read()); - } - } - - TEST_ASSERT_EQUAL(0, stream.available()); - TEST_ASSERT_EQUAL(-1, stream.peek()); -} - -void test_flush(void) { - byte values[5] = {60, 3, 1, 119, 62}; - LiveStream stream; - - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(1, stream.write(values[i])); - } - - stream.flush(); - - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, stream.read()); - } -} - -int main(int argc, char **argv) { - UNITY_BEGIN(); - RUN_TEST(test_read_write); - RUN_TEST(test_flush); - UNITY_END(); -} \ No newline at end of file diff --git a/test/test_progmem_stream/test_progmem_stream.cpp b/test/test_progmem_stream/test_progmem_stream.cpp deleted file mode 100644 index 752b327..0000000 --- a/test/test_progmem_stream/test_progmem_stream.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "internal/ProgmemStream.h" -#include - -using namespace BlenderServoAnimation; - -const byte PROGMEM values[5] = {60, 3, 1, 119, 62}; - -void test_read(void) { - ProgmemStream stream(values, 5); - - TEST_ASSERT_EQUAL(5, stream.available()); - TEST_ASSERT_EQUAL(60, stream.peek()); - - byte exp[5] = {60, 3, 1, 119, 62}; - - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(exp[i], stream.read()); - } - - TEST_ASSERT_EQUAL(0, stream.available()); - TEST_ASSERT_EQUAL(-1, stream.peek()); -} - -int main(int argc, char **argv) { - UNITY_BEGIN(); - RUN_TEST(test_read); - UNITY_END(); -} \ No newline at end of file diff --git a/test/test_scene/test_scene.cpp b/test/test_scene/test_scene.cpp index 201baa0..43d8c59 100644 --- a/test/test_scene/test_scene.cpp +++ b/test/test_scene/test_scene.cpp @@ -1,5 +1,5 @@ #include "../test/helper.h" -#include "internal/ProgmemStream.h" +#include "internal/AnimationData.h" #include "internal/Scene.h" #include @@ -12,9 +12,8 @@ void setUp(void) { void test_play_with_frames(void) { ServoManager servoManager; servoManager.setPositionCallback(move); - ProgmemStream *stream = new ProgmemStream(PROGMEM_DATA, DATA_SIZE); - Scene scene(servoManager, FPS, FRAMES); - scene.setProgmemData(stream); + AnimationData *data = new AnimationData(PROGMEM_DATA, DATA_SIZE); + Scene scene(&servoManager, data, FPS, FRAMES); positionLog exp[10] = { {0, 375}, {1, 375}, {0, 376}, {1, 376}, {0, 377}, @@ -37,9 +36,8 @@ void test_stop(void) { ServoManager servoManager; servoManager.setPositionCallback(move); servoManager.setDefaultThreshold(20); - ProgmemStream *stream = new ProgmemStream(PROGMEM_DATA, DATA_SIZE); - Scene scene(servoManager, FPS, FRAMES); - scene.setProgmemData(stream); + AnimationData *data = new AnimationData(PROGMEM_DATA, DATA_SIZE); + Scene scene(&servoManager, data, FPS, FRAMES); positionLog exp[15] = { {0, 375}, {1, 375}, {0, 376}, {1, 376}, {0, 377}, @@ -70,9 +68,8 @@ void test_stop(void) { void test_has_finished(void) { ServoManager servoManager; - ProgmemStream *stream = new ProgmemStream(PROGMEM_DATA, DATA_SIZE); - Scene scene(servoManager, FPS, FRAMES); - scene.setProgmemData(stream); + AnimationData *data = new AnimationData(PROGMEM_DATA, DATA_SIZE); + Scene scene(&servoManager, data, FPS, FRAMES); TEST_ASSERT_FALSE(scene.hasFinished()); @@ -89,9 +86,8 @@ void test_has_finished(void) { void test_get_frame(void) { ServoManager servoManager; - ProgmemStream *stream = new ProgmemStream(PROGMEM_DATA, DATA_SIZE); - Scene scene(servoManager, FPS, FRAMES); - scene.setProgmemData(stream); + AnimationData *data = new AnimationData(PROGMEM_DATA, DATA_SIZE); + Scene scene(&servoManager, data, FPS, FRAMES); TEST_ASSERT_EQUAL(0, scene.getFrame()); diff --git a/test/test_servo_manager/test_servo_manager.cpp b/test/test_servo_manager/test_servo_manager.cpp index bd1e309..efaedd6 100644 --- a/test/test_servo_manager/test_servo_manager.cpp +++ b/test/test_servo_manager/test_servo_manager.cpp @@ -1,5 +1,5 @@ #include "../test/helper.h" -#include "internal/ProgmemStream.h" +#include "internal/AnimationData.h" #include "internal/ServoManager.h" #include @@ -9,14 +9,14 @@ void setUp(void) { resetPositionLog(); } -void test_parse_stream(void) { - ProgmemStream stream(PROGMEM_DATA, DATA_SIZE); +void test_parse_data(void) { + AnimationData data(PROGMEM_DATA, DATA_SIZE); ServoManager servoManager; servoManager.setPositionCallback(move); TEST_ASSERT_EQUAL(0, logIndex); - servoManager.parseStream(&stream); + servoManager.parseData(&data); TEST_ASSERT_EQUAL(2, logIndex); TEST_ASSERT_EQUAL(0, positions[0].servoId); @@ -25,20 +25,20 @@ void test_parse_stream(void) { TEST_ASSERT_EQUAL(375, positions[1].position); } -void test_parse_stream_without_line_breaks(void) { - ProgmemStream stream(PROGMEM_DATA, DATA_SIZE); +void test_parse_data_without_line_breaks(void) { + AnimationData data(PROGMEM_DATA, DATA_SIZE); ServoManager servoManager; servoManager.setPositionCallback(move); TEST_ASSERT_EQUAL(0, logIndex); - servoManager.parseStream(&stream, false); + servoManager.parseData(&data, false); TEST_ASSERT_EQUAL(10, logIndex); } void test_move_all_towards_neutral(void) { - ProgmemStream stream(PROGMEM_DATA, DATA_SIZE); + AnimationData data(PROGMEM_DATA, DATA_SIZE); ServoManager servoManager; servoManager.setPositionCallback(move); servoManager.setDefaultThreshold(20); @@ -46,9 +46,9 @@ void test_move_all_towards_neutral(void) { TEST_ASSERT_EQUAL(0, logIndex); - servoManager.parseStream(&stream); - servoManager.parseStream(&stream); - servoManager.parseStream(&stream); + servoManager.parseData(&data); + servoManager.parseData(&data); + servoManager.parseData(&data); TEST_ASSERT_EQUAL(6, logIndex); TEST_ASSERT_FALSE(servoManager.servosAreAllNeutral()); @@ -66,8 +66,8 @@ void test_move_all_towards_neutral(void) { int main(int argc, char **argv) { UNITY_BEGIN(); - RUN_TEST(test_parse_stream); - RUN_TEST(test_parse_stream_without_line_breaks); + RUN_TEST(test_parse_data); + RUN_TEST(test_parse_data_without_line_breaks); RUN_TEST(test_move_all_towards_neutral); UNITY_END(); } \ No newline at end of file