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_;
|
2019-01-20 16:26:18 -05:00
|
|
|
utils::concurrent_list<std::function<void()>> scheduler::callbacks_;
|
|
|
|
utils::concurrent_list<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_);
|
2019-01-20 16:26:18 -05:00
|
|
|
callbacks_.add(callback);
|
2018-12-27 11:11:52 -05:00
|
|
|
}
|
|
|
|
|
2018-12-28 06:50:34 -05:00
|
|
|
void scheduler::once(const std::function<void()>& callback)
|
|
|
|
{
|
|
|
|
std::lock_guard _(mutex_);
|
2019-01-20 16:26:18 -05:00
|
|
|
single_callbacks_.add(callback);
|
2018-12-28 06:50:34 -05:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2019-01-20 16:26:18 -05:00
|
|
|
for (const auto& callback : callbacks_)
|
2018-12-27 11:11:52 -05:00
|
|
|
{
|
2019-01-20 16:26:18 -05:00
|
|
|
(*callback)();
|
2018-12-27 11:11:52 -05:00
|
|
|
}
|
2018-12-28 06:50:34 -05:00
|
|
|
|
2019-01-20 16:26:18 -05:00
|
|
|
for (const auto& callback : single_callbacks_)
|
2018-12-28 06:50:34 -05:00
|
|
|
{
|
2019-01-20 16:26:18 -05:00
|
|
|
(*callback)();
|
2018-12-28 06:50:34 -05:00
|
|
|
}
|
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);
|