Engine: make task queue singleton static

Compile it as static object & renamed to more correct names. Also made the integral type for frame delay an unsigned int instead
This commit is contained in:
Kawe Mazidjatari 2024-02-28 00:43:57 +01:00
parent 85c7db410d
commit 23a3c8fc00
10 changed files with 37 additions and 30 deletions

View File

@ -135,7 +135,7 @@ void CClientState::VConnectionClosing(CClientState* thisptr, const char* szReaso
// Delay execution to the next frame; this is required to avoid a rare crash.
// Cannot reload playlists while still disconnecting.
g_TaskScheduler->Dispatch([]()
g_TaskQueue.Dispatch([]()
{
// Reload the local playlist to override the cached
// one from the server we got disconnected from.

View File

@ -61,15 +61,15 @@ Runs all active servers
*/
void _Host_RunFrame(void* unused, float time)
{
for (IFrameTask* const& task : g_FrameTasks)
for (IFrameTask* const& task : g_TaskQueueList)
{
task->RunFrame();
}
g_FrameTasks.erase(std::remove_if(g_FrameTasks.begin(), g_FrameTasks.end(), [](const IFrameTask* task)
g_TaskQueueList.erase(std::remove_if(g_TaskQueueList.begin(), g_TaskQueueList.end(), [](const IFrameTask* task)
{
return task->IsFinished();
}), g_FrameTasks.end());
}), g_TaskQueueList.end());
#ifndef DEDICATED
g_TextOverlay.ShouldDraw(time);

View File

@ -30,7 +30,7 @@ void SV_IsClientBanned(CClient* pClient, const string& svIPAddr,
{
if (!ThreadInMainThread())
{
g_TaskScheduler->Dispatch([pClient, svError, svIPAddr, nNucleusID, nPort]
g_TaskQueue.Dispatch([pClient, svError, svIPAddr, nNucleusID, nPort]
{
// Make sure client isn't already disconnected,
// and that if there is a valid netchannel, that
@ -66,7 +66,7 @@ void SV_ProcessBulkCheck(const CBanSystem::BannedList_t* pBannedVec, const bool
if (!ThreadInMainThread())
{
g_TaskScheduler->Dispatch([outBannedVec]
g_TaskQueue.Dispatch([outBannedVec]
{
SV_CheckForBan(outBannedVec, true);
}, 0);

View File

@ -118,7 +118,7 @@ bool CModAppSystemGroup::StaticCreate(CModAppSystemGroup* pModAppSystemGroup)
cv->EnableDevCvars();
}
g_FrameTasks.push_back(std::move(g_TaskScheduler));
g_TaskQueueList.push_back(&g_TaskQueue);
g_bAppSystemInit = true;
return CModAppSystemGroup__Create(pModAppSystemGroup);

View File

@ -368,7 +368,7 @@ void CBrowser::RefreshServerList(void)
std::string svServerListMessage;
g_ServerListManager.RefreshServerList(svServerListMessage);
g_TaskScheduler->Dispatch([&, svServerListMessage]
g_TaskQueue.Dispatch([&, svServerListMessage]
{
SetServerListMessage(svServerListMessage.c_str());
}, 0);
@ -774,7 +774,7 @@ void CBrowser::SendHostingPostRequest(const NetGameServer_t& gameServer)
const bool result = g_MasterServer.PostServerHost(hostRequestMessage, hostToken, hostIp, gameServer);
g_TaskScheduler->Dispatch([&, result, hostRequestMessage, hostToken, hostIp]
g_TaskQueue.Dispatch([&, result, hostRequestMessage, hostToken, hostIp]
{
InstallHostingDetails(result, hostRequestMessage.c_str(), hostToken.c_str(), hostIp);
}, 0);

View File

@ -59,7 +59,7 @@ void CServerListManager::LaunchServer(const bool bChangeLevel) const
{
if (!ThreadInMainThread())
{
g_TaskScheduler->Dispatch([this, bChangeLevel]()
g_TaskQueue.Dispatch([this, bChangeLevel]()
{
this->LaunchServer(bChangeLevel);
}, 0);
@ -90,7 +90,7 @@ void CServerListManager::ConnectToServer(const string& svIp, const int nPort, co
{
if (!ThreadInMainThread())
{
g_TaskScheduler->Dispatch([this, svIp, nPort, svNetKey]()
g_TaskQueue.Dispatch([this, svIp, nPort, svNetKey]()
{
this->ConnectToServer(svIp, nPort, svNetKey);
}, 0);
@ -113,7 +113,7 @@ void CServerListManager::ConnectToServer(const string& svServer, const string& s
{
if (!ThreadInMainThread())
{
g_TaskScheduler->Dispatch([this, svServer, svNetKey]()
g_TaskQueue.Dispatch([this, svServer, svNetKey]()
{
this->ConnectToServer(svServer, svNetKey);
}, 0);
@ -134,7 +134,6 @@ void CServerListManager::ConnectToServer(const string& svServer, const string& s
void CServerListManager::ProcessCommand(const char* pszCommand) const
{
Cbuf_AddText(Cbuf_GetCurrentPlayer(), pszCommand, cmd_source_t::kCommandSrcCode);
//g_TaskScheduler->Dispatch(Cbuf_Execute, 0); // Run in main thread.
}
CServerListManager g_ServerListManager;

View File

@ -1,11 +1,12 @@
#ifndef TIER0_IFRAMETASK_H
#define TIER0_IFRAMETASK_H
struct ScheduledTasks_s
struct QueuedTasks_s
{
int m_nDelayedFrames;
unsigned int m_nDelayedFrames;
std::function<void()> m_rFunctor;
ScheduledTasks_s(int frames, std::function<void()> functor)
QueuedTasks_s(unsigned int frames, std::function<void()> functor)
{
m_nDelayedFrames = frames;
m_rFunctor = functor;
@ -16,6 +17,7 @@ abstract_class IFrameTask
{
public:
virtual ~IFrameTask() {}
virtual void RunFrame() = 0;
virtual bool IsFinished() const = 0;
};

View File

@ -8,7 +8,9 @@
// Committed tasks are scheduled to execute after 'i' frames.
// ----------------------------------------------------------------------------
// A use case for scheduling tasks in the main thread would be (for example)
// calling 'KeyValues::ParsePlaylists(...)' from the render thread.
// performing a web request in a separate thread, and apply the results (such as
// server lists in the browser) onto the imgui panels which are created/drawn in
// the main thread
//=============================================================================//
class CFrameTask : public IFrameTask
{
@ -17,14 +19,14 @@ public:
virtual void RunFrame();
virtual bool IsFinished() const;
void Dispatch(std::function<void()> functor, int frames);
void Dispatch(std::function<void()> functor, unsigned int frames);
private:
mutable std::mutex m_Mutex;
std::list<ScheduledTasks_s> m_ScheduledTasks;
std::list<QueuedTasks_s> m_QueuedTasks;
};
extern std::list<IFrameTask*> g_FrameTasks;
extern CFrameTask* g_TaskScheduler;
extern std::list<IFrameTask*> g_TaskQueueList;
extern CFrameTask g_TaskQueue;
#endif // TIER0_FRAMETASK_H

View File

@ -13,20 +13,24 @@
void CFrameTask::RunFrame()
{
std::lock_guard<std::mutex> l(m_Mutex);
for (auto& delay : m_ScheduledTasks)
for (QueuedTasks_s& delay : m_QueuedTasks)
{
delay.m_nDelayedFrames = (std::max)(delay.m_nDelayedFrames - 1, 0);
if (delay.m_nDelayedFrames == 0)
{
delay.m_rFunctor();
}
--delay.m_nDelayedFrames;
}
auto newEnd = std::remove_if(m_ScheduledTasks.begin(), m_ScheduledTasks.end(), [](const ScheduledTasks_s& delay)
const auto newEnd = std::remove_if(m_QueuedTasks.begin(), m_QueuedTasks.end(),
[](const QueuedTasks_s& delay)
{
return delay.m_nDelayedFrames == 0;
});
m_ScheduledTasks.erase(newEnd, m_ScheduledTasks.end());
m_QueuedTasks.erase(newEnd, m_QueuedTasks.end());
}
//-----------------------------------------------------------------------------
@ -43,12 +47,12 @@ bool CFrameTask::IsFinished() const
// Input : functor -
// frames -
//-----------------------------------------------------------------------------
void CFrameTask::Dispatch(std::function<void()> functor, int frames)
void CFrameTask::Dispatch(std::function<void()> functor, unsigned int frames)
{
std::lock_guard<std::mutex> l(m_Mutex);
m_ScheduledTasks.emplace_back(frames, functor);
m_QueuedTasks.emplace_back(frames, functor);
}
//-----------------------------------------------------------------------------
std::list<IFrameTask*> g_FrameTasks;
CFrameTask* g_TaskScheduler = new CFrameTask();
std::list<IFrameTask*> g_TaskQueueList;
CFrameTask g_TaskQueue;

View File

@ -133,7 +133,7 @@ void Script_Execute(const SQChar* code, const SQCONTEXT context)
if (!ThreadInMainThread())
{
const string scode(code);
g_TaskScheduler->Dispatch([scode, context]()
g_TaskQueue.Dispatch([scode, context]()
{
Script_Execute(scode.c_str(), context);
}, 0);