mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-14 10:21:21 +00:00
rsx/overlays: Putting it all together
- Migrate dialogs with input-only threads to use the unified input system
This commit is contained in:
parent
12690de9de
commit
ddc9e74aa8
@ -5,6 +5,8 @@
|
||||
#include "Emu/Cell/lv2/sys_sync.h"
|
||||
#include "Emu/Cell/timers.hpp"
|
||||
#include "Emu/Io/interception.h"
|
||||
|
||||
#include "Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "Emu/RSX/Overlays/overlay_message_dialog.h"
|
||||
|
||||
#include "cellSysutil.h"
|
||||
|
@ -4,9 +4,11 @@
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Io/interception.h"
|
||||
#include "Emu/Io/Keyboard.h"
|
||||
#include "Emu/RSX/Overlays/overlay_osk.h"
|
||||
#include "Emu/IdManager.h"
|
||||
|
||||
#include "Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "Emu/RSX/Overlays/overlay_osk.h"
|
||||
|
||||
#include "cellSysutil.h"
|
||||
#include "cellOskDialog.h"
|
||||
#include "cellMsgDialog.h"
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "Emu/VFS.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "Emu/RSX/Overlays/overlay_user_list_dialog.h"
|
||||
|
||||
#include "cellUserInfo.h"
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "GLGSRender.h"
|
||||
#include "Emu/Cell/Modules/cellVideoOut.h"
|
||||
#include "Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "util/video_provider.h"
|
||||
|
||||
LOG_CHANNEL(screenshot_log, "SCREENSHOT");
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlay_home_menu.h"
|
||||
#include "../overlay_manager.h"
|
||||
#include "Emu/RSX/RSXThread.h"
|
||||
#include "Utilities/date_time.h"
|
||||
|
||||
@ -165,31 +166,24 @@ namespace rsx
|
||||
this->on_close = std::move(on_close);
|
||||
visible = true;
|
||||
|
||||
auto& list_thread = g_fxo->get<named_thread<home_menu_dialog_thread>>();
|
||||
|
||||
const auto notify = std::make_shared<atomic_t<bool>>(false);
|
||||
auto& overlayman = g_fxo->get<display_manager>();
|
||||
|
||||
list_thread([&, notify]()
|
||||
{
|
||||
const u64 tbit = alloc_thread_bit();
|
||||
g_thread_bit = tbit;
|
||||
|
||||
*notify = true;
|
||||
notify->notify_one();
|
||||
|
||||
auto ref = g_fxo->get<display_manager>().get(uid);
|
||||
|
||||
if (const auto error = run_input_loop())
|
||||
overlayman.attach_thread_input(
|
||||
uid, // Target
|
||||
[](s32 error) // What to do with the result
|
||||
{
|
||||
if (error != selection_code::canceled)
|
||||
if (error && error != selection_code::canceled)
|
||||
{
|
||||
rsx_log.error("Home menu dialog input loop exited with error code=%d", error);
|
||||
}
|
||||
},
|
||||
[¬ify]() // What to do before starting the loop
|
||||
{
|
||||
*notify = true;
|
||||
notify->notify_one();
|
||||
}
|
||||
|
||||
thread_bits &= ~tbit;
|
||||
thread_bits.notify_all();
|
||||
});
|
||||
);
|
||||
|
||||
if (g_cfg.misc.pause_during_home_menu)
|
||||
{
|
||||
@ -199,7 +193,7 @@ namespace rsx
|
||||
});
|
||||
}
|
||||
|
||||
while (list_thread < thread_state::errored && !*notify)
|
||||
while (!Emu.IsStopped() && !*notify)
|
||||
{
|
||||
notify->wait(false, atomic_wait_timeout{1'000'000});
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "shader_loading_dialog_native.h"
|
||||
#include "../overlay_manager.h"
|
||||
#include "../overlay_message_dialog.h"
|
||||
#include "../../GSRender.h"
|
||||
#include "Emu/Cell/ErrorCodes.h"
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlay_cursor.h"
|
||||
#include "overlay_manager.h"
|
||||
|
||||
#include "Emu/RSX/RSXThread.h"
|
||||
|
||||
namespace rsx
|
||||
|
@ -1,10 +1,23 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlay_manager.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace overlays
|
||||
{
|
||||
display_manager::~display_manager()
|
||||
{
|
||||
if (m_input_thread)
|
||||
{
|
||||
m_input_thread_abort.store(true);
|
||||
while (*m_input_thread <= thread_state::aborting)
|
||||
{
|
||||
_mm_pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display_manager::lock()
|
||||
{
|
||||
m_list_mutex.lock_shared();
|
||||
@ -123,8 +136,29 @@ namespace rsx
|
||||
{
|
||||
if (auto iface = std::dynamic_pointer_cast<user_interface>(item))
|
||||
{
|
||||
// Kick input thread if not enabled. Expect the interface to attach shortly
|
||||
std::lock_guard lock(m_input_thread_lock);
|
||||
m_input_token_stack.emplace_front(std::move(iface));
|
||||
|
||||
if (!m_input_thread)
|
||||
{
|
||||
m_input_thread = std::make_shared<named_thread<overlay_input_thread>>();
|
||||
(*m_input_thread)([this]()
|
||||
{
|
||||
input_thread_loop();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display_manager::attach_thread_input(
|
||||
u32 uid,
|
||||
std::function<void(s32)> on_input_loop_exit,
|
||||
std::function<void()> on_input_loop_enter)
|
||||
{
|
||||
if (auto iface = std::dynamic_pointer_cast<user_interface>(get(uid)))
|
||||
{
|
||||
std::lock_guard lock(m_input_thread_lock);
|
||||
m_input_token_stack.emplace_front(std::move(iface), on_input_loop_enter, on_input_loop_exit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,5 +187,40 @@ namespace rsx
|
||||
m_input_token_stack.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void display_manager::input_thread_loop()
|
||||
{
|
||||
while (!m_input_thread_abort)
|
||||
{
|
||||
input_thread_context_t input_context;
|
||||
{
|
||||
reader_lock lock(m_input_thread_lock);
|
||||
if (!m_input_token_stack.empty())
|
||||
{
|
||||
input_context = m_input_token_stack.front();
|
||||
m_input_token_stack.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
if (input_context.target)
|
||||
{
|
||||
if (input_context.input_loop_prologue)
|
||||
{
|
||||
input_context.input_loop_prologue();
|
||||
}
|
||||
|
||||
const auto result = input_context.target->run_input_loop();
|
||||
|
||||
if (input_context.input_loop_epilogue)
|
||||
{
|
||||
input_context.input_loop_epilogue(result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_ctrl::wait_for(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Utilities/mutex.h"
|
||||
#include "Utilities/Thread.h"
|
||||
#include "Utilities/Timer.h"
|
||||
|
||||
#include <deque>
|
||||
@ -41,6 +42,8 @@ namespace rsx
|
||||
explicit display_manager(int) noexcept
|
||||
{}
|
||||
|
||||
~display_manager();
|
||||
|
||||
// Adds an object to the internal list. Optionally removes other objects of the same type.
|
||||
// Original handle loses ownership but a usable pointer is returned
|
||||
template <typename T>
|
||||
@ -152,19 +155,31 @@ namespace rsx
|
||||
// Release read-only lock (BasicLockable). May perform internal cleanup before returning
|
||||
void unlock();
|
||||
|
||||
// Enable input thread attach to the specified interface
|
||||
void attach_thread_input(
|
||||
u32 uid, // The input target
|
||||
std::function<void(s32)> on_input_loop_exit = nullptr, // [optional] What to do with the result if any
|
||||
std::function<void()> on_input_loop_enter = nullptr); // [optional] What to do before running the input routine
|
||||
|
||||
private:
|
||||
struct overlay_input_thread
|
||||
{
|
||||
static constexpr auto thread_name = "Overlay Input Thread"sv;
|
||||
};
|
||||
|
||||
struct input_thread_access_token
|
||||
struct input_thread_context_t
|
||||
{
|
||||
std::shared_ptr<user_interface> target;
|
||||
std::function<void()> input_loop_prologue = nullptr;
|
||||
std::function<void(s32)> input_loop_epilogue = nullptr;
|
||||
};
|
||||
|
||||
std::deque<input_thread_access_token> m_input_token_stack;
|
||||
std::deque<input_thread_context_t> m_input_token_stack;
|
||||
shared_mutex m_input_thread_lock;
|
||||
atomic_t<bool> m_input_thread_abort = false;
|
||||
|
||||
std::shared_ptr<named_thread<overlay_input_thread>> m_input_thread;
|
||||
void input_thread_loop();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlays.h"
|
||||
#include "overlay_manager.h"
|
||||
#include "overlay_media_list_dialog.h"
|
||||
|
||||
#include "Emu/Cell/Modules/cellMusic.h"
|
||||
#include "Emu/VFS.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
#include "Utilities/Thread.h"
|
||||
#include "overlays.h"
|
||||
#include "Emu/VFS.h"
|
||||
#include "Emu/Cell/Modules/cellMusic.h"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlays.h"
|
||||
#include "overlay_manager.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
namespace rsx
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlay_manager.h"
|
||||
#include "overlay_message_dialog.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
@ -299,52 +300,42 @@ namespace rsx
|
||||
{
|
||||
if (!m_stop_input_loop)
|
||||
{
|
||||
auto& dlg_thread = g_fxo->get<named_thread<msg_dialog_thread>>();
|
||||
|
||||
const auto notify = std::make_shared<atomic_t<bool>>(false);
|
||||
auto& overlayman = g_fxo->get<display_manager>();
|
||||
|
||||
dlg_thread([&, notify]()
|
||||
overlayman.attach_thread_input(
|
||||
uid,
|
||||
[](s32 error)
|
||||
{
|
||||
if (error && error != selection_code::canceled)
|
||||
{
|
||||
rsx_log.error("Message dialog input loop exited with error code=%d", error);
|
||||
}
|
||||
},
|
||||
[¬ify]()
|
||||
{
|
||||
*notify = true;
|
||||
notify->notify_one();
|
||||
}
|
||||
);
|
||||
|
||||
#if 0
|
||||
while (!m_stop_input_loop && thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
const u64 tbit = alloc_thread_bit();
|
||||
g_thread_bit = tbit;
|
||||
refresh();
|
||||
|
||||
*notify = true;
|
||||
notify->notify_one();
|
||||
// Only update the screen at about 60fps since updating it everytime slows down the process
|
||||
std::this_thread::sleep_for(16ms);
|
||||
|
||||
if (interactive)
|
||||
if (!g_fxo->is_init<display_manager>())
|
||||
{
|
||||
auto ref = g_fxo->get<display_manager>().get(uid);
|
||||
|
||||
if (const auto error = run_input_loop())
|
||||
{
|
||||
if (error != selection_code::canceled)
|
||||
{
|
||||
rsx_log.error("Message dialog input loop exited with error code=%d", error);
|
||||
}
|
||||
}
|
||||
rsx_log.fatal("display_manager was improperly destroyed");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!m_stop_input_loop && thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Only update the screen at about 60fps since updating it everytime slows down the process
|
||||
std::this_thread::sleep_for(16ms);
|
||||
|
||||
if (!g_fxo->is_init<display_manager>())
|
||||
{
|
||||
rsx_log.fatal("display_manager was improperly destroyed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thread_bits &= ~tbit;
|
||||
thread_bits.notify_all();
|
||||
});
|
||||
|
||||
while (dlg_thread < thread_state::errored && !*notify)
|
||||
while (!Emu.IsStopped() && !*notify)
|
||||
{
|
||||
notify->wait(false, atomic_wait_timeout{1'000'000});
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlay_manager.h"
|
||||
#include "overlay_osk.h"
|
||||
#include "Emu/RSX/RSXThread.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
@ -1624,31 +1625,26 @@ namespace rsx
|
||||
|
||||
update_panel();
|
||||
|
||||
auto& osk_thread = g_fxo->get<named_thread<osk_dialog_thread>>();
|
||||
|
||||
const auto notify = std::make_shared<atomic_t<bool>>(false);
|
||||
auto& overlayman = g_fxo->get<display_manager>();
|
||||
|
||||
osk_thread([&, notify]()
|
||||
{
|
||||
const u64 tbit = alloc_thread_bit();
|
||||
g_thread_bit = tbit;
|
||||
|
||||
*notify = true;
|
||||
notify->notify_one();
|
||||
|
||||
if (const auto error = run_input_loop())
|
||||
overlayman.attach_thread_input(
|
||||
uid,
|
||||
[](s32 error)
|
||||
{
|
||||
if (error != selection_code::canceled)
|
||||
if (error && error != selection_code::canceled)
|
||||
{
|
||||
rsx_log.error("Osk input loop exited with error code=%d", error);
|
||||
}
|
||||
},
|
||||
[¬ify]()
|
||||
{
|
||||
*notify = true;
|
||||
notify->notify_one();
|
||||
}
|
||||
);
|
||||
|
||||
thread_bits &= ~tbit;
|
||||
thread_bits.notify_all();
|
||||
});
|
||||
|
||||
while (osk_thread < thread_state::errored && !*notify)
|
||||
while (!Emu.IsStopped() && !*notify)
|
||||
{
|
||||
notify->wait(false, atomic_wait_timeout{1'000'000});
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlay_manager.h"
|
||||
#include "overlay_perf_metrics.h"
|
||||
#include "Emu/RSX/RSXThread.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlay_manager.h"
|
||||
#include "overlay_user_list_dialog.h"
|
||||
#include "Emu/vfs_config.h"
|
||||
#include "Emu/system_utils.hpp"
|
||||
@ -243,33 +244,26 @@ namespace rsx
|
||||
this->on_close = std::move(on_close);
|
||||
visible = true;
|
||||
|
||||
auto& list_thread = g_fxo->get<named_thread<user_list_dialog_thread>>();
|
||||
|
||||
const auto notify = std::make_shared<atomic_t<bool>>(false);
|
||||
auto& overlayman = g_fxo->get<display_manager>();
|
||||
|
||||
list_thread([&, notify]()
|
||||
{
|
||||
const u64 tbit = alloc_thread_bit();
|
||||
g_thread_bit = tbit;
|
||||
|
||||
*notify = true;
|
||||
notify->notify_one();
|
||||
|
||||
auto ref = g_fxo->get<display_manager>().get(uid);
|
||||
|
||||
if (const auto error = run_input_loop())
|
||||
overlayman.attach_thread_input(
|
||||
uid,
|
||||
[](s32 error)
|
||||
{
|
||||
if (error != selection_code::canceled)
|
||||
if (error && error != selection_code::canceled)
|
||||
{
|
||||
rsx_log.error("User list dialog input loop exited with error code=%d", error);
|
||||
}
|
||||
},
|
||||
[¬ify]()
|
||||
{
|
||||
*notify = true;
|
||||
notify->notify_one();
|
||||
}
|
||||
);
|
||||
|
||||
thread_bits &= ~tbit;
|
||||
thread_bits.notify_all();
|
||||
});
|
||||
|
||||
while (list_thread < thread_state::errored && !*notify)
|
||||
while (!Emu.IsStopped() && !*notify)
|
||||
{
|
||||
notify->wait(false, atomic_wait_timeout{1'000'000});
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "overlays.h"
|
||||
#include "overlay_manager.h"
|
||||
#include "overlay_message_dialog.h"
|
||||
#include "Input/pad_thread.h"
|
||||
#include "Emu/Io/interception.h"
|
||||
@ -47,6 +48,8 @@ namespace rsx
|
||||
|
||||
s32 user_interface::run_input_loop()
|
||||
{
|
||||
user_interface::thread_bits_allocator thread_bits_alloc(this);
|
||||
|
||||
m_interactive = true;
|
||||
|
||||
std::array<steady_clock::time_point, CELL_PAD_MAX_PORT_NUM> timestamp;
|
||||
|
@ -123,6 +123,26 @@ namespace rsx
|
||||
|
||||
std::function<void(s32 status)> on_close = nullptr;
|
||||
|
||||
class thread_bits_allocator
|
||||
{
|
||||
public:
|
||||
thread_bits_allocator(user_interface* parent)
|
||||
: m_parent(parent)
|
||||
{
|
||||
m_thread_bit = m_parent->alloc_thread_bit();
|
||||
g_thread_bit = m_thread_bit;
|
||||
}
|
||||
|
||||
~thread_bits_allocator()
|
||||
{
|
||||
m_parent->thread_bits &= ~m_thread_bit;
|
||||
m_parent->thread_bits.notify_all();
|
||||
}
|
||||
|
||||
private:
|
||||
user_interface* m_parent;
|
||||
u64 m_thread_bit;
|
||||
};
|
||||
public:
|
||||
s32 return_code = 0; // CELL_OK
|
||||
|
||||
@ -137,236 +157,5 @@ namespace rsx
|
||||
|
||||
s32 run_input_loop();
|
||||
};
|
||||
|
||||
class display_manager
|
||||
{
|
||||
private:
|
||||
atomic_t<u32> m_uid_ctr = 0;
|
||||
std::vector<std::shared_ptr<overlay>> m_iface_list;
|
||||
std::vector<std::shared_ptr<overlay>> m_dirty_list;
|
||||
|
||||
shared_mutex m_list_mutex;
|
||||
std::vector<u32> m_uids_to_remove;
|
||||
std::vector<u32> m_type_ids_to_remove;
|
||||
|
||||
bool remove_type(u32 type_id)
|
||||
{
|
||||
bool found = false;
|
||||
for (auto It = m_iface_list.begin(); It != m_iface_list.end();)
|
||||
{
|
||||
if (It->get()->type_index == type_id)
|
||||
{
|
||||
m_dirty_list.push_back(std::move(*It));
|
||||
It = m_iface_list.erase(It);
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
++It;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool remove_uid(u32 uid)
|
||||
{
|
||||
for (auto It = m_iface_list.begin(); It != m_iface_list.end(); It++)
|
||||
{
|
||||
const auto e = It->get();
|
||||
if (e->uid == uid)
|
||||
{
|
||||
m_dirty_list.push_back(std::move(*It));
|
||||
m_iface_list.erase(It);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void cleanup_internal()
|
||||
{
|
||||
for (const auto &uid : m_uids_to_remove)
|
||||
{
|
||||
remove_uid(uid);
|
||||
}
|
||||
|
||||
for (const auto &type_id : m_type_ids_to_remove)
|
||||
{
|
||||
remove_type(type_id);
|
||||
}
|
||||
|
||||
m_uids_to_remove.clear();
|
||||
m_type_ids_to_remove.clear();
|
||||
}
|
||||
|
||||
public:
|
||||
// Disable default construction to make it conditionally available in g_fxo
|
||||
explicit display_manager(int) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
// Adds an object to the internal list. Optionally removes other objects of the same type.
|
||||
// Original handle loses ownership but a usable pointer is returned
|
||||
template <typename T>
|
||||
std::shared_ptr<T> add(std::shared_ptr<T>& entry, bool remove_existing = true)
|
||||
{
|
||||
std::lock_guard lock(m_list_mutex);
|
||||
|
||||
entry->uid = m_uid_ctr.fetch_add(1);
|
||||
entry->type_index = id_manager::typeinfo::get_index<T>();
|
||||
|
||||
if (remove_existing)
|
||||
{
|
||||
for (auto It = m_iface_list.begin(); It != m_iface_list.end(); It++)
|
||||
{
|
||||
if (It->get()->type_index == entry->type_index)
|
||||
{
|
||||
// Replace
|
||||
m_dirty_list.push_back(std::move(*It));
|
||||
*It = std::move(entry);
|
||||
return std::static_pointer_cast<T>(*It);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_iface_list.push_back(std::move(entry));
|
||||
return std::static_pointer_cast<T>(m_iface_list.back());
|
||||
}
|
||||
|
||||
// Allocates object and adds to internal list. Returns pointer to created object
|
||||
template <typename T, typename ...Args>
|
||||
std::shared_ptr<T> create(Args&&... args)
|
||||
{
|
||||
auto object = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
return add(object);
|
||||
}
|
||||
|
||||
// Removes item from list if it matches the uid
|
||||
void remove(u32 uid)
|
||||
{
|
||||
if (m_list_mutex.try_lock())
|
||||
{
|
||||
remove_uid(uid);
|
||||
m_list_mutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uids_to_remove.push_back(uid);
|
||||
}
|
||||
}
|
||||
|
||||
// Removes all objects of this type from the list
|
||||
template <typename T>
|
||||
void remove()
|
||||
{
|
||||
const auto type_id = id_manager::typeinfo::get_index<T>();
|
||||
if (m_list_mutex.try_lock())
|
||||
{
|
||||
remove_type(type_id);
|
||||
m_list_mutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type_ids_to_remove.push_back(type_id);
|
||||
}
|
||||
}
|
||||
|
||||
// True if any visible elements to draw exist
|
||||
bool has_visible() const
|
||||
{
|
||||
return !m_iface_list.empty();
|
||||
}
|
||||
|
||||
// True if any elements have been deleted but their resources may not have been cleaned up
|
||||
bool has_dirty() const
|
||||
{
|
||||
return !m_dirty_list.empty();
|
||||
}
|
||||
|
||||
// Returns current list for reading. Caller must ensure synchronization by first locking the list
|
||||
const std::vector<std::shared_ptr<overlay>>& get_views() const
|
||||
{
|
||||
return m_iface_list;
|
||||
}
|
||||
|
||||
// Returns current list of removed objects not yet deallocated for reading.
|
||||
// Caller must ensure synchronization by first locking the list
|
||||
const std::vector<std::shared_ptr<overlay>>& get_dirty() const
|
||||
{
|
||||
return m_dirty_list;
|
||||
}
|
||||
|
||||
// Deallocate object. Object must first be removed via the remove() functions
|
||||
void dispose(const std::vector<u32>& uids)
|
||||
{
|
||||
std::lock_guard lock(m_list_mutex);
|
||||
|
||||
if (!m_uids_to_remove.empty() || !m_type_ids_to_remove.empty())
|
||||
{
|
||||
cleanup_internal();
|
||||
}
|
||||
|
||||
m_dirty_list.erase
|
||||
(
|
||||
std::remove_if(m_dirty_list.begin(), m_dirty_list.end(), [&uids](std::shared_ptr<overlay>& e)
|
||||
{
|
||||
return std::find(uids.begin(), uids.end(), e->uid) != uids.end();
|
||||
}),
|
||||
m_dirty_list.end()
|
||||
);
|
||||
}
|
||||
|
||||
// Returns pointer to the object matching the given uid
|
||||
std::shared_ptr<overlay> get(u32 uid)
|
||||
{
|
||||
reader_lock lock(m_list_mutex);
|
||||
|
||||
for (const auto& iface : m_iface_list)
|
||||
{
|
||||
if (iface->uid == uid)
|
||||
return iface;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// Returns pointer to the first object matching the given type
|
||||
template <typename T>
|
||||
std::shared_ptr<T> get()
|
||||
{
|
||||
reader_lock lock(m_list_mutex);
|
||||
|
||||
const auto type_id = id_manager::typeinfo::get_index<T>();
|
||||
for (const auto& iface : m_iface_list)
|
||||
{
|
||||
if (iface->type_index == type_id)
|
||||
{
|
||||
return std::static_pointer_cast<T>(iface);
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// Lock for read-only access (BasicLockable)
|
||||
void lock()
|
||||
{
|
||||
m_list_mutex.lock_shared();
|
||||
}
|
||||
|
||||
// Release read-only lock (BasicLockable). May perform internal cleanup before returning
|
||||
void unlock()
|
||||
{
|
||||
m_list_mutex.unlock_shared();
|
||||
|
||||
if (!m_uids_to_remove.empty() || !m_type_ids_to_remove.empty())
|
||||
{
|
||||
std::lock_guard lock(m_list_mutex);
|
||||
cleanup_internal();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "../Overlays/overlay_animated_icon.h"
|
||||
#include "../Overlays/overlay_dock.h"
|
||||
#include "../Overlays/overlay_manager.h"
|
||||
#include "../Overlays/overlay_shader_compile_notification.h"
|
||||
#include "../Overlays/Shaders/shader_loading_dialog_native.h"
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "VKGSRender.h"
|
||||
#include "vkutils/buffer_object.h"
|
||||
#include "Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "Emu/RSX/Overlays/overlays.h"
|
||||
#include "Emu/Cell/Modules/cellVideoOut.h"
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "system_progress.hpp"
|
||||
#include "Emu/Cell/Modules/cellMsgDialog.h"
|
||||
#include "Emu/RSX/RSXThread.h"
|
||||
#include "Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "Emu/RSX/Overlays/overlay_message_dialog.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Io/interception.h"
|
||||
#include "../Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "Emu/RSX/Overlays/overlay_save_dialog.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include "../Emu/IdManager.h"
|
||||
#include "../Emu/System.h"
|
||||
|
||||
#include "../Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "../Emu/RSX/Overlays/overlay_trophy_notification.h"
|
||||
|
||||
#include "Utilities/File.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user