diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 301a1912c..6c19894bc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-added-large-files - id: check-ast @@ -38,7 +38,7 @@ repos: # CPP hooks - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v17.0.6 + rev: v18.1.4 hooks: - id: clang-format args: ['-fallback-style=none', '-i'] diff --git a/plotjuggler_base/include/PlotJuggler/reactive_function.h b/plotjuggler_base/include/PlotJuggler/reactive_function.h index 601cfe43e..55d81a839 100644 --- a/plotjuggler_base/include/PlotJuggler/reactive_function.h +++ b/plotjuggler_base/include/PlotJuggler/reactive_function.h @@ -17,6 +17,12 @@ class CreatedSeriesXY; namespace PJ { +enum class MatchType +{ + Exact, // Returns an index only if the exact time is found + Nearest // Returns the nearest time index (current behavior) +}; + struct TimeseriesRef { TimeseriesRef(PlotData* data); @@ -25,7 +31,10 @@ struct TimeseriesRef void set(unsigned index, double x, double y); - double atTime(double t) const; + double atTime(double t, MatchType match_type) const; + + std::optional + getRawIndexAtTime(double t, MatchType match_type) const; // Method signature updated unsigned size() const; diff --git a/plotjuggler_base/src/reactive_function.cpp b/plotjuggler_base/src/reactive_function.cpp index 27d54d1bf..e331ccca6 100644 --- a/plotjuggler_base/src/reactive_function.cpp +++ b/plotjuggler_base/src/reactive_function.cpp @@ -114,6 +114,7 @@ void ReactiveLuaFunction::prepareLua() _timeseries_ref["at"] = &TimeseriesRef::at; _timeseries_ref["set"] = &TimeseriesRef::set; _timeseries_ref["atTime"] = &TimeseriesRef::atTime; + _timeseries_ref["getRawIndexAtTime"] = &TimeseriesRef::getRawIndexAtTime; _timeseries_ref["clear"] = &TimeseriesRef::clear; //--------------------------------------- @@ -184,10 +185,33 @@ void TimeseriesRef::set(unsigned index, double x, double y) p = { x, y }; } -double TimeseriesRef::atTime(double t) const +double TimeseriesRef::atTime(double t, MatchType match_type) const { - int i = _plot_data->getIndexFromX(t); - return _plot_data->at(i).y; + auto index = getRawIndexAtTime(t, match_type); + if (!index) + { + throw std::runtime_error("Time point not found for exact match requirement"); + } + return _plot_data->at(*index).y; +} + +std::optional TimeseriesRef::getRawIndexAtTime(double t, + MatchType match_type) const +{ + if (match_type == MatchType::Exact) + { + auto it = std::find_if(_plot_data->begin(), _plot_data->end(), + [t](const auto& point) { return point.x == t; }); + if (it != _plot_data->end()) + { + return std::distance(_plot_data->begin(), it); + } + return std::nullopt; // Exact time not found + } + else + { + return _plot_data->getIndexFromX(t); // Nearest match + } } unsigned TimeseriesRef::size() const