mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:49:58 +00:00
[Server] Fix iterating killed timers when kill() called in the callback
Instance new timers before new tick
This commit is contained in:
parent
45d3b24c17
commit
1de9f30449
2 changed files with 34 additions and 9 deletions
|
@ -62,7 +62,7 @@ Timer::~Timer()
|
||||||
|
|
||||||
void Timer::tick()
|
void Timer::tick()
|
||||||
{
|
{
|
||||||
if (end)
|
if (end || markedToDelete)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto duration = chrono::system_clock::now().time_since_epoch();
|
const auto duration = chrono::system_clock::now().time_since_epoch();
|
||||||
|
@ -81,6 +81,11 @@ void Timer::tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Timer::kill()
|
||||||
|
{
|
||||||
|
markedToDelete = true;
|
||||||
|
}
|
||||||
|
|
||||||
void TimerController::Init(LuaState &lua)
|
void TimerController::Init(LuaState &lua)
|
||||||
{
|
{
|
||||||
sol::table timerTable = lua.getState()->create_table("TimerCtrl");
|
sol::table timerTable = lua.getState()->create_table("TimerCtrl");
|
||||||
|
@ -96,22 +101,37 @@ void TimerController::Init(LuaState &lua)
|
||||||
|
|
||||||
std::shared_ptr<Timer> TimerController::create(sol::environment env, sol::function callback, long msec, sol::table args)
|
std::shared_ptr<Timer> TimerController::create(sol::environment env, sol::function callback, long msec, sol::table args)
|
||||||
{
|
{
|
||||||
timers.emplace_back(new Timer(env, callback, msec, args));
|
newTimersQueue.emplace_back(new Timer(env, callback, msec, args));
|
||||||
return timers.back();
|
return newTimersQueue.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerController::kill(const std::shared_ptr<Timer> &timer)
|
void TimerController::kill(const std::shared_ptr<Timer> &timer)
|
||||||
{
|
{
|
||||||
auto it = find(timers.begin(), timers.end(), timer);
|
LOG_MESSAGE_SIMPLE(Log::LOG_TRACE, "Timer %p marked for deletion\n", timer.get());
|
||||||
if (it != timers.end())
|
timer->kill();
|
||||||
{
|
haveMarkedToDeletion = true;
|
||||||
LOG_MESSAGE_SIMPLE(Log::LOG_TRACE, "Timer %p killed\n", timer.get());
|
|
||||||
timers.erase(it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerController::tick()
|
void TimerController::tick()
|
||||||
{
|
{
|
||||||
|
if (haveMarkedToDeletion)
|
||||||
|
{
|
||||||
|
size_t deleted = timers.size();
|
||||||
|
haveMarkedToDeletion = false;
|
||||||
|
timers.erase(remove_if(timers.begin(), timers.end(), [](const std::shared_ptr<Timer> &timer) {
|
||||||
|
return timer->isMarkedToDelete();
|
||||||
|
}), timers.end());
|
||||||
|
deleted -= timers.size();
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::LOG_TRACE, "Deleted %d timers\n", deleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!newTimersQueue.empty())
|
||||||
|
{
|
||||||
|
timers.insert(timers.begin(), make_move_iterator(newTimersQueue.begin()), make_move_iterator(newTimersQueue.end()));
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::LOG_TRACE, "Created %d timers\n", newTimersQueue.size());
|
||||||
|
newTimersQueue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &timer : timers)
|
for (auto &timer : timers)
|
||||||
{
|
{
|
||||||
timer->tick();
|
timer->tick();
|
||||||
|
|
|
@ -24,12 +24,15 @@ public:
|
||||||
protected:
|
protected:
|
||||||
Timer(sol::environment &env, sol::function &callback, long msec, sol::table &args);
|
Timer(sol::environment &env, sol::function &callback, long msec, sol::table &args);
|
||||||
void tick();
|
void tick();
|
||||||
|
void kill();
|
||||||
|
bool isMarkedToDelete() const { return markedToDelete; }
|
||||||
private:
|
private:
|
||||||
double startTime, targetMsec;
|
double startTime, targetMsec;
|
||||||
sol::function callback;
|
sol::function callback;
|
||||||
sol::table data;
|
sol::table data;
|
||||||
sol::environment env;
|
sol::environment env;
|
||||||
bool end;
|
bool end;
|
||||||
|
bool markedToDelete;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TimerController
|
class TimerController
|
||||||
|
@ -44,5 +47,7 @@ public:
|
||||||
void tick();
|
void tick();
|
||||||
private:
|
private:
|
||||||
std::vector<std::shared_ptr<Timer>> timers;
|
std::vector<std::shared_ptr<Timer>> timers;
|
||||||
|
std::vector<std::shared_ptr<Timer>> newTimersQueue;
|
||||||
|
bool haveMarkedToDeletion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue