Initial commit

This commit is contained in:
Michal 2026-01-11 18:57:42 +04:00 • committed by GitHub
commit 3dd53cf457
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
105 changed files with 35670 additions and 0 deletions

160
src/tasks.cpp Normal file
View file

@ -0,0 +1,160 @@
//
// Created by Michal Přikryl on 10.07.2025.
// Copyright (c) 2025 slynxcz. All rights reserved.
//
#include "tasks.h"
#include <algorithm>
#include <chrono>
#include <mutex>
#include <queue>
namespace TemplatePlugin {
double universal_time = 0.0;
double last_tick_time = 0.0;
double timer_next_think = 0.0;
namespace {
std::vector<Timer *> once_off_timers;
std::vector<Timer *> repeat_timers;
std::mutex nextFrameMutex;
std::queue<std::function<void()> > nextFrameQueue;
}
void Tasks::NextFrame(std::function<void()> &&task) {
std::lock_guard lock(nextFrameMutex);
nextFrameQueue.emplace(std::move(task));
}
Timer::Timer(float interval, double execTime, TimerCallback callback, int flags)
: Interval(interval), ExecTime(execTime), Callback(std::move(callback)), Flags(flags) {
}
void Tasks::Init() {
universal_time = 0.0;
last_tick_time = 0.0;
timer_next_think = 0.0;
}
void Tasks::Shutdown() {
for (auto *timer: once_off_timers)
delete timer;
for (auto *timer: repeat_timers)
delete timer;
once_off_timers.clear();
repeat_timers.clear();
std::lock_guard lock(nextFrameMutex);
std::queue<std::function<void()> > empty;
std::swap(nextFrameQueue, empty);
}
void Tasks::Tick(bool simulating) {
std::queue<std::function<void()>> localQueue;
{
std::lock_guard lock(nextFrameMutex);
std::swap(localQueue, nextFrameQueue);
}
while (!localQueue.empty()) {
try {
localQueue.front()();
} catch (...) {
}
localQueue.pop();
}
double now = std::chrono::duration_cast<std::chrono::duration<float> >(
std::chrono::steady_clock::now().time_since_epoch()).count();
if (simulating)
universal_time += now - last_tick_time;
else
universal_time += 0.015;
last_tick_time = now;
if (universal_time < timer_next_think)
return;
for (int i = static_cast<int>(once_off_timers.size()) - 1; i >= 0; --i) {
Timer *timer = once_off_timers[i];
if (universal_time >= timer->ExecTime) {
timer->InExec = true;
try {
timer->Callback();
} catch (...) {
}
delete timer;
once_off_timers.erase(once_off_timers.begin() + i);
}
}
for (int i = static_cast<int>(repeat_timers.size()) - 1; i >= 0; --i) {
Timer *timer = repeat_timers[i];
if (universal_time >= timer->ExecTime) {
timer->InExec = true;
try {
timer->Callback();
} catch (...) {
}
if (timer->KillMe) {
delete timer;
repeat_timers.erase(repeat_timers.begin() + i);
continue;
}
timer->InExec = false;
timer->ExecTime = universal_time + timer->Interval;
}
}
timer_next_think = universal_time + 0.1;
}
Timer *Tasks::AddTimer(float interval, TimerCallback callback, int flags) {
Timer *timer = new Timer(interval, universal_time + interval, std::move(callback), flags);
if (flags & TIMER_FLAG_REPEAT)
repeat_timers.push_back(timer);
else
once_off_timers.push_back(timer);
return timer;
}
void Tasks::KillTimer(Timer *timer) {
if (!timer) return;
auto killFrom = [](std::vector<Timer *> &list, Timer *target) {
auto it = std::remove_if(list.begin(), list.end(), [=](Timer *t) { return t == target; });
if (it != list.end()) {
delete target;
list.erase(it, list.end());
}
};
if (timer->InExec) {
timer->KillMe = true;
return;
}
if (timer->Flags & TIMER_FLAG_REPEAT)
killFrom(repeat_timers, timer);
else
killFrom(once_off_timers, timer);
}
void Tasks::RemoveMapChangeTimers() {
auto removeFrom = [](std::vector<Timer*>& list) {
for (int i = static_cast<int>(list.size()) - 1; i >= 0; --i) {
Timer* t = list[i];
if (t->Flags & TIMER_FLAG_NO_MAPCHANGE) {
delete t;
list.erase(list.begin() + i);
}
}
};
removeFrom(once_off_timers);
removeFrom(repeat_timers);
}
}