Program Listing for File SyncRealTime.cc

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