simplify code of Audio/Context

This commit is contained in:
falsycat 2022-11-04 14:29:48 +09:00
parent c5337f69c2
commit beb67589ef
3 changed files with 20 additions and 44 deletions

View File

@ -22,7 +22,6 @@ class Queue : public nf7::File::Interface {
Queue& operator=(Queue&&) = delete;
// thread-safe
// WARNING: when failed to create ma_context, nullptr is passed
virtual void Push(const std::shared_ptr<nf7::Context>&, Task&&) noexcept = 0;
virtual std::shared_ptr<Queue> self() noexcept = 0;

View File

@ -59,7 +59,6 @@ class Thread final : public nf7::Context,
auto self = shared_from_this();
if (auto p = q_.Pop()) {
k.unlock();
env_->ExecAsync(p->first, [this, self, t = std::move(p->second)]() mutable {
runner_(std::move(t));
++tasks_done_;
@ -67,8 +66,7 @@ class Thread final : public nf7::Context,
});
} else if (auto time = q_.next()) {
working_ = false;
env_->ExecAsync(
shared_from_this(), [this, self]() mutable { HandleNext(); }, *time);
env_->ExecAsync(self, [this]() mutable { HandleNext(); }, *time);
} else {
working_ = false;
}

View File

@ -2,6 +2,7 @@
#include <atomic>
#include <cinttypes>
#include <memory>
#include <typeinfo>
#include <imgui.h>
#include <miniaudio.h>
@ -10,7 +11,6 @@
#include "common/audio_queue.hh"
#include "common/dir_item.hh"
#include "common/generic_context.hh"
#include "common/generic_type_info.hh"
#include "common/ptr_selector.hh"
#include "common/thread.hh"
@ -67,74 +67,58 @@ class AudioContext final : public nf7::File, public nf7::DirItem {
class AudioContext::Queue final : public nf7::audio::Queue,
public std::enable_shared_from_this<AudioContext::Queue> {
public:
enum State {
kInitial,
kReady,
kBroken,
};
struct ThreadData {
struct SharedData {
public:
std::atomic<State> state = kInitial;
ma_context ctx;
std::atomic<bool> broken = false;
ma_context ctx;
};
struct Runner {
public:
Runner(const std::shared_ptr<ThreadData>& tdata) noexcept : tdata_(tdata) {
Runner(const std::shared_ptr<SharedData>& d) noexcept : data_(d) {
}
void operator()(Task&& t) {
if (tdata_->state != kBroken) {
t(&tdata_->ctx);
if (!data_->broken) {
t(&data_->ctx);
}
}
private:
std::shared_ptr<ThreadData> tdata_;
std::shared_ptr<SharedData> data_;
};
using Thread = nf7::Thread<Runner, Task>;
Queue() = delete;
Queue(AudioContext& f) noexcept :
env_(&f.env()),
tdata_(std::make_shared<ThreadData>()),
th_(std::make_shared<Thread>(f, Runner {tdata_})) {
auto ctx = std::make_shared<nf7::GenericContext>(f.env(), 0, "creating ma_context");
th_->Push(ctx, [tdata = tdata_](auto) {
if (MA_SUCCESS == ma_context_init(nullptr, 0, nullptr, &tdata->ctx)) {
tdata->state = kReady;
} else {
tdata->state = kBroken;
data_(std::make_shared<SharedData>()),
th_(std::make_shared<Thread>(f, Runner {data_})) {
th_->Push(th_, [data = data_](auto) {
if (MA_SUCCESS != ma_context_init(nullptr, 0, nullptr, &data->ctx)) {
data->broken = true;
}
});
}
~Queue() noexcept {
th_->Push(
std::make_shared<nf7::GenericContext>(*env_, 0, "deleting ma_context"),
[](auto ma) { ma_context_uninit(ma); }
);
th_->Push(th_, [](auto ma) { ma_context_uninit(ma); });
}
Queue(const Queue&) = delete;
Queue(Queue&&) = delete;
Queue& operator=(const Queue&) = delete;
Queue& operator=(Queue&&) = delete;
void Push(const std::shared_ptr<nf7::Context>& ctx, Task&& task) noexcept override {
th_->Push(ctx, std::move(task));
}
std::shared_ptr<audio::Queue> self() noexcept override { return shared_from_this(); }
State state() const noexcept { return tdata_->state; }
bool broken() const noexcept { return data_->broken; }
size_t tasksDone() const noexcept { return th_->tasksDone(); }
// thread-safe
ma_context* ctx() const noexcept {
return state() == kReady? &tdata_->ctx: nullptr;
return broken()? nullptr: &data_->ctx;
}
private:
Env* const env_;
std::shared_ptr<ThreadData> tdata_;
std::shared_ptr<Thread> th_;
std::shared_ptr<SharedData> data_;
std::shared_ptr<Thread> th_;
};
@ -203,12 +187,7 @@ void AudioContext::UpdateDeviceListMenu(ma_device_info* ptr, ma_uint32 n) noexce
}
void AudioContext::UpdateTooltip() noexcept {
const auto state = q_->state();
const char* state_str =
state == Queue::kInitial? "initializing":
state == Queue::kReady ? "ready":
state == Queue::kBroken ? "broken": "unknown";
ImGui::Text("state: %s", state_str);
ImGui::Text("state: %s", q_->broken()? "broken": "running");
}
}