TimingEvents: Use function pointers instead of std::function

This commit is contained in:
Connor McLaughlin 2021-01-10 01:43:59 +10:00
parent 8c241ed8de
commit 11992bde4e
10 changed files with 56 additions and 35 deletions

View file

@ -78,10 +78,14 @@ CDROM::~CDROM() = default;
void CDROM::Initialize() void CDROM::Initialize()
{ {
m_command_event = m_command_event = TimingEvents::CreateTimingEvent(
TimingEvents::CreateTimingEvent("CDROM Command Event", 1, 1, std::bind(&CDROM::ExecuteCommand, this), false); "CDROM Command Event", 1, 1,
m_drive_event = TimingEvents::CreateTimingEvent("CDROM Drive Event", 1, 1, [](void* param, TickCount ticks, TickCount ticks_late) { static_cast<CDROM*>(param)->ExecuteCommand(); }, this,
std::bind(&CDROM::ExecuteDrive, this, std::placeholders::_2), false); false);
m_drive_event = TimingEvents::CreateTimingEvent(
"CDROM Drive Event", 1, 1,
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<CDROM*>(param)->ExecuteDrive(ticks_late); },
this, false);
if (g_settings.cdrom_read_thread) if (g_settings.cdrom_read_thread)
m_reader.StartThread(); m_reader.StartThread();

View file

@ -29,8 +29,10 @@ void DMA::Initialize()
m_halt_ticks = g_settings.dma_halt_ticks; m_halt_ticks = g_settings.dma_halt_ticks;
m_transfer_buffer.resize(32); m_transfer_buffer.resize(32);
m_unhalt_event = TimingEvents::CreateTimingEvent("DMA Transfer Unhalt", 1, m_max_slice_ticks, m_unhalt_event = TimingEvents::CreateTimingEvent(
std::bind(&DMA::UnhaltTransfer, this, std::placeholders::_1), false); "DMA Transfer Unhalt", 1, m_max_slice_ticks,
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<DMA*>(param)->UnhaltTransfer(ticks); }, this,
false);
Reset(); Reset();
} }

View file

@ -31,9 +31,13 @@ bool GPU::Initialize(HostDisplay* host_display)
m_force_progressive_scan = g_settings.gpu_disable_interlacing; m_force_progressive_scan = g_settings.gpu_disable_interlacing;
m_force_ntsc_timings = g_settings.gpu_force_ntsc_timings; m_force_ntsc_timings = g_settings.gpu_force_ntsc_timings;
m_crtc_tick_event = TimingEvents::CreateTimingEvent( m_crtc_tick_event = TimingEvents::CreateTimingEvent(
"GPU CRTC Tick", 1, 1, std::bind(&GPU::CRTCTickEvent, this, std::placeholders::_1), true); "GPU CRTC Tick", 1, 1,
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<GPU*>(param)->CRTCTickEvent(ticks); }, this,
true);
m_command_tick_event = TimingEvents::CreateTimingEvent( m_command_tick_event = TimingEvents::CreateTimingEvent(
"GPU Command Tick", 1, 1, std::bind(&GPU::CommandTickEvent, this, std::placeholders::_1), true); "GPU Command Tick", 1, 1,
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<GPU*>(param)->CommandTickEvent(ticks); }, this,
true);
m_fifo_size = g_settings.gpu_fifo_size; m_fifo_size = g_settings.gpu_fifo_size;
m_max_run_ahead = g_settings.gpu_max_run_ahead; m_max_run_ahead = g_settings.gpu_max_run_ahead;
m_console_is_pal = System::IsPALRegion(); m_console_is_pal = System::IsPALRegion();

View file

@ -18,8 +18,9 @@ MDEC::~MDEC() = default;
void MDEC::Initialize() void MDEC::Initialize()
{ {
m_block_copy_out_event = m_block_copy_out_event = TimingEvents::CreateTimingEvent(
TimingEvents::CreateTimingEvent("MDEC Block Copy Out", 1, 1, std::bind(&MDEC::CopyOutBlock, this), false); "MDEC Block Copy Out", 1, 1,
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<MDEC*>(param)->CopyOutBlock(); }, this, false);
m_total_blocks_decoded = 0; m_total_blocks_decoded = 0;
Reset(); Reset();
} }

View file

@ -13,8 +13,10 @@ MemoryCard::MemoryCard()
{ {
m_FLAG.no_write_yet = true; m_FLAG.no_write_yet = true;
m_save_event = TimingEvents::CreateTimingEvent("Memory Card Host Flush", GetSaveDelayInTicks(), GetSaveDelayInTicks(), m_save_event = TimingEvents::CreateTimingEvent(
std::bind(&MemoryCard::SaveIfChanged, this, true), false); "Memory Card Host Flush", GetSaveDelayInTicks(), GetSaveDelayInTicks(),
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<MemoryCard*>(param)->SaveIfChanged(true); },
this, false);
} }
MemoryCard::~MemoryCard() MemoryCard::~MemoryCard()

View file

@ -17,7 +17,9 @@ Pad::~Pad() = default;
void Pad::Initialize() void Pad::Initialize()
{ {
m_transfer_event = TimingEvents::CreateTimingEvent( m_transfer_event = TimingEvents::CreateTimingEvent(
"Pad Serial Transfer", 1, 1, std::bind(&Pad::TransferEvent, this, std::placeholders::_2), false); "Pad Serial Transfer", 1, 1,
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<Pad*>(param)->TransferEvent(ticks_late); },
this, false);
Reset(); Reset();
} }

View file

@ -24,11 +24,13 @@ void SPU::Initialize()
// (X * D) / N / 768 -> (X * D) / (N * 768) // (X * D) / N / 768 -> (X * D) / (N * 768)
m_cpu_ticks_per_spu_tick = System::ScaleTicksToOverclock(SYSCLK_TICKS_PER_SPU_TICK); m_cpu_ticks_per_spu_tick = System::ScaleTicksToOverclock(SYSCLK_TICKS_PER_SPU_TICK);
m_cpu_tick_divider = static_cast<TickCount>(g_settings.cpu_overclock_numerator * SYSCLK_TICKS_PER_SPU_TICK); m_cpu_tick_divider = static_cast<TickCount>(g_settings.cpu_overclock_numerator * SYSCLK_TICKS_PER_SPU_TICK);
m_tick_event = TimingEvents::CreateTimingEvent("SPU Sample", m_cpu_ticks_per_spu_tick, m_cpu_ticks_per_spu_tick, m_tick_event = TimingEvents::CreateTimingEvent(
std::bind(&SPU::Execute, this, std::placeholders::_1), false); "SPU Sample", m_cpu_ticks_per_spu_tick, m_cpu_ticks_per_spu_tick,
m_transfer_event = [](void* param, TickCount ticks, TickCount ticks_late) { static_cast<SPU*>(param)->Execute(ticks); }, this, false);
TimingEvents::CreateTimingEvent("SPU Transfer", TRANSFER_TICKS_PER_HALFWORD, TRANSFER_TICKS_PER_HALFWORD, m_transfer_event = TimingEvents::CreateTimingEvent(
std::bind(&SPU::ExecuteTransfer, this, std::placeholders::_1), false); "SPU Transfer", TRANSFER_TICKS_PER_HALFWORD, TRANSFER_TICKS_PER_HALFWORD,
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<SPU*>(param)->ExecuteTransfer(ticks); }, this,
false);
Reset(); Reset();
} }

View file

@ -18,7 +18,9 @@ Timers::~Timers() = default;
void Timers::Initialize() void Timers::Initialize()
{ {
m_sysclk_event = TimingEvents::CreateTimingEvent( m_sysclk_event = TimingEvents::CreateTimingEvent(
"Timer SysClk Interrupt", 1, 1, std::bind(&Timers::AddSysClkTicks, this, std::placeholders::_1), false); "Timer SysClk Interrupt", 1, 1,
[](void* param, TickCount ticks, TickCount ticks_late) { static_cast<Timers*>(param)->AddSysClkTicks(ticks); },
this, false);
Reset(); Reset();
} }

View file

@ -36,10 +36,10 @@ void Shutdown()
} }
std::unique_ptr<TimingEvent> CreateTimingEvent(std::string name, TickCount period, TickCount interval, std::unique_ptr<TimingEvent> CreateTimingEvent(std::string name, TickCount period, TickCount interval,
TimingEventCallback callback, bool activate) TimingEventCallback callback, void* callback_param, bool activate)
{ {
std::unique_ptr<TimingEvent> event = std::unique_ptr<TimingEvent> event =
std::make_unique<TimingEvent>(std::move(name), period, interval, std::move(callback)); std::make_unique<TimingEvent>(std::move(name), period, interval, callback, callback_param);
if (activate) if (activate)
event->Activate(); event->Activate();
@ -291,7 +291,7 @@ void RunEvents()
event->m_time_since_last_run = 0; event->m_time_since_last_run = 0;
// The cycles_late is only an indicator, it doesn't modify the cycles to execute. // The cycles_late is only an indicator, it doesn't modify the cycles to execute.
event->m_callback(ticks_to_execute, ticks_late); event->m_callback(event->m_callback_param, ticks_to_execute, ticks_late);
if (event->m_active) if (event->m_active)
SortEvent(event); SortEvent(event);
} }
@ -369,9 +369,10 @@ bool DoState(StateWrapper& sw)
} // namespace TimingEvents } // namespace TimingEvents
TimingEvent::TimingEvent(std::string name, TickCount period, TickCount interval, TimingEventCallback callback) TimingEvent::TimingEvent(std::string name, TickCount period, TickCount interval, TimingEventCallback callback,
: m_downcount(interval), m_time_since_last_run(0), m_period(period), m_interval(interval), void* callback_param)
m_callback(std::move(callback)), m_name(std::move(name)), m_active(false) : m_downcount(interval), m_time_since_last_run(0), m_period(period), m_interval(interval), m_callback(callback),
m_callback_param(callback_param), m_name(std::move(name)), m_active(false)
{ {
} }
@ -448,7 +449,7 @@ void TimingEvent::InvokeEarly(bool force /* = false */)
m_downcount = pending_ticks + m_interval; m_downcount = pending_ticks + m_interval;
m_time_since_last_run -= ticks_to_execute; m_time_since_last_run -= ticks_to_execute;
m_callback(ticks_to_execute, 0); m_callback(m_callback_param, ticks_to_execute, 0);
// Since we've changed the downcount, we need to re-sort the events. // Since we've changed the downcount, we need to re-sort the events.
DebugAssert(TimingEvents::s_current_event != this); DebugAssert(TimingEvents::s_current_event != this);

View file

@ -9,12 +9,13 @@
class StateWrapper; class StateWrapper;
// Event callback type. Second parameter is the number of cycles the event was executed "late". // Event callback type. Second parameter is the number of cycles the event was executed "late".
using TimingEventCallback = std::function<void(TickCount ticks, TickCount ticks_late)>; using TimingEventCallback = void (*)(void* param, TickCount ticks, TickCount ticks_late);
class TimingEvent class TimingEvent
{ {
public: public:
TimingEvent(std::string name, TickCount period, TickCount interval, TimingEventCallback callback); TimingEvent(std::string name, TickCount period, TickCount interval, TimingEventCallback callback,
void* callback_param);
~TimingEvent(); ~TimingEvent();
ALWAYS_INLINE const std::string& GetName() const { return m_name; } ALWAYS_INLINE const std::string& GetName() const { return m_name; }
@ -59,14 +60,16 @@ public:
TimingEvent* prev = nullptr; TimingEvent* prev = nullptr;
TimingEvent* next = nullptr; TimingEvent* next = nullptr;
TimingEventCallback m_callback;
void* m_callback_param;
TickCount m_downcount; TickCount m_downcount;
TickCount m_time_since_last_run; TickCount m_time_since_last_run;
TickCount m_period; TickCount m_period;
TickCount m_interval; TickCount m_interval;
TimingEventCallback m_callback;
std::string m_name;
bool m_active; bool m_active;
std::string m_name;
}; };
namespace TimingEvents { namespace TimingEvents {
@ -79,7 +82,7 @@ void Shutdown();
/// Creates a new event. /// Creates a new event.
std::unique_ptr<TimingEvent> CreateTimingEvent(std::string name, TickCount period, TickCount interval, std::unique_ptr<TimingEvent> CreateTimingEvent(std::string name, TickCount period, TickCount interval,
TimingEventCallback callback, bool activate); TimingEventCallback callback, void* callback_param, bool activate);
/// Serialization. /// Serialization.
bool DoState(StateWrapper& sw); bool DoState(StateWrapper& sw);
@ -90,6 +93,4 @@ void UpdateCPUDowncount();
TimingEvent** GetHeadEventPtr(); TimingEvent** GetHeadEventPtr();
} // namespace TimingEvents
} // namespace TimingEventManager