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
|
|
|
|
|
|
2025-10-25 16:40:56 -05:00
|
|
|
#include <concepts>
|
2025-03-06 21:14:38 -06:00
|
|
|
#include <functional>
|
|
|
|
|
#include <future>
|
2015-01-31 11:38:23 +01:00
|
|
|
|
2025-04-27 19:53:18 -05:00
|
|
|
#include "Common/Functional.h"
|
2025-10-25 16:40:56 -05:00
|
|
|
#include "Common/SPSCQueue.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
|
|
|
|
2025-10-25 16:40:56 -05:00
|
|
|
// Called from the Video thread.
|
|
|
|
|
void PullEvents();
|
|
|
|
|
|
|
|
|
|
// The following are called from the CPU thread.
|
2020-04-07 19:37:32 +02:00
|
|
|
void WaitForEmptyQueue();
|
2016-06-24 10:43:46 +02:00
|
|
|
|
2025-10-25 16:40:56 -05:00
|
|
|
template <std::invocable<> F>
|
2025-03-06 21:14:38 -06:00
|
|
|
void PushEvent(F&& callback)
|
|
|
|
|
{
|
|
|
|
|
if (m_passthrough)
|
|
|
|
|
{
|
2025-10-25 16:40:56 -05:00
|
|
|
std::invoke(std::forward<F>(callback));
|
2025-03-06 21:14:38 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QueueEvent(Event{std::forward<F>(callback)});
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-25 16:40:56 -05:00
|
|
|
template <std::invocable<> F>
|
2025-03-06 21:14:38 -06:00
|
|
|
auto PushBlockingEvent(F&& callback) -> std::invoke_result_t<F>
|
|
|
|
|
{
|
|
|
|
|
if (m_passthrough)
|
2025-10-25 16:40:56 -05:00
|
|
|
return std::invoke(std::forward<F>(callback));
|
2025-03-06 21:14:38 -06:00
|
|
|
|
|
|
|
|
std::packaged_task task{std::forward<F>(callback)};
|
|
|
|
|
QueueEvent(Event{[&] { task(); }});
|
|
|
|
|
|
|
|
|
|
return task.get_future().get();
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-25 16:40:56 -05:00
|
|
|
// Not thread-safe. Only set during initialization.
|
|
|
|
|
void SetPassthrough(bool enable);
|
|
|
|
|
|
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-04-27 19:53:18 -05:00
|
|
|
using Event = Common::MoveOnlyFunction<void()>;
|
2025-03-06 21:14:38 -06:00
|
|
|
|
|
|
|
|
void QueueEvent(Event&& event);
|
|
|
|
|
|
2015-01-31 11:38:23 +01:00
|
|
|
static AsyncRequests s_singleton;
|
|
|
|
|
|
2025-10-25 16:40:56 -05:00
|
|
|
Common::WaitableSPSCQueue<Event> m_queue;
|
2015-01-31 11:38:23 +01:00
|
|
|
|
2018-04-01 19:01:55 -04:00
|
|
|
bool m_passthrough = true;
|
2015-01-31 11:38:23 +01:00
|
|
|
};
|