flatten 20260225
This commit is contained in:
2
tjp/core/time-obsolete/Notes.txt
Normal file
2
tjp/core/time-obsolete/Notes.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
The scheduler needs to be redone.
|
||||
|
||||
161
tjp/core/time-obsolete/Scheduler+Retry.hpp
Normal file
161
tjp/core/time-obsolete/Scheduler+Retry.hpp
Normal file
@@ -0,0 +1,161 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Scheduler.hpp"
|
||||
#include <core/future/Future.hpp>
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
struct RetryImmediateFailure : Exception
|
||||
{
|
||||
RetryImmediateFailure(Exception &&e) :
|
||||
exception(std::move(e))
|
||||
{}
|
||||
|
||||
Exception exception;
|
||||
} ;
|
||||
|
||||
struct RetryOverrideDelayFailure : Exception
|
||||
{
|
||||
RetryOverrideDelayFailure(Exception &&e, float delay_) :
|
||||
exception(std::move(e)),
|
||||
delay(delay_)
|
||||
{}
|
||||
|
||||
Exception exception;
|
||||
float delay;
|
||||
} ;
|
||||
|
||||
template<typename R, typename G, typename F>
|
||||
void retry_(
|
||||
const typename PromiseOfFutures<R>::Instance &promise,
|
||||
const WeakSchedulerPtr &scheduler_,
|
||||
int remaining, float m,
|
||||
G &&delayF,
|
||||
F &&f,
|
||||
int retries
|
||||
)
|
||||
{
|
||||
promise->add(
|
||||
f().then([promise, scheduler_, remaining, m, delayF=std::move(delayF), f=std::move(f), retries](auto &&future) {
|
||||
sLogDebug("core::time::retry", "time::retry " << logVar(remaining) << logVar(retries) << logVar(m));
|
||||
|
||||
if (remaining == 0)
|
||||
{
|
||||
promise->consume(future);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto executeRetry = [&](int retries, float delay)
|
||||
{
|
||||
if (auto scheduler = strong(scheduler_))
|
||||
{
|
||||
sLogDebug("core::time::retry", "time::retry scheduling try " << logVar(remaining) << logVar(retries) << logVar(m) << logVar(delay));
|
||||
|
||||
promise->add(
|
||||
scheduler->schedule<void>(
|
||||
delay,
|
||||
[promise, scheduler_, remaining, m, delayF=std::move(delayF), f=std::move(f), retries]() {
|
||||
retry_<R>(
|
||||
promise, scheduler_, remaining-1, m,
|
||||
std::move(delayF),
|
||||
std::move(f),
|
||||
retries
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
promise->consume(future_of_exception<R>(NullPointerException{}));
|
||||
}
|
||||
} ;
|
||||
|
||||
try
|
||||
{
|
||||
promise->consume_throw_exception(future);
|
||||
sLogDebug("core::time::retry", "time::retry consume_throw_exception succeeded " << logVar(remaining) << logVar(retries) << logVar(m));
|
||||
}
|
||||
catch (RetryImmediateFailure &e)
|
||||
{
|
||||
sLogDebug("core::time::retry", "time::retry failed RetryImmediateFailure " << logVar(e.what()));
|
||||
|
||||
promise->consume(future_of_exception<R>(std::move(e.exception)));
|
||||
}
|
||||
catch (RetryOverrideDelayFailure &e)
|
||||
{
|
||||
sLogDebug("core::time::retry", "time::retry failed RetryOverrideDelayFailure " << logVar(e.what()));
|
||||
|
||||
executeRetry(
|
||||
retries+1,
|
||||
e.delay
|
||||
);
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
sLogDebug("core::time::retry", "time::retry failed " << logVar(e.what()));
|
||||
|
||||
executeRetry(
|
||||
retries+1,
|
||||
delayF(retries+1, m)
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
template<typename R, typename C, typename F>
|
||||
Future<R> retry_function(const SchedulerPtr &scheduler, int count, float delay, C &&calc, F &&f)
|
||||
{
|
||||
auto promise = PromiseOfFutures<R>::generate();
|
||||
retry_<R>(promise, weak(scheduler), count, delay, std::forward<C>(calc), std::forward<F>(f), 0);
|
||||
return promise->get_future();
|
||||
}
|
||||
|
||||
template<typename R, typename F>
|
||||
Future<R> retry_exponential(const SchedulerPtr &scheduler, int count, float delay, F &&f)
|
||||
{
|
||||
auto expontial = [](int count, float delay) { return (count*count) * delay; };
|
||||
|
||||
return retry_function<R>(scheduler, count, delay, expontial, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename R, typename F>
|
||||
Future<R> retry_linear(const SchedulerPtr &scheduler, int count, float delay, F &&f)
|
||||
{
|
||||
auto linear = [](int count, float delay) { return count * delay; };
|
||||
|
||||
return retry_function<R>(scheduler, count, delay, linear, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename R, typename F>
|
||||
Future<R> retry_constant(const SchedulerPtr &scheduler, int count, float delay, F &&f)
|
||||
{
|
||||
auto constant = [](int count, float delay) { return delay; };
|
||||
|
||||
return retry_function<R>(scheduler, count, delay, constant, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename R, typename F>
|
||||
Future<R> retry(const SchedulerPtr &scheduler, int count, float delay, F &&f)
|
||||
{
|
||||
return retry_linear<R>(scheduler, count, delay, std::forward<F>(f));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
34
tjp/core/time-obsolete/Scheduler.cpp
Normal file
34
tjp/core/time-obsolete/Scheduler.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Scheduler.hpp"
|
||||
|
||||
namespace timprepscius::core::time {
|
||||
|
||||
Scheduler::~Scheduler ()
|
||||
{
|
||||
}
|
||||
|
||||
Future<void> Scheduler::after(Time period)
|
||||
{
|
||||
Promise<void> v;
|
||||
auto event = schedule(
|
||||
period,
|
||||
false,
|
||||
[v]() {
|
||||
auto r = v;
|
||||
r.set_value();
|
||||
}
|
||||
);
|
||||
|
||||
return v.get_future().then([event](auto &&f) { return f.get(); });
|
||||
}
|
||||
|
||||
} // namespace
|
||||
24
tjp/core/time-obsolete/Scheduler.h
Normal file
24
tjp/core/time-obsolete/Scheduler.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/ptr/Ptr.h>
|
||||
|
||||
namespace timprepscius::core::time {
|
||||
|
||||
struct Scheduler;
|
||||
struct SchedulerEvent;
|
||||
using SchedulerEventPtr = StrongPtr<SchedulerEvent>;
|
||||
|
||||
using SchedulerPtr = StrongPtr<Scheduler>;
|
||||
using WeakSchedulerPtr = WeakPtr<Scheduler>;
|
||||
|
||||
} // namespace
|
||||
52
tjp/core/time-obsolete/Scheduler.hpp
Normal file
52
tjp/core/time-obsolete/Scheduler.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Scheduler.h"
|
||||
|
||||
#include <core/future/Future.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include "Time.h"
|
||||
|
||||
namespace timprepscius::core::time {
|
||||
|
||||
struct SchedulerEvent {
|
||||
virtual ~SchedulerEvent () {}
|
||||
virtual void cancel () = 0;
|
||||
} ;
|
||||
|
||||
struct Scheduler
|
||||
{
|
||||
virtual SchedulerEventPtr schedule(Duration period, bool repeat, std::function<void()> &&f) = 0;
|
||||
virtual ~Scheduler();
|
||||
|
||||
Future<void> after(Duration period);
|
||||
|
||||
template<typename T, typename F>
|
||||
Future<T> schedule(Duration period, F &&f);
|
||||
|
||||
template<typename T, typename F>
|
||||
Future<T> schedule_future(Duration period, F &&f);
|
||||
|
||||
template<typename T, typename F>
|
||||
Future<T> schedule(F &&f);
|
||||
|
||||
template<typename T, typename F>
|
||||
Future<T> schedule_future(F &&f);
|
||||
|
||||
template<typename F>
|
||||
void run(F &&f);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "Scheduler.inl"
|
||||
97
tjp/core/time-obsolete/Scheduler.inl
Normal file
97
tjp/core/time-obsolete/Scheduler.inl
Normal file
@@ -0,0 +1,97 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Scheduler.h"
|
||||
|
||||
#include <core/future/Future.hpp>
|
||||
#include <core/future/PromiseOfFutures.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include "Time.h"
|
||||
|
||||
namespace timprepscius::core::time {
|
||||
|
||||
template<typename T, typename F>
|
||||
Future<T> Scheduler::schedule(Duration period, F &&f)
|
||||
{
|
||||
Promise<T> v;
|
||||
auto event = schedule(
|
||||
period,
|
||||
false,
|
||||
[v, f=std::move(f)]() {
|
||||
auto r = v;
|
||||
r.consume(f);
|
||||
}
|
||||
);
|
||||
|
||||
return v.get_future().then([event](auto &&f) { return f.get(); });
|
||||
}
|
||||
|
||||
|
||||
// this should be rewritten to use the above "after", should be much simpler
|
||||
|
||||
template<typename T, typename F>
|
||||
Future<T> Scheduler::schedule_future(Duration period, F &&f_)
|
||||
{
|
||||
auto v = PromiseOfFutures<T>::generate();
|
||||
|
||||
auto execute = Promise<void>();
|
||||
v->add(
|
||||
execute.get_future().then(
|
||||
[v_=weak(v), f=std::move(f_)](auto &&) {
|
||||
if (auto v = strong(v_))
|
||||
{
|
||||
v->add(
|
||||
f().then(
|
||||
[v_](auto &&r) {
|
||||
if (auto v = strong(v_))
|
||||
v->consume(r);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
auto event = schedule(
|
||||
period,
|
||||
false,
|
||||
[execute]() {
|
||||
auto execute_ = execute;
|
||||
execute_.set_value();
|
||||
}
|
||||
);
|
||||
|
||||
return v->get_future().then([event](auto &&f) { return f.get(); });
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename F>
|
||||
Future<T> Scheduler::schedule(F &&f)
|
||||
{
|
||||
return schedule<T>(Immediate, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename T, typename F>
|
||||
Future<T> Scheduler::schedule_future(F &&f)
|
||||
{
|
||||
return schedule_future<T>(Immediate, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void Scheduler::run(F &&f)
|
||||
{
|
||||
return schedule<void>(std::forward<F>(f)).wait();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
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
|
||||
21
tjp/core/time-obsolete/SchedulerManual.h
Normal file
21
tjp/core/time-obsolete/SchedulerManual.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
struct SchedulerManual;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
121
tjp/core/time-obsolete/SchedulerManual.hpp
Normal file
121
tjp/core/time-obsolete/SchedulerManual.hpp
Normal file
@@ -0,0 +1,121 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Scheduler.hpp"
|
||||
|
||||
#include <core/types/Types.h>
|
||||
#include <core/ptr/Ptr.hpp>
|
||||
#include <core/threads/Lock.h>
|
||||
#include <core/allocator/MapAllocator.hpp>
|
||||
#include <core/containers/Map.h>
|
||||
#include <core/threads/Atomic.h>
|
||||
|
||||
#include "TimeSource.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
struct SchedulerManual : Scheduler
|
||||
{
|
||||
struct EventImp;
|
||||
|
||||
struct EventTime
|
||||
{
|
||||
Time time;
|
||||
u64 index;
|
||||
|
||||
bool operator<(const EventTime &rhs) const
|
||||
{
|
||||
if (time == rhs.time)
|
||||
return index < rhs.index;
|
||||
|
||||
return time < rhs.time;
|
||||
}
|
||||
|
||||
bool operator==(const EventTime &rhs) const
|
||||
{
|
||||
return time == rhs.time && index == rhs.index;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
typedef WeakPtr<EventImp> WeakEventPtr;
|
||||
|
||||
typedef core::MapAllocator<EventTime, WeakEventPtr> Allocator;
|
||||
typedef Map<EventTime, WeakEventPtr,std::less<EventTime>,Allocator> Events;
|
||||
|
||||
// typedef Map<EventTime, WeakEventPtr> Events;
|
||||
|
||||
struct EventImp : SchedulerEvent
|
||||
{
|
||||
SchedulerManual *parent;
|
||||
|
||||
Time period;
|
||||
bool repeat;
|
||||
std::function<void()> f;
|
||||
EventTime at;
|
||||
|
||||
RecursiveMutex mutex;
|
||||
Events::iterator position;
|
||||
|
||||
EventImp(
|
||||
SchedulerManual *parent,
|
||||
Time period,
|
||||
bool repeat,
|
||||
std::function<void()> &&f
|
||||
);
|
||||
|
||||
bool operator<(const EventImp &rhs) const
|
||||
{
|
||||
return at < rhs.at;
|
||||
}
|
||||
|
||||
void cancel () override;
|
||||
} ;
|
||||
|
||||
|
||||
Atomic<u64> nextIndex;
|
||||
StrongPtr<TimeSource> timeSource;
|
||||
Mutex mutex;
|
||||
Events events;
|
||||
|
||||
SchedulerManual(const StrongPtr<TimeSource> &timeSource_);
|
||||
~SchedulerManual();
|
||||
|
||||
SchedulerEventPtr schedule (Time period, bool repeat, std::function<void()> &&f) override;
|
||||
SchedulerEventPtr schedule (const StrongPtr<EventImp> &event, Time now);
|
||||
SchedulerEventPtr schedule_no_lock (const StrongPtr<EventImp> &event, Time now);
|
||||
|
||||
void cancel(EventImp *event);
|
||||
Time durationUntilNextEvent();
|
||||
|
||||
Event changed;
|
||||
void update_has_lock();
|
||||
|
||||
bool running, stopped;
|
||||
Event stopped_;
|
||||
|
||||
void run();
|
||||
void cycle();
|
||||
void stop();
|
||||
|
||||
void clear();
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
101
tjp/core/time-obsolete/SchedulerPool.cpp
Normal file
101
tjp/core/time-obsolete/SchedulerPool.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#include "SchedulerPool.hpp"
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
SchedulerPool::SchedulerPool () :
|
||||
nextIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
SchedulerPool::~SchedulerPool ()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
SchedulerEventPtr SchedulerPool::schedule(const SchedulerPtr &scheduler, Time period, std::function<void()> &&f)
|
||||
{
|
||||
auto event = scheduler->schedule(period, true, std::move(f));
|
||||
|
||||
auto lock = lock_of(mutex);
|
||||
events.insert(event);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
SchedulerEventPtr SchedulerPool::once(const SchedulerPtr &scheduler, Time period, std::function<void()> &&f)
|
||||
{
|
||||
auto index = nextIndex++;
|
||||
|
||||
auto weak = weak_this(this);
|
||||
|
||||
// I'm locking before the schedule because, very rarely, the scheduler runs the event
|
||||
// before I can put it in the map, which causes it to stay in the map forever.
|
||||
// If this causes some locking problem in the future, I could also
|
||||
// allocate it in the map, then schedule, and then finally, if the map still
|
||||
// has the entry for it, set it - if not discard.
|
||||
auto lock = lock_of(mutex);
|
||||
|
||||
auto event = scheduler->schedule(
|
||||
period,
|
||||
false,
|
||||
[this, weak, f=std::move(f), index]() {
|
||||
if (auto that = strong(weak))
|
||||
{
|
||||
remove_once(index);
|
||||
f();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onces.emplace(index, event);
|
||||
|
||||
sLogDebug("core::time::SchedulerPool", logOfThis(this) << logVar(index) << logVar(onces.size()) << logVar(period) << logVar(event));
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
void SchedulerPool::remove_once_no_lock(size_t index)
|
||||
{
|
||||
debug_assert(mutex.locked_by_caller());
|
||||
|
||||
auto i = onces.find(index);
|
||||
if (i != onces.end())
|
||||
{
|
||||
sLogDebug("core::time::SchedulerPool", logOfThis(this) << logVar(index) << logVar(onces.size()) << logVar(i->second));
|
||||
|
||||
onces.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLogDebug("core::time::SchedulerPool", logOfThis(this) << logVar(index) << logVar(onces.size()) << logLabel("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void SchedulerPool::remove_once(size_t index)
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
remove_once_no_lock(index);
|
||||
}
|
||||
|
||||
void SchedulerPool::clear ()
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
onces.clear();
|
||||
events.clear();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
21
tjp/core/time-obsolete/SchedulerPool.h
Normal file
21
tjp/core/time-obsolete/SchedulerPool.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
struct SchedulerPool;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
47
tjp/core/time-obsolete/SchedulerPool.hpp
Normal file
47
tjp/core/time-obsolete/SchedulerPool.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SchedulerPool.h"
|
||||
#include "Scheduler.hpp"
|
||||
#include <core/threads/Lock.hpp>
|
||||
#include <core/ptr/Ptr.hpp>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
struct SchedulerPool : StrongThis<SchedulerPool>
|
||||
{
|
||||
QMutex mutex;
|
||||
std::set<SchedulerEventPtr> events;
|
||||
|
||||
std::atomic<size_t> nextIndex;
|
||||
std::map<size_t, SchedulerEventPtr> onces;
|
||||
SchedulerPtr scheduler;
|
||||
|
||||
SchedulerPool();
|
||||
virtual ~SchedulerPool ();
|
||||
|
||||
SchedulerEventPtr schedule(const SchedulerPtr &scheduler, Time period, std::function<void()> &&f);
|
||||
|
||||
SchedulerEventPtr once(const SchedulerPtr &scheduler, Time offset, std::function<void()> &&f);
|
||||
void remove_once(size_t index);
|
||||
void remove_once_no_lock(size_t index);
|
||||
|
||||
void clear();
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
50
tjp/core/time-obsolete/Time+Test.cpp
Normal file
50
tjp/core/time-obsolete/Time+Test.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
/*
|
||||
* Author: Timothy Prepscius
|
||||
* Copyright: See copyright located at COPYRIGHTLOCATION
|
||||
*/
|
||||
|
||||
#include "Time.h"
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#include <core/testing/catch.hpp>
|
||||
|
||||
namespace timprepscius::core::time {
|
||||
|
||||
SCENARIO("time::Time")
|
||||
{
|
||||
GIVEN("a time source")
|
||||
{
|
||||
auto t0 = v1::now();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
auto t1 = v1::now();
|
||||
|
||||
auto dt = t1 - t0;
|
||||
auto mL = 15 * v1::Millisecond;
|
||||
auto mR = 25 * v1::Millisecond;
|
||||
|
||||
auto between = mL < dt && dt < mR;
|
||||
REQUIRE(between);
|
||||
}
|
||||
|
||||
GIVEN("a time source")
|
||||
{
|
||||
auto t0 = v2::now();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
auto t1 = v2::now();
|
||||
|
||||
auto dt = t1 - t0;
|
||||
auto mL = 15 * v2::Millisecond;
|
||||
auto mR = 25 * v2::Millisecond;
|
||||
|
||||
auto between = mL < dt && dt < mR;
|
||||
REQUIRE(between);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
20
tjp/core/time-obsolete/Time.h
Normal file
20
tjp/core/time-obsolete/Time.h
Normal file
@@ -0,0 +1,20 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Time_v1.h"
|
||||
#include "Time_v2.h"
|
||||
|
||||
namespace timprepscius::core::time {
|
||||
|
||||
using namespace v1;
|
||||
|
||||
}
|
||||
39
tjp/core/time-obsolete/TimeSource+Test.cpp
Normal file
39
tjp/core/time-obsolete/TimeSource+Test.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
/*
|
||||
* Author: Timothy Prepscius
|
||||
* Copyright: See copyright located at COPYRIGHTLOCATION
|
||||
*/
|
||||
|
||||
#include "TimeSource.hpp"
|
||||
#include "Time.h"
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#include <core/testing/catch.hpp>
|
||||
|
||||
namespace timprepscius::core::time {
|
||||
|
||||
SCENARIO("time::TimeSource")
|
||||
{
|
||||
GIVEN("a time source")
|
||||
{
|
||||
auto ts = new TimeSourceStandard();
|
||||
|
||||
auto t0 = ts->getTime();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
auto t1 = ts->getTime();
|
||||
|
||||
auto dt = t1 - t0;
|
||||
auto mL = 15 * Millisecond;
|
||||
auto mR = 25 * Millisecond;
|
||||
|
||||
auto between = mL < dt && dt < mR;
|
||||
REQUIRE(between);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace
|
||||
32
tjp/core/time-obsolete/TimeSource.h
Normal file
32
tjp/core/time-obsolete/TimeSource.h
Normal file
@@ -0,0 +1,32 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Server.hpp
|
||||
// TimeSync
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/27/17.
|
||||
// Copyright © 2017 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
class TimeSource;
|
||||
|
||||
template<typename Resolution>
|
||||
class TimeSourceResolution;
|
||||
|
||||
template<typename clock_type_t, typename Resolution>
|
||||
class TimeSourceResolutionStandard;
|
||||
|
||||
class ManualTimeSource;
|
||||
|
||||
class TimeSourceStandard;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
129
tjp/core/time-obsolete/TimeSource.hpp
Normal file
129
tjp/core/time-obsolete/TimeSource.hpp
Normal file
@@ -0,0 +1,129 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Server.hpp
|
||||
// TimeSync
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/27/17.
|
||||
// Copyright © 2017 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "TimeSource.h"
|
||||
#include "Time.h"
|
||||
#include <chrono>
|
||||
|
||||
namespace timprepscius {
|
||||
namespace core {
|
||||
namespace time {
|
||||
|
||||
class TimeSource
|
||||
{
|
||||
public:
|
||||
virtual ~TimeSource () {}
|
||||
|
||||
virtual Time getTime () = 0;
|
||||
virtual size_t getTimeTicks () = 0;
|
||||
virtual Time getTimeAt (size_t ticks) = 0;
|
||||
} ;
|
||||
|
||||
template<typename Resolution>
|
||||
class TimeSourceResolution : public TimeSource
|
||||
{
|
||||
public:
|
||||
typedef Resolution resolution;
|
||||
|
||||
Time getTime () override
|
||||
{
|
||||
return getTimeAt(getTimeTicks());
|
||||
}
|
||||
|
||||
Time getTimeAt (size_t ticks) override
|
||||
{
|
||||
auto denominator = Resolution::period::den;
|
||||
if (time::Denominator == 1)
|
||||
return toTime((time::V)ticks / denominator);
|
||||
|
||||
const auto d0 = time::Denominator;
|
||||
const auto d1 = denominator;
|
||||
|
||||
if (d0 > d1)
|
||||
{
|
||||
V r = d0 / d1;
|
||||
return toTime( (time::V)ticks * r );
|
||||
}
|
||||
else
|
||||
{
|
||||
V r = d1 / d0;
|
||||
return toTime( (time::V)ticks / r );
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
template<typename clock_type_t, typename Resolution = std::chrono::microseconds>
|
||||
class TimeSourceResolutionStandard : public TimeSourceResolution<Resolution>
|
||||
{
|
||||
public:
|
||||
typedef clock_type_t clock_type;
|
||||
|
||||
protected:
|
||||
clock_type clock;
|
||||
typename clock_type::time_point startTime;
|
||||
|
||||
public:
|
||||
TimeSourceResolutionStandard ()
|
||||
{
|
||||
startTime = clock.now();
|
||||
}
|
||||
|
||||
size_t getTimeTicks () override
|
||||
{
|
||||
return std::chrono::duration_cast<Resolution>(clock.now() - startTime).count() + 0;
|
||||
}
|
||||
} ;
|
||||
|
||||
class ManualTimeSource : public TimeSource
|
||||
{
|
||||
protected:
|
||||
TimeSource *source;
|
||||
size_t ticks;
|
||||
|
||||
public:
|
||||
ManualTimeSource(TimeSource *source_) :
|
||||
source(source_)
|
||||
{
|
||||
ticks = source_->getTimeTicks();
|
||||
}
|
||||
|
||||
size_t getTimeTicks () override
|
||||
{
|
||||
return ticks;
|
||||
}
|
||||
|
||||
Time getTime () override
|
||||
{
|
||||
return source->getTimeAt(ticks);
|
||||
}
|
||||
|
||||
Time getTimeAt (size_t ticks) override
|
||||
{
|
||||
return source->getTimeAt(ticks);
|
||||
}
|
||||
|
||||
void update ()
|
||||
{
|
||||
ticks = source->getTimeTicks();
|
||||
}
|
||||
} ;
|
||||
|
||||
class TimeSourceStandard : public TimeSourceResolutionStandard<std::chrono::high_resolution_clock>
|
||||
{
|
||||
public:
|
||||
TimeSourceStandard() {}
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
140
tjp/core/time-obsolete/Time_v1.cpp
Normal file
140
tjp/core/time-obsolete/Time_v1.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Time_v1.h"
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
namespace timprepscius::core::time::v1 {
|
||||
|
||||
Time now()
|
||||
{
|
||||
return getSecondsSince1970();
|
||||
}
|
||||
|
||||
Real toReal(Time v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
Time toTime(Real v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
size_t getMillisecondsSince1970_count()
|
||||
{
|
||||
auto t = std::chrono::duration_cast< std::chrono::milliseconds > (std::chrono::system_clock::now().time_since_epoch());
|
||||
return t.count();
|
||||
}
|
||||
|
||||
size_t getSecondsSince1970_count()
|
||||
{
|
||||
auto t = std::chrono::duration_cast< std::chrono::seconds > (std::chrono::system_clock::now().time_since_epoch());
|
||||
return t.count();
|
||||
}
|
||||
|
||||
|
||||
double getSecondsSince1970 ()
|
||||
{
|
||||
auto t = std::chrono::duration_cast< std::chrono::milliseconds > (
|
||||
std::chrono::system_clock::now().time_since_epoch()
|
||||
);
|
||||
|
||||
return t.count() / 1000.0;
|
||||
}
|
||||
|
||||
double getSecondsSince1970_UTC ()
|
||||
{
|
||||
return getSecondsSince1970();
|
||||
/*
|
||||
std::chrono::system_clock clock;
|
||||
auto now = clock.now();
|
||||
auto timenow = clock.to_time_t(now);
|
||||
|
||||
|
||||
time_t t = ::time(NULL);
|
||||
|
||||
std::tm tm;
|
||||
struct timeval now;
|
||||
struct timezone zone;
|
||||
|
||||
std::memset(&tm, 0, sizeof(tm));
|
||||
std::memset(&now, 0, sizeof(now));
|
||||
std::memset(&zone, 0, sizeof(zone));
|
||||
|
||||
::gmtime_r(&t, &tm);
|
||||
gettimeofday(&now, &zone);
|
||||
|
||||
auto secondsAtNow = ::mktime(&tm);
|
||||
auto partialSeconds = ((double)now.tv_usec)/(1000 * 1000);
|
||||
|
||||
return (double)secondsAtNow + partialSeconds;
|
||||
*/
|
||||
}
|
||||
|
||||
double getUTCFromLocal(double time)
|
||||
{
|
||||
// https://stackoverflow.com/questions/38686405/convert-time-t-from-localtime-zone-to-utc
|
||||
|
||||
std::time_t lt = time;
|
||||
|
||||
std::tm tm;
|
||||
std::memset(&tm, 0, sizeof(tm));
|
||||
|
||||
::gmtime_r(<, &tm);
|
||||
tm.tm_isdst = -1;
|
||||
auto utc = std::mktime(&tm);
|
||||
|
||||
double iptr;
|
||||
|
||||
auto result = utc + modf(time, &iptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// https://arstechnica.com/civis/viewtopic.php?t=136625
|
||||
size_t getLocalFromUTCOffset ()
|
||||
{
|
||||
time_t currtime;
|
||||
|
||||
struct tm * timeinfo;
|
||||
|
||||
::time ( &currtime );
|
||||
|
||||
timeinfo = gmtime ( &currtime );
|
||||
|
||||
time_t utc = mktime( timeinfo );
|
||||
|
||||
timeinfo = localtime ( &currtime );
|
||||
|
||||
time_t local = mktime( timeinfo );
|
||||
|
||||
// Get offset in hours from UTC
|
||||
size_t HOUR_IN_SECONDS = 60 *60;
|
||||
|
||||
double offsetFromUTC = difftime(utc, local);
|
||||
|
||||
// Adjust for DST
|
||||
|
||||
if (timeinfo->tm_isdst)
|
||||
{
|
||||
offsetFromUTC -= 1 * HOUR_IN_SECONDS;
|
||||
}
|
||||
|
||||
return offsetFromUTC;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
45
tjp/core/time-obsolete/Time_v1.h
Normal file
45
tjp/core/time-obsolete/Time_v1.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace timprepscius::core::time::v1 {
|
||||
|
||||
using V = double;
|
||||
using Time = V;
|
||||
using Duration = Time;
|
||||
|
||||
const V Denominator = 1.0;
|
||||
using Real = double;
|
||||
|
||||
const Time Zero = 0;
|
||||
const Duration FarFuture = 10000000000.0;
|
||||
const Duration Immediate = 0;
|
||||
|
||||
const Duration Second = 1.0;
|
||||
const Duration Decisecond = Second / 10;
|
||||
const Duration Centisecond = Second / 100;
|
||||
const Duration Millisecond = Second / 1000;
|
||||
|
||||
size_t getMillisecondsSince1970_count();
|
||||
size_t getSecondsSince1970_count();
|
||||
double getSecondsSince1970 ();
|
||||
double getSecondsSince1970_UTC ();
|
||||
double getUTCFromLocal(double time);
|
||||
|
||||
size_t getLocalFromUTCOffset ();
|
||||
|
||||
Time now();
|
||||
Real toReal(Time t);
|
||||
Time toTime(V v);
|
||||
|
||||
} // namespace
|
||||
51
tjp/core/time-obsolete/Time_v2.cpp
Normal file
51
tjp/core/time-obsolete/Time_v2.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Time_v2.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
#include <chrono>
|
||||
|
||||
namespace timprepscius::core::time::v2 {
|
||||
|
||||
const Duration Millisecond = { 1000 };
|
||||
const Duration Centisecond = { 10 * Millisecond };
|
||||
const Duration Decisecond = { 100 * Millisecond };
|
||||
const Duration Second = { 1000 * Millisecond };
|
||||
const V Denominator = Second.v;
|
||||
|
||||
const Time FarFuture = { std::numeric_limits<V>::max() };
|
||||
|
||||
const Duration Immediate = { 0 };
|
||||
const Time Zero = { 0 };
|
||||
|
||||
std::ostream &operator <<(std::ostream &o, const Duration &v)
|
||||
{
|
||||
return o << v.v;
|
||||
}
|
||||
|
||||
Time now()
|
||||
{
|
||||
auto t = std::chrono::duration_cast< std::chrono::milliseconds > (std::chrono::system_clock::now().time_since_epoch());
|
||||
return (size_t)t.count() * Millisecond;
|
||||
}
|
||||
|
||||
double toReal(Time time)
|
||||
{
|
||||
return (double)time.v / Second.v;
|
||||
}
|
||||
|
||||
Time toTime(V v)
|
||||
{
|
||||
return { v };
|
||||
}
|
||||
|
||||
} // namespace
|
||||
61
tjp/core/time-obsolete/Time_v2.h
Normal file
61
tjp/core/time-obsolete/Time_v2.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/types/Types.h>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace timprepscius::core::time::v2 {
|
||||
|
||||
using V = s64;
|
||||
|
||||
struct Duration {
|
||||
V v;
|
||||
} ;
|
||||
|
||||
using Time = Duration;
|
||||
extern const V Denominator;
|
||||
|
||||
extern const Duration Second;
|
||||
extern const Duration Decisecond;
|
||||
extern const Duration Centisecond;
|
||||
extern const Duration Millisecond;
|
||||
|
||||
extern const Time FarFuture;
|
||||
extern const Duration Immediate;
|
||||
extern const Time Zero;
|
||||
|
||||
Duration operator *(const Duration &lhs, const Duration &rhs);
|
||||
Duration operator /(const Duration &lhs, const Duration &rhs);
|
||||
Duration operator +(const Duration &lhs, const Duration &rhs);
|
||||
Duration operator -(const Duration &lhs, const Duration &rhs);
|
||||
|
||||
bool operator >(const Duration &lhs, const Duration &rhs);
|
||||
bool operator <(const Duration &lhs, const Duration &rhs);
|
||||
bool operator ==(const Duration &lhs, const Duration &rhs);
|
||||
bool operator !=(const Duration &lhs, const Duration &rhs);
|
||||
|
||||
Duration operator *(int, const Duration &rhs);
|
||||
Duration operator *(size_t, const Duration &rhs);
|
||||
Duration operator *(double, const Duration &rhs);
|
||||
Duration operator /(const Duration &rhs, double);
|
||||
Duration operator /(const Duration &rhs, int);
|
||||
Duration operator /(const Duration &rhs, size_t);
|
||||
|
||||
std::ostream &operator <<(std::ostream &o, const Duration &v);
|
||||
|
||||
Time now();
|
||||
double toReal(Time);
|
||||
Time toTime(V v);
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "Time_v2.inl"
|
||||
114
tjp/core/time-obsolete/Time_v2.inl
Normal file
114
tjp/core/time-obsolete/Time_v2.inl
Normal file
@@ -0,0 +1,114 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
//
|
||||
// Timer.h
|
||||
// algorithm
|
||||
//
|
||||
// Created by Timothy Prepscius on 1/19/18.
|
||||
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Time_v2.h"
|
||||
|
||||
namespace timprepscius::core::time::v2 {
|
||||
|
||||
inline
|
||||
Duration operator *(const Duration &lhs, const Duration &rhs)
|
||||
{
|
||||
return { lhs.v * rhs.v };
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator /(const Duration &lhs, const Duration &rhs)
|
||||
{
|
||||
return { lhs.v / rhs.v };
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator +(const Duration &lhs, const Duration &rhs)
|
||||
{
|
||||
return { lhs.v + rhs.v };
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator -(const Duration &lhs, const Duration &rhs)
|
||||
{
|
||||
return { lhs.v - rhs.v };
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator >(const Duration &lhs, const Duration &rhs)
|
||||
{
|
||||
return lhs.v > rhs.v;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator <(const Duration &lhs, const Duration &rhs)
|
||||
{
|
||||
return lhs.v < rhs.v;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const Duration &lhs, const Duration &rhs)
|
||||
{
|
||||
return lhs.v == rhs.v;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator !=(const Duration &lhs, const Duration &rhs)
|
||||
{
|
||||
return lhs.v != rhs.v;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Duration mul(T lhs, const Duration &rhs)
|
||||
{
|
||||
return { (V)(lhs * rhs.v) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Duration dev(const Duration &lhs, T t)
|
||||
{
|
||||
return { (V)(lhs.v / t) };
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator *(int lhs, const Duration &rhs)
|
||||
{
|
||||
return mul(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator *(size_t lhs, const Duration &rhs)
|
||||
{
|
||||
return mul(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator *(double lhs, const Duration &rhs)
|
||||
{
|
||||
return mul(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator /(const Duration &lhs, double rhs)
|
||||
{
|
||||
return dev(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator /(const Duration &lhs, int rhs)
|
||||
{
|
||||
return dev(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
Duration operator /(const Duration &lhs, size_t rhs)
|
||||
{
|
||||
return dev(lhs, rhs);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user