Program Listing for File SyncRealTime.cc#
↰ Return to documentation for file (doxygen_docs/GeneralKModels/SyncRealTime.cc)
#include "Karana/GeneralKModels/SyncRealTime.h"
#include "Karana/KCore/Allocator.h"
#include <cstdlib>
#include <thread>
/**
* @file
* @brief SyncRealTime implementation.
*/
namespace Karana::Models {
namespace kd = Karana::Dynamics;
SyncRealTime::SyncRealTime(std::string_view name,
const kc::ks_ptr<kd::ModelManager> &mm,
double rt_speed)
: KModel<SyncRealTime>(name, mm)
, _rt_speed(rt_speed)
, _enabled(rt_speed > 0) {
const char *dtest_running = std::getenv("DTEST_RUNNING");
if (dtest_running && *dtest_running) {
_enabled = false;
}
};
kc::ks_ptr<SyncRealTime> SyncRealTime::create(std::string_view name,
const kc::ks_ptr<kd::ModelManager> &mm,
double rt_speed) {
kc::ks_ptr<SyncRealTime> srt =
std::allocate_shared<SyncRealTime>(kc::Allocator<SyncRealTime>{}, name, mm, rt_speed);
mm->registerModel(srt);
return srt;
}
void SyncRealTime::preHop(const km::Ktime &t, const km::Vec &) {
if (!_enabled) {
return;
}
_pre_hop_st = t;
_pre_hop_rt = std::chrono::high_resolution_clock::now();
}
void SyncRealTime::postHop(const km::Ktime &t, const km::Vec &) {
if (!_enabled) {
return;
}
auto now = std::chrono::high_resolution_clock::now();
auto sleep_dur = (t - _pre_hop_st) / _rt_speed;
// This check is to avoid weird behavior if the clock changes mid-hop
if (now >= _pre_hop_rt) {
sleep_dur -= now - _pre_hop_rt;
}
std::this_thread::sleep_for(sleep_dur);
}
double SyncRealTime::getRealTimeSpeed() const { return _rt_speed; }
// Destructor included for MacOS builds. Must have a key-function out-of-line to avoid dulpicate
// symbols.
SyncRealTime::~SyncRealTime(){};
} // namespace Karana::Models