#include "gtl_scr_engine_diagnostic.h" #include "core/gtl_logger.h" namespace gtl { namespace scr { engine_diagnostic::engine_diagnostic(QObject* parent) : engine(parent) { _diagnostic = new diagnostic(this); connect(_diagnostic, &diagnostic::stopped, this, &engine_diagnostic::diagnostic_stopped); connect(_diagnostic, &diagnostic::progress_, this, &engine_diagnostic::diagnostic_progress); connect(this, &engine::spec_created, this, &engine_diagnostic::connect_spec); connect(this, &engine::base_index_created, this, &engine_diagnostic::connect_base_index); } bool engine_diagnostic::evaluate(QString program) { _devices_intervals.clear(); _diagnostic->start(); _diagnostic->set_time(0); _diagnose = QJSValue(); if(program.isEmpty()) { gtl::logger::warning("diagnostic engine", "script is empty."); _diagnostic->stop(); return true; } else if(engine::evaluate(program)) { _diagnose = _engine->globalObject().property("diagnose"); if(!_diagnose.isCallable()) { _diagnostic->stop(); gtl::logger::error("engine_diagnostic", tr("can't find diagnose function")); } if(_player) connect(_diagnostic, &diagnostic::stopped, _player, &player::stop); return true; } _diagnostic->stop(); return false; } void engine_diagnostic::init() { engine::init(); _engine->globalObject().property("gtl").setProperty("diagnostic", _engine->newQObject(_diagnostic)); } void engine_diagnostic::device_recieved_data() { if(!_diagnose.isCallable()) return; if(!_diagnostic->is_running()) return; gtl::device* device = static_cast(sender()); qreal rate = 0; if(_player) { device = nullptr; rate = _player->rate(); } else rate = device->rate(); qreal interval = _devices_intervals[device]; auto it = std::find_if(_analog_inputs.begin(), _analog_inputs.end(), [=](QObject* ai){return static_cast(ai)->root() == device;}); if(_player) it = _analog_inputs.begin(); if(it == _analog_inputs.end()) return; if(device) device->lock_ai(); qreal time = static_cast(*it)->size() / rate; // qDebug() << time << interval; interval += time; _diagnostic->set_time(_diagnostic->time() + time); if(qAbs(interval - _diagnostic->interval()) < /*1e-6*/1.0/rate || interval > _diagnostic->interval()) { // qDebug() << _diagnostic->time() << interval << _diagnostic->interval(); QJSValue result = _diagnose.call(); if(result.isError()) gtl::logger::error("engine_diagnostic", result.toString() + " " + tr("at line") + ": " + result.property("lineNumber").toString()); interval -= _diagnostic->interval(); // qDebug() << interval; } if(device) device->unlock_ai(); _devices_intervals[device] = interval; } void engine_diagnostic::connect_spec(spec *spec) { connect(_diagnostic, &diagnostic::stopped, spec, >l::math::spec::stop_acq); } void engine_diagnostic::connect_base_index(math::analog_value *index) { connect(_diagnostic, &diagnostic::stopped, index, >l::math::analog_value::stop_acq); } diagnostic::diagnostic(QObject *parent) : QObject(parent) , _interval(1) , _time(0) , _is_running(false) , _progress(0) { } qreal diagnostic::interval() const { return _interval; } qreal diagnostic::time() const { return _time; } void diagnostic::start() { _is_running = true; } bool diagnostic::is_running() const { return _is_running; } qreal diagnostic::progress() const { return _progress; } void diagnostic::set_interval(qreal value) { if(_interval != value) { qDebug() << "set_interval: " << value; _interval = value; emit interval_changed(); } } void diagnostic::set_time(qreal value) { if(_time != value) { _time = value; emit time_changed(); } } void diagnostic::stop() { if(!_is_running) return; _is_running = false; emit stopped(); } void diagnostic::set_progress(qreal value) { if(value != _progress) { _progress = value; emit progress_changed(); emit progress_(_progress); } } } }