diff --git a/libs/audio/include/psemek/audio/stream.hpp b/libs/audio/include/psemek/audio/stream.hpp index e78ae218..e76b2d8c 100644 --- a/libs/audio/include/psemek/audio/stream.hpp +++ b/libs/audio/include/psemek/audio/stream.hpp @@ -2,6 +2,8 @@ #include +#include + #include namespace psemek::audio @@ -22,6 +24,8 @@ namespace psemek::audio virtual void stop() = 0; virtual bool is_playing() const = 0; + virtual void on_stop(util::function callback) = 0; + virtual ~stream() {} }; diff --git a/libs/audio/source/engine.cpp b/libs/audio/source/engine.cpp index 1c23dcca..52e8bad6 100644 --- a/libs/audio/source/engine.cpp +++ b/libs/audio/source/engine.cpp @@ -85,6 +85,8 @@ namespace psemek::audio std::vector> effects; + util::function callback; + stream_impl(int channel, std::shared_ptr track, bool loop, spec_t spec) : channel(channel) , track(track) @@ -152,6 +154,11 @@ namespace psemek::audio { return playing; } + + void on_stop(util::function callback) override + { + this->callback = std::move(callback); + } }; } @@ -268,9 +275,19 @@ namespace psemek::audio } if (!self) return; - std::lock_guard lock{self->channels_mutex}; - self->channels[ch].stream->playing = false; - self->channels[ch].stream = nullptr; + util::function callback; + { + // callback will probably lock something as well, + // leading to a deadlock, so we have to call the + // callback outside of the lock + std::lock_guard lock{self->channels_mutex}; + self->channels[ch].stream->playing = false; + callback = std::move(self->channels[ch].stream->callback); + self->channels[ch].stream = nullptr; + } + + if (callback) + callback(); } engine::engine()