flatten 20260225
This commit is contained in:
229
tjp/core/time-obsolete/SchedulerManual.cpp
Normal file
229
tjp/core/time-obsolete/SchedulerManual.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#include "SchedulerManual.hpp"
|
||||
|
||||
#include <core/log/Log.h>
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
SchedulerManual::SchedulerManual(const StrongPtr<TimeSource> &timeSource_) :
|
||||
timeSource (timeSource_),
|
||||
running(false),
|
||||
stopped(false),
|
||||
nextIndex(1)
|
||||
{
|
||||
}
|
||||
|
||||
SchedulerManual::~SchedulerManual()
|
||||
{
|
||||
debug_assert(!running);
|
||||
}
|
||||
|
||||
SchedulerManual::EventImp::EventImp(
|
||||
SchedulerManual *parent_,
|
||||
Time period_,
|
||||
bool repeat_,
|
||||
std::function<void()> &&f_
|
||||
) :
|
||||
parent(parent_),
|
||||
period(period_),
|
||||
repeat(repeat_),
|
||||
f(f_)
|
||||
{
|
||||
}
|
||||
|
||||
SchedulerEventPtr SchedulerManual::schedule_no_lock (const StrongPtr<EventImp> &eventImp, Time now)
|
||||
{
|
||||
debug_assert(mutex.locked_by_caller());
|
||||
|
||||
eventImp->at = { now + eventImp->period, nextIndex++ };
|
||||
|
||||
sLogDebug ("core::time::SchedulerManual", logVar(ptr_of(eventImp)) << logVar(now) << logVar(eventImp->at.time) << logVar(eventImp->period) << logVar(eventImp->repeat));
|
||||
|
||||
auto insertion = events.emplace(eventImp->at, weak(eventImp));
|
||||
debug_assert(insertion.second);
|
||||
debug_assert(eventImp->position == events.end());
|
||||
|
||||
eventImp->position = insertion.first;
|
||||
changed.notify_all();
|
||||
return eventImp;
|
||||
}
|
||||
|
||||
SchedulerEventPtr SchedulerManual::schedule (const StrongPtr<EventImp> &eventImp, Time now)
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
return schedule_no_lock(eventImp, now);
|
||||
}
|
||||
|
||||
SchedulerEventPtr SchedulerManual::schedule (Time period, bool repeat, std::function<void()> &&f)
|
||||
{
|
||||
auto eventImp = strong<EventImp>(
|
||||
this,
|
||||
period,
|
||||
repeat,
|
||||
std::move(f)
|
||||
);
|
||||
|
||||
eventImp->position = events.end();
|
||||
|
||||
schedule(eventImp, timeSource->getTime());
|
||||
return eventImp;
|
||||
}
|
||||
|
||||
void SchedulerManual::EventImp::cancel ()
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
parent->cancel(this);
|
||||
}
|
||||
|
||||
void SchedulerManual::cancel(EventImp *event)
|
||||
{
|
||||
sLogDebug("core::time::scheduler", logVar(event));
|
||||
|
||||
if (event)
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
|
||||
if (event->position != events.end())
|
||||
events.erase(event->position);
|
||||
|
||||
event->position = events.end();
|
||||
changed.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
Duration SchedulerManual::durationUntilNextEvent()
|
||||
{
|
||||
debug_assert(mutex.locked_by_caller());
|
||||
|
||||
if (events.empty())
|
||||
return time::FarFuture;
|
||||
|
||||
return events.begin()->first.time - timeSource->getTime();
|
||||
}
|
||||
|
||||
void SchedulerManual::update_has_lock ()
|
||||
{
|
||||
auto currentTime = EventTime { timeSource->getTime(), nextIndex };
|
||||
|
||||
while (!events.empty())
|
||||
{
|
||||
if (stopped)
|
||||
return;
|
||||
|
||||
auto position = events.begin();
|
||||
auto &event_ = position->second;
|
||||
|
||||
if (position->first < currentTime)
|
||||
{
|
||||
auto event = strong(event_);
|
||||
|
||||
debug_assert(mutex.locked_by_caller());
|
||||
events.erase(position);
|
||||
|
||||
if (event)
|
||||
{
|
||||
event->position = events.end();
|
||||
|
||||
if (event->repeat)
|
||||
{
|
||||
schedule_no_lock(event, currentTime.time);
|
||||
}
|
||||
}
|
||||
|
||||
mutex.unlock();
|
||||
|
||||
if (event)
|
||||
{
|
||||
auto lock = lock_of(event->mutex);
|
||||
|
||||
try
|
||||
{
|
||||
event->f();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
sLogError("core::time::SchedulerManual", "there was a problem houston " << e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
mutex.lock();
|
||||
}
|
||||
};
|
||||
|
||||
void SchedulerManual::run()
|
||||
{
|
||||
running = true;
|
||||
stopped = false;
|
||||
|
||||
mutex.lock();
|
||||
while (!stopped)
|
||||
{
|
||||
auto duration = std::chrono::duration<double>(toReal(durationUntilNextEvent()));
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto then = now + duration;
|
||||
changed.wait_until(mutex, then);
|
||||
|
||||
update_has_lock();
|
||||
}
|
||||
|
||||
running = false;
|
||||
stopped_.notify_all();
|
||||
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void SchedulerManual::cycle()
|
||||
{
|
||||
mutex.lock();
|
||||
running = true;
|
||||
|
||||
if (!events.empty())
|
||||
{
|
||||
update_has_lock();
|
||||
}
|
||||
|
||||
running = false;
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void SchedulerManual::stop ()
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
|
||||
stopped = true;
|
||||
changed.notify_all();
|
||||
}
|
||||
|
||||
void SchedulerManual::clear ()
|
||||
{
|
||||
auto l = lock_of(mutex);
|
||||
for (auto &[id, event_]: events)
|
||||
{
|
||||
if (auto event = strong(event_))
|
||||
{
|
||||
event->position = events.end();
|
||||
}
|
||||
}
|
||||
|
||||
events.clear();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user