mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
Add new typemap for always existing objects
Not to be confused with singletons or global variables.
This commit is contained in:
parent
7db2e2537f
commit
8517ccfdfa
6 changed files with 136 additions and 6 deletions
|
@ -41,7 +41,7 @@ void spu_recompiler::init()
|
|||
if (!m_spurt)
|
||||
{
|
||||
m_cache = fxm::get<spu_cache>();
|
||||
m_spurt = fxm::get_always<spu_runtime>();
|
||||
m_spurt = g_fxo->get<spu_runtime>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -538,8 +538,6 @@ spu_runtime::spu_runtime()
|
|||
fs::file(m_cache_path + "spu.log", fs::rewrite);
|
||||
fs::file(m_cache_path + "spu-ir.log", fs::rewrite);
|
||||
}
|
||||
|
||||
LOG_SUCCESS(SPU, "SPU Recompiler Runtime initialized...");
|
||||
}
|
||||
|
||||
bool spu_runtime::add(u64 last_reset_count, void* _where, spu_function_t compiled)
|
||||
|
@ -4165,7 +4163,7 @@ public:
|
|||
if (!m_spurt)
|
||||
{
|
||||
m_cache = fxm::get<spu_cache>();
|
||||
m_spurt = fxm::get_always<spu_runtime>();
|
||||
m_spurt = g_fxo->get<spu_runtime>();
|
||||
cpu_translator::initialize(m_jit.get_context(), m_jit.get_engine());
|
||||
|
||||
const auto md_name = llvm::MDString::get(m_context, "branch_weights");
|
||||
|
|
|
@ -76,6 +76,10 @@ public:
|
|||
public:
|
||||
spu_runtime();
|
||||
|
||||
spu_runtime(const spu_runtime&) = delete;
|
||||
|
||||
spu_runtime& operator=(const spu_runtime&) = delete;
|
||||
|
||||
const std::string& get_cache_path() const
|
||||
{
|
||||
return m_cache_path;
|
||||
|
@ -226,7 +230,7 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
std::shared_ptr<spu_runtime> m_spurt;
|
||||
spu_runtime* m_spurt{};
|
||||
|
||||
u32 m_pos;
|
||||
u32 m_size;
|
||||
|
|
|
@ -138,7 +138,7 @@ class idm
|
|||
{
|
||||
using traits = id_manager::id_traits<T>;
|
||||
|
||||
// Note: if id is lower than base, diff / step will be higher than count
|
||||
// Note: if id is lower than base, diff / step will be higher than count
|
||||
u32 diff = id - traits::base;
|
||||
|
||||
if (diff % traits::step)
|
||||
|
@ -785,6 +785,7 @@ public:
|
|||
};
|
||||
|
||||
#include "Utilities/typemap.h"
|
||||
#include "util/fixed_typemap.hpp"
|
||||
|
||||
extern utils::typemap g_typemap;
|
||||
|
||||
|
@ -793,3 +794,7 @@ constexpr utils::typemap* g_idm = &g_typemap;
|
|||
using utils::id_new;
|
||||
using utils::id_any;
|
||||
using utils::id_always;
|
||||
|
||||
extern stx::manual_fixed_typemap<void> g_fixed_typemap;
|
||||
|
||||
constexpr stx::manual_fixed_typemap<void>* g_fxo = &g_fixed_typemap;
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "Emu/RSX/VK/VulkanAPI.h"
|
||||
#endif
|
||||
|
||||
stx::manual_fixed_typemap<void> g_fixed_typemap;
|
||||
|
||||
utils::typemap g_typemap{nullptr};
|
||||
|
||||
cfg_root g_cfg;
|
||||
|
@ -318,6 +320,7 @@ void Emulator::Init()
|
|||
idm::init();
|
||||
fxm::init();
|
||||
g_idm->init();
|
||||
g_fxo->reset();
|
||||
|
||||
// Reset defaults, cache them
|
||||
g_cfg.from_default();
|
||||
|
@ -1511,6 +1514,7 @@ void Emulator::Load(const std::string& title_id, bool add_only, bool force_globa
|
|||
LOG_NOTICE(LOADER, "Cache: %s", _main->cache);
|
||||
}
|
||||
|
||||
g_fxo->init();
|
||||
fxm::import<GSRender>(Emu.GetCallbacks().get_gs_render); // TODO: must be created in appropriate sys_rsx syscall
|
||||
fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler, m_title_id);
|
||||
network_thread_init();
|
||||
|
@ -1735,6 +1739,7 @@ void Emulator::Stop(bool restart)
|
|||
idm::clear();
|
||||
fxm::clear();
|
||||
g_idm->init();
|
||||
g_fxo->reset();
|
||||
|
||||
LOG_NOTICE(GENERAL, "Objects cleared...");
|
||||
|
||||
|
|
118
rpcs3/util/fixed_typemap.hpp
Normal file
118
rpcs3/util/fixed_typemap.hpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <util/typeindices.hpp>
|
||||
|
||||
namespace stx
|
||||
{
|
||||
// Typemap with exactly one object of each used type, created on init() and destroyed on clear()
|
||||
template <typename /*Tag*/>
|
||||
class manual_fixed_typemap
|
||||
{
|
||||
// Save default constructor and destructor
|
||||
struct typeinfo
|
||||
{
|
||||
void(*create)(void*& ptr) noexcept;
|
||||
void(*destroy)(void*& ptr) noexcept;
|
||||
|
||||
template <typename T>
|
||||
static void call_ctor(void*& ptr) noexcept
|
||||
{
|
||||
// Call default constructor only if available
|
||||
if constexpr (std::is_default_constructible_v<T>)
|
||||
{
|
||||
// Don't overwrite if already exists
|
||||
if (!ptr)
|
||||
{
|
||||
ptr = new T{};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void call_dtor(void*& ptr) noexcept
|
||||
{
|
||||
delete static_cast<T*>(ptr);
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static typeinfo make_typeinfo()
|
||||
{
|
||||
typeinfo r;
|
||||
r.create = &call_ctor<T>;
|
||||
r.destroy = &call_dtor<T>;
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<void*[]> m_list;
|
||||
|
||||
public:
|
||||
constexpr manual_fixed_typemap() noexcept = default;
|
||||
|
||||
manual_fixed_typemap(const manual_fixed_typemap&) = delete;
|
||||
|
||||
manual_fixed_typemap(manual_fixed_typemap&& r) noexcept
|
||||
{
|
||||
std::swap(m_list, r.m_list);
|
||||
}
|
||||
|
||||
manual_fixed_typemap& operator=(const manual_fixed_typemap&) = delete;
|
||||
|
||||
manual_fixed_typemap& operator=(manual_fixed_typemap&& r) noexcept
|
||||
{
|
||||
manual_fixed_typemap x(std::move(*this));
|
||||
std::swap(m_list, x.m_list);
|
||||
}
|
||||
|
||||
// Destroy all objects and keep them in uninitialized state, must be called first
|
||||
void reset() noexcept
|
||||
{
|
||||
if (!m_list)
|
||||
{
|
||||
m_list = std::make_unique<void*[]>(stx::typeinfo_v<typeinfo>.count());
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& type : stx::typeinfo_v<typeinfo>)
|
||||
{
|
||||
type.destroy(m_list[type.index()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Default initialize all objects if possible and not already initialized
|
||||
void init() noexcept
|
||||
{
|
||||
for (auto& type : stx::typeinfo_v<typeinfo>)
|
||||
{
|
||||
type.create(m_list[type.index()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Explicitly (re)initialize object of type T possibly with dynamic type As and arguments
|
||||
template <typename T, typename As = T, typename... Args>
|
||||
T* init(Args&&... args) noexcept
|
||||
{
|
||||
auto& ptr = m_list[stx::type_counter<typeinfo>::template type<std::decay_t<T>>.index()];
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
delete static_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
auto* obj = static_cast<T*>(new std::decay_t<As>(std::forward<Args>(args)...));
|
||||
ptr = obj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Obtain object pointer (the only thread safe function)
|
||||
template <typename T>
|
||||
T* get() const noexcept
|
||||
{
|
||||
return static_cast<T*>(m_list[stx::type_counter<typeinfo>::template type<std::decay_t<T>>.index()]);
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Add table
Reference in a new issue