maint: fix line endings in the scheduler

This commit is contained in:
FutureRave 2023-02-17 10:58:15 +00:00
parent 83b750d17e
commit a0dedc2a52

View File

@ -1,191 +1,191 @@
#include <std_include.hpp> #include <std_include.hpp>
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
#include "game/game.hpp" #include "game/game.hpp"
#include <utils/hook.hpp> #include <utils/hook.hpp>
#include <utils/concurrency.hpp> #include <utils/concurrency.hpp>
#include <utils/thread.hpp> #include <utils/thread.hpp>
namespace scheduler namespace scheduler
{ {
namespace namespace
{ {
struct task struct task
{ {
std::function<bool()> handler{}; std::function<bool()> handler{};
std::chrono::milliseconds interval{}; std::chrono::milliseconds interval{};
std::chrono::high_resolution_clock::time_point last_call{}; std::chrono::high_resolution_clock::time_point last_call{};
}; };
using task_list = std::vector<task>; using task_list = std::vector<task>;
class task_pipeline class task_pipeline
{ {
public: public:
void add(task&& task) void add(task&& task)
{ {
new_callbacks_.access([&task](task_list& tasks) new_callbacks_.access([&task](task_list& tasks)
{ {
tasks.emplace_back(std::move(task)); tasks.emplace_back(std::move(task));
}); });
} }
void execute() void execute()
{ {
callbacks_.access([&](task_list& tasks) callbacks_.access([&](task_list& tasks)
{ {
this->merge_callbacks(); this->merge_callbacks();
for (auto i = tasks.begin(); i != tasks.end();) for (auto i = tasks.begin(); i != tasks.end();)
{ {
const auto now = std::chrono::high_resolution_clock::now(); const auto now = std::chrono::high_resolution_clock::now();
const auto diff = now - i->last_call; const auto diff = now - i->last_call;
if (diff < i->interval) if (diff < i->interval)
{ {
++i; ++i;
continue; continue;
} }
i->last_call = now; i->last_call = now;
const auto res = i->handler(); const auto res = i->handler();
if (res == cond_end) if (res == cond_end)
{ {
i = tasks.erase(i); i = tasks.erase(i);
} }
else else
{ {
++i; ++i;
} }
} }
}); });
} }
private: private:
utils::concurrency::container<task_list> new_callbacks_; utils::concurrency::container<task_list> new_callbacks_;
utils::concurrency::container<task_list, std::recursive_mutex> callbacks_; utils::concurrency::container<task_list, std::recursive_mutex> callbacks_;
void merge_callbacks() void merge_callbacks()
{ {
callbacks_.access([&](task_list& tasks) callbacks_.access([&](task_list& tasks)
{ {
new_callbacks_.access([&](task_list& new_tasks) new_callbacks_.access([&](task_list& new_tasks)
{ {
tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()),
std::move_iterator(new_tasks.end())); std::move_iterator(new_tasks.end()));
new_tasks = {}; new_tasks = {};
}); });
}); });
} }
}; };
volatile bool kill = false; volatile bool kill = false;
std::thread thread; std::thread thread;
task_pipeline pipelines[pipeline::count]; task_pipeline pipelines[pipeline::count];
utils::hook::detour r_end_frame_hook; utils::hook::detour r_end_frame_hook;
utils::hook::detour g_run_frame_hook; utils::hook::detour g_run_frame_hook;
utils::hook::detour main_frame_hook; utils::hook::detour main_frame_hook;
void r_end_frame_stub() void r_end_frame_stub()
{ {
execute(pipeline::renderer); execute(pipeline::renderer);
r_end_frame_hook.invoke<void>(); r_end_frame_hook.invoke<void>();
} }
void server_frame_stub() void server_frame_stub()
{ {
g_run_frame_hook.invoke<void>(); g_run_frame_hook.invoke<void>();
execute(pipeline::server); execute(pipeline::server);
} }
void main_frame_stub() void main_frame_stub()
{ {
main_frame_hook.invoke<void>(); main_frame_hook.invoke<void>();
execute(pipeline::main); execute(pipeline::main);
} }
} }
void execute(const pipeline type) void execute(const pipeline type)
{ {
assert(type >= 0 && type < pipeline::count); assert(type >= 0 && type < pipeline::count);
pipelines[type].execute(); pipelines[type].execute();
} }
void schedule(const std::function<bool()>& callback, const pipeline type, void schedule(const std::function<bool()>& callback, const pipeline type,
const std::chrono::milliseconds delay) const std::chrono::milliseconds delay)
{ {
assert(type >= 0 && type < pipeline::count); assert(type >= 0 && type < pipeline::count);
task task; task task;
task.handler = callback; task.handler = callback;
task.interval = delay; task.interval = delay;
task.last_call = std::chrono::high_resolution_clock::now(); task.last_call = std::chrono::high_resolution_clock::now();
pipelines[type].add(std::move(task)); pipelines[type].add(std::move(task));
} }
void loop(const std::function<void()>& callback, const pipeline type, void loop(const std::function<void()>& callback, const pipeline type,
const std::chrono::milliseconds delay) const std::chrono::milliseconds delay)
{ {
schedule([callback]() schedule([callback]()
{ {
callback(); callback();
return cond_continue; return cond_continue;
}, type, delay); }, type, delay);
} }
void once(const std::function<void()>& callback, const pipeline type, void once(const std::function<void()>& callback, const pipeline type,
const std::chrono::milliseconds delay) const std::chrono::milliseconds delay)
{ {
schedule([callback]() schedule([callback]()
{ {
callback(); callback();
return cond_end; return cond_end;
}, type, delay); }, type, delay);
} }
struct component final : generic_component struct component final : generic_component
{ {
void post_load() override void post_load() override
{ {
thread = utils::thread::create_named_thread("Async Scheduler", []() thread = utils::thread::create_named_thread("Async Scheduler", []()
{ {
while (!kill) while (!kill)
{ {
execute(pipeline::async); execute(pipeline::async);
std::this_thread::sleep_for(10ms); std::this_thread::sleep_for(10ms);
} }
}); });
} }
void post_unpack() override void post_unpack() override
{ {
if (!game::is_server()) if (!game::is_server())
{ {
r_end_frame_hook.create(0x142273560_g, r_end_frame_stub); r_end_frame_hook.create(0x142273560_g, r_end_frame_stub);
// some func called before R_EndFrame, maybe SND_EndFrame? // some func called before R_EndFrame, maybe SND_EndFrame?
} }
//g_run_frame_hook.create(0x14065C360_g, server_frame_stub); // GlassSv_Update //g_run_frame_hook.create(0x14065C360_g, server_frame_stub); // GlassSv_Update
main_frame_hook.create(game::select(0x1420F9860, 0x1405020E0), main_frame_stub); main_frame_hook.create(game::select(0x1420F9860, 0x1405020E0), main_frame_stub);
// Com_Frame_Try_Block_Function // Com_Frame_Try_Block_Function
} }
void pre_destroy() override void pre_destroy() override
{ {
kill = true; kill = true;
if (thread.joinable()) if (thread.joinable())
{ {
thread.join(); thread.join();
} }
} }
}; };
} }
REGISTER_COMPONENT(scheduler::component) REGISTER_COMPONENT(scheduler::component)