summaryrefslogtreecommitdiffhomepage
path: root/spline/spline.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'spline/spline.hpp')
-rw-r--r--spline/spline.hpp179
1 files changed, 124 insertions, 55 deletions
diff --git a/spline/spline.hpp b/spline/spline.hpp
index 067967b5..780442b9 100644
--- a/spline/spline.hpp
+++ b/spline/spline.hpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, Stanislaw Halik <sthalik@misaki.pl>
+/* Copyright (c) 2012-2019, Stanislaw Halik <sthalik@misaki.pl>
* Permission to use, copy, modify, and/or distribute this
* software for any purpose with or without fee is hereby granted,
@@ -8,13 +8,12 @@
#pragma once
-#include "compat/qcopyable-mutex.hpp"
#include "options/options.hpp"
-#include "compat/util.hpp"
-using namespace options;
-
+#include "axis-opts.hpp"
#include "export.hpp"
+#include "compat/mutex.hpp"
+#include <cstddef>
#include <vector>
#include <limits>
#include <memory>
@@ -26,83 +25,153 @@ using namespace options;
namespace spline_detail {
-class OTR_SPLINE_EXPORT settings final : public QObject
+using points_t = QList<QPointF>;
+using namespace options;
+
+class OTR_SPLINE_EXPORT base_settings : public QObject
{
Q_OBJECT
+
+signals:
+ void recomputed() const;
+};
+
+class OTR_SPLINE_EXPORT settings final : public base_settings
+{
public:
bundle b;
- value<QList<QPointF>> points;
- settings(bundle b);
+ value<QList<QPointF>> points { b, "points", {} };
+ axis_opts opts;
+ settings(bundle const& b, const QString& axis_name, Axis idx);
~settings() override;
-signals:
- void recomputed() const;
};
-}
+struct OTR_SPLINE_EXPORT base_spline_
+{
+ base_spline_() = default;
+ virtual ~base_spline_();
+
+ virtual double get_value(double x) const = 0;
+ virtual double get_value_no_save(double x) const = 0;
+
+ [[nodiscard]] virtual bool get_last_value(QPointF& point) = 0;
+ virtual void set_tracking_active(bool value) const = 0;
-class OTR_SPLINE_EXPORT spline final
+ virtual double max_input() const = 0;
+ virtual double max_output() const = 0;
+
+ virtual const points_t& get_points() const = 0;
+ virtual int get_point_count() const = 0;
+
+ base_spline_(const base_spline_&) = default;
+ base_spline_& operator=(const base_spline_&) = default;
+};
+
+struct OTR_SPLINE_EXPORT spline_settings_mixin
{
- double precision(const QList<QPointF>& points) const;
- void update_interp_data();
- float get_value_internal(int x);
- void add_lone_point();
- float get_value_no_save_internal(double x);
- static bool sort_fn(const QPointF& one, const QPointF& two);
+ virtual std::shared_ptr<base_settings> get_settings() = 0;
+ virtual std::shared_ptr<const base_settings> get_settings() const = 0;
- static QPointF ensure_in_bounds(const QList<QPointF>& points, double max_x, int i);
- static int element_count(const QList<QPointF>& points, double max_x);
+ spline_settings_mixin(const spline_settings_mixin&) = default;
+ spline_settings_mixin& operator=(const spline_settings_mixin&) = default;
- mem<spline_detail::settings> s;
- QMetaObject::Connection connection;
+ spline_settings_mixin() = default;
+ virtual ~spline_settings_mixin();
+};
- std::vector<float> data;
- using interp_data_t = decltype(data);
+struct OTR_SPLINE_EXPORT spline_modify_mixin
+{
+ virtual void add_point(QPointF pt) = 0;
+ virtual void add_point(double x, double y) = 0;
+ virtual void move_point(int idx, QPointF pt) = 0;
+ virtual void remove_point(int i) = 0;
+ virtual void clear() = 0;
+
+ spline_modify_mixin(const spline_modify_mixin&) = default;
+ spline_modify_mixin& operator=(const spline_modify_mixin&) = default;
+
+ spline_modify_mixin() = default;
+ virtual ~spline_modify_mixin();
+};
+
+struct OTR_SPLINE_EXPORT base_spline : base_spline_, spline_modify_mixin, spline_settings_mixin
+{
+ base_spline(const base_spline&) = default;
+ base_spline& operator=(const base_spline&) = default;
+
+ base_spline() = default;
+ ~base_spline() override;
+};
+
+class OTR_SPLINE_EXPORT spline : public base_spline
+{
+ using f = double;
- static constexpr int value_count = 4096;
+ double bucket_size_coefficient(const QList<QPointF>& points) const;
+ void update_interp_data() const;
+ double get_value_internal(int x) const;
+ static bool sort_fn(QPointF one, QPointF two);
- MyMutex _mutex;
- QPointF last_input_value;
- qreal max_x, max_y;
- volatile bool activep;
- bool validp;
+ static void ensure_in_bounds(const QList<QPointF>& points, int i, f& x, f& y);
+ static int element_count(const QList<QPointF>& points, double max_input);
+
+ void disconnect_signals();
+ void invalidate_settings_();
+
+ mutex mtx { mutex::Recursive };
+ std::shared_ptr<settings> s;
+ QMetaObject::Connection conn_points, conn_maxx, conn_maxy;
+
+ std::shared_ptr<QObject> ctx { std::make_shared<QObject>() };
+
+ mutable QPointF last_input_value{-1, -1};
+ mutable std::vector<f> data = std::vector<f>(value_count, magic_fill_value);
+ mutable points_t points;
+ mutable axis_opts::max_clamp clamp_x = axis_opts::x1000, clamp_y = axis_opts::x1000;
+ mutable bool activep = false;
+
+ static constexpr unsigned value_count = 8192;
+ static constexpr f magic_fill_value = -(1 << 24) + 1;
+ static constexpr double c_interp = 5;
public:
- using settings = spline_detail::settings;
+ void invalidate_settings();
void reload();
- void save(QSettings& s);
void save();
- void set_bundle(bundle b);
+ void set_bundle(bundle b, const QString& axis_name, Axis axis);
+
+ double max_input() const override;
+ double max_output() const override;
- qreal max_input() const;
- qreal max_output() const;
spline();
- spline(qreal maxx, qreal maxy, const QString& name);
- ~spline();
+ spline(const QString& name, const QString& axis_name, Axis axis);
+ ~spline() override;
- spline& operator=(const spline&) = default;
spline(const spline&) = default;
- float get_value(double x);
- float get_value_no_save(double x) const;
- DEFUN_WARN_UNUSED bool get_last_value(QPointF& point);
- void remove_point(int i);
- void clear();
+ double get_value(double x) const override;
+ double get_value_no_save(double x) const override;
+ [[nodiscard]] bool get_last_value(QPointF& point) override;
+
+ void add_point(QPointF pt) override;
+ void add_point(double x, double y) override;
+ void move_point(int idx, QPointF pt) override;
+ void remove_point(int i) override;
+ void clear() override;
- void add_point(QPointF pt);
- void add_point(double x, double y);
- void move_point(int idx, QPointF pt);
- QList<QPointF> get_points() const;
- void set_max_input(qreal MaxInput);
- void set_max_output(qreal MaxOutput);
+ const points_t& get_points() const override;
- void set_tracking_active(bool value);
+ void set_tracking_active(bool value) const override;
bundle get_bundle();
- void recompute();
+ void ensure_valid(points_t& in_out) const;
- mem<settings> get_settings();
- mem<const settings> get_settings() const;
+ std::shared_ptr<base_settings> get_settings() override;
+ std::shared_ptr<const base_settings> get_settings() const override;
- using points_t = decltype(s->points());
- int get_point_count() const;
+ int get_point_count() const override;
};
+
+} // ns spline_detail
+
+using spline = spline_detail::spline;