2015-05-24 06:55:12 +02:00
|
|
|
// Copyright 2015 Dolphin Emulator Project
|
2021-07-05 03:22:19 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2015-01-31 11:38:23 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <condition_variable>
|
2025-03-06 21:14:38 -06:00
|
|
|
#include <functional>
|
|
|
|
#include <future>
|
2015-01-31 11:38:23 +01:00
|
|
|
#include <mutex>
|
|
|
|
#include <queue>
|
|
|
|
|
2016-08-05 16:04:39 +02:00
|
|
|
#include "Common/Flag.h"
|
2015-01-31 11:38:23 +01:00
|
|
|
|
2015-05-01 18:58:11 +02:00
|
|
|
struct EfbPokeData;
|
2019-06-29 18:35:12 +10:00
|
|
|
class PointerWrap;
|
2015-05-01 18:58:11 +02:00
|
|
|
|
2015-01-31 11:38:23 +01:00
|
|
|
class AsyncRequests
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
AsyncRequests();
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2015-01-31 11:38:23 +01:00
|
|
|
void PullEvents()
|
|
|
|
{
|
2016-08-05 16:04:39 +02:00
|
|
|
if (!m_empty.IsSet())
|
2015-01-31 11:38:23 +01:00
|
|
|
PullEventsInternal();
|
|
|
|
}
|
2020-04-07 19:37:32 +02:00
|
|
|
void WaitForEmptyQueue();
|
2015-01-31 11:38:23 +01:00
|
|
|
void SetEnable(bool enable);
|
2015-01-31 12:01:01 +01:00
|
|
|
void SetPassthrough(bool enable);
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2025-03-06 21:14:38 -06:00
|
|
|
template <typename F>
|
|
|
|
void PushEvent(F&& callback)
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
|
|
|
|
|
|
if (m_passthrough)
|
|
|
|
{
|
|
|
|
std::invoke(callback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QueueEvent(Event{std::forward<F>(callback)});
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename F>
|
|
|
|
auto PushBlockingEvent(F&& callback) -> std::invoke_result_t<F>
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
|
|
|
|
|
|
if (m_passthrough)
|
|
|
|
return std::invoke(callback);
|
|
|
|
|
|
|
|
std::packaged_task task{std::forward<F>(callback)};
|
|
|
|
QueueEvent(Event{[&] { task(); }});
|
|
|
|
|
|
|
|
lock.unlock();
|
|
|
|
return task.get_future().get();
|
|
|
|
}
|
|
|
|
|
2015-01-31 11:38:23 +01:00
|
|
|
static AsyncRequests* GetInstance() { return &s_singleton; }
|
2018-04-12 14:18:04 +02:00
|
|
|
|
2015-01-31 11:38:23 +01:00
|
|
|
private:
|
2025-03-06 21:14:38 -06:00
|
|
|
using Event = std::function<void()>;
|
|
|
|
|
|
|
|
void QueueEvent(Event&& event);
|
|
|
|
|
2015-01-31 11:38:23 +01:00
|
|
|
void PullEventsInternal();
|
|
|
|
|
|
|
|
static AsyncRequests s_singleton;
|
|
|
|
|
2016-08-05 16:04:39 +02:00
|
|
|
Common::Flag m_empty;
|
2015-01-31 11:38:23 +01:00
|
|
|
std::queue<Event> m_queue;
|
|
|
|
std::mutex m_mutex;
|
|
|
|
std::condition_variable m_cond;
|
|
|
|
|
2018-04-01 19:01:55 -04:00
|
|
|
bool m_enable = false;
|
|
|
|
bool m_passthrough = true;
|
2015-01-31 11:38:23 +01:00
|
|
|
};
|