parent
e53dfc4cc5
commit
4c88fcc4a5
@ -0,0 +1,79 @@ |
|||||||
|
#include "audio_element_handle.hpp" |
||||||
|
#include "audio_element.hpp" |
||||||
|
#include "freertos/projdefs.h" |
||||||
|
|
||||||
|
namespace audio { |
||||||
|
|
||||||
|
AudioElementHandle::AudioElementHandle(std::unique_ptr<TaskHandle_t> task, |
||||||
|
std::shared_ptr<IAudioElement> element) |
||||||
|
: task_(std::move(task)), element_(std::move(element)) {} |
||||||
|
|
||||||
|
AudioElementHandle::~AudioElementHandle() { |
||||||
|
Quit(); |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioElementHandle::CurrentState() -> ElementState { |
||||||
|
return element_->ElementState(); |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioElementHandle::PlayPause(enum PlayPause state) -> void { |
||||||
|
ElementState s = CurrentState(); |
||||||
|
if (state == PLAY && s == STATE_PAUSE) { |
||||||
|
// Ensure we actually finished any previous pause command.
|
||||||
|
// TODO: really?
|
||||||
|
PauseSync(); |
||||||
|
SetStateAndWakeUp(STATE_RUN); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (state == PAUSE && s == STATE_RUN) { |
||||||
|
element_->ElementState(STATE_PAUSE); |
||||||
|
SetStateAndWakeUp(STATE_PAUSE); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioElementHandle::Quit() -> void { |
||||||
|
SetStateAndWakeUp(STATE_QUIT); |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioElementHandle::PauseSync() -> void { |
||||||
|
PlayPause(PAUSE); |
||||||
|
MonitorUtilState(eSuspended); |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioElementHandle::QuitSync() -> void { |
||||||
|
Quit(); |
||||||
|
MonitorUtilState(eDeleted); |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioElementHandle::MonitorUtilState(eTaskState desired) -> void { |
||||||
|
while (eTaskGetState(task_.get()) != desired) { |
||||||
|
WakeUpTask(); |
||||||
|
vTaskDelay(pdMS_TO_TICKS(1)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioElementHandle::SetStateAndWakeUp(ElementState state) -> void { |
||||||
|
element_->ElementState(state); |
||||||
|
WakeUpTask(); |
||||||
|
} |
||||||
|
|
||||||
|
auto AudioElementHandle::WakeUpTask() -> void { |
||||||
|
// TODO: various races where the task isn't blocked yet, but there is a block
|
||||||
|
// between now and its next element state check. Also think about chunk blocks
|
||||||
|
// nested in element bodies.
|
||||||
|
// Maybe we need a big mutex or semaphore somewhere in here.
|
||||||
|
switch (eTaskGetState(task_.get())) { |
||||||
|
case eBlocked: |
||||||
|
// TODO: when is this safe?
|
||||||
|
xTaskAbortDelay(task_.get()); |
||||||
|
break; |
||||||
|
case eSuspended: |
||||||
|
vTaskResume(task_.get()); |
||||||
|
break; |
||||||
|
default: |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace audio
|
@ -0,0 +1,41 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <memory> |
||||||
|
#include "audio_element.hpp" |
||||||
|
|
||||||
|
namespace audio { |
||||||
|
|
||||||
|
class AudioElementHandle { |
||||||
|
public: |
||||||
|
AudioElementHandle(std::unique_ptr<TaskHandle_t> task, |
||||||
|
std::shared_ptr<IAudioElement> element); |
||||||
|
~AudioElementHandle(); |
||||||
|
|
||||||
|
auto CurrentState() -> ElementState; |
||||||
|
|
||||||
|
// TODO: think about this contract. Would it ever make sense to pause and
|
||||||
|
// then walk away? Things could keep running for a whole loop if data comes
|
||||||
|
// through, so probably not?
|
||||||
|
enum PlayPause { |
||||||
|
PLAY, |
||||||
|
PAUSE, |
||||||
|
}; |
||||||
|
auto PlayPause(PlayPause state) -> void; |
||||||
|
auto Quit() -> void; |
||||||
|
|
||||||
|
auto PauseSync() -> void; |
||||||
|
auto QuitSync() -> void; |
||||||
|
|
||||||
|
AudioElementHandle(const AudioElementHandle&) = delete; |
||||||
|
AudioElementHandle& operator=(const AudioElementHandle&) = delete; |
||||||
|
|
||||||
|
private: |
||||||
|
std::unique_ptr<TaskHandle_t> task_; |
||||||
|
std::shared_ptr<IAudioElement> element_; |
||||||
|
|
||||||
|
auto MonitorUtilState(eTaskState desired) -> void; |
||||||
|
auto SetStateAndWakeUp(ElementState state) -> void; |
||||||
|
auto WakeUpTask() -> void; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace audio
|
Loading…
Reference in new issue