diff options
Diffstat (limited to 'spline/spline.hpp')
| -rw-r--r-- | spline/spline.hpp | 179 |
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; |
