iw5-mod/src/module/scheduler.cpp

100 lines
1.9 KiB
C++
Raw Normal View History

2018-12-27 11:11:52 -05:00
#include <std_include.hpp>
#include "scheduler.hpp"
2019-01-16 10:19:21 -05:00
#include "utils/string.hpp"
#include "game/structs.hpp"
#include "game/game.hpp"
2018-12-27 11:11:52 -05:00
std::mutex scheduler::mutex_;
2019-01-16 10:19:21 -05:00
std::queue<std::pair<std::string, int>> scheduler::errors_;
2018-12-27 11:11:52 -05:00
std::vector<std::function<void()>> scheduler::callbacks_;
2018-12-28 06:50:34 -05:00
std::vector<std::function<void()>> scheduler::single_callbacks_;
2018-12-27 11:11:52 -05:00
void scheduler::on_frame(const std::function<void()>& callback)
{
std::lock_guard _(mutex_);
callbacks_.push_back(callback);
}
2018-12-28 06:50:34 -05:00
void scheduler::once(const std::function<void()>& callback)
{
std::lock_guard _(mutex_);
single_callbacks_.push_back(callback);
}
2019-01-16 10:19:21 -05:00
void scheduler::error(const std::string& message, int level)
{
std::lock_guard _(mutex_);
errors_.emplace(message, level);
}
__declspec(naked) void scheduler::execute()
{
__asm
{
call execute_error
call execute_safe
retn
}
}
void scheduler::execute_safe()
2018-12-27 11:11:52 -05:00
{
std::vector<std::function<void()>> callbacks_copy;
2018-12-28 06:50:34 -05:00
std::vector<std::function<void()>> single_callbacks_copy;
2018-12-27 11:11:52 -05:00
{
std::lock_guard _(mutex_);
callbacks_copy = callbacks_;
2018-12-28 06:50:34 -05:00
single_callbacks_copy = single_callbacks_;
single_callbacks_.clear();
2018-12-27 11:11:52 -05:00
}
for (const auto& callback : callbacks_copy)
{
callback();
}
2018-12-28 06:50:34 -05:00
for (const auto& callback : single_callbacks_copy)
{
callback();
}
2018-12-27 11:11:52 -05:00
}
2019-01-16 10:19:21 -05:00
void scheduler::execute_error()
{
const char* message;
int level;
if(get_next_error(&message, &level) && message)
{
game::native::Com_Error(level, "%s", message);
}
}
bool scheduler::get_next_error(const char** error_message, int* error_level)
{
std::lock_guard _(mutex_);
if(errors_.empty())
{
*error_message = nullptr;
return false;
}
const auto error = errors_.front();
errors_.pop();
*error_level = error.second;
*error_message = utils::string::va("%s", error.first.data());
return true;
}
2018-12-27 11:11:52 -05:00
void scheduler::pre_destroy()
{
std::lock_guard _(mutex_);
callbacks_.clear();
2018-12-28 06:50:34 -05:00
single_callbacks_.clear();
2018-12-27 11:11:52 -05:00
}
REGISTER_MODULE(scheduler);