Use static polymorphism for gradients.

This commit is contained in:
John Preston 2020-12-14 18:47:33 +04:00
parent d5a076ccef
commit e08a0de35d
2 changed files with 25 additions and 13 deletions

View file

@ -16,7 +16,7 @@ namespace anim {
namespace details { namespace details {
template <typename T> template <typename T, typename Derived>
class gradients { class gradients {
public: public:
gradients(base::flat_map<T, std::vector<QColor>> colors) gradients(base::flat_map<T, std::vector<QColor>> colors)
@ -31,7 +31,7 @@ public:
return _gradients.find(state2)->second; return _gradients.find(state2)->second;
} }
auto gradient = empty_gradient(); auto gradient = static_cast<const Derived*>(this)->empty_gradient();
const auto size = _colors.front().second.size(); const auto size = _colors.front().second.size();
const auto colors1 = _colors.find(state1); const auto colors1 = _colors.find(state1);
const auto colors2 = _colors.find(state2); const auto colors2 = _colors.find(state2);
@ -47,8 +47,6 @@ public:
} }
protected: protected:
virtual QGradient empty_gradient() const = 0;
void cache_gradients() { void cache_gradients() {
_gradients = base::flat_map<T, QGradient>(); _gradients = base::flat_map<T, QGradient>();
for (const auto &[key, value] : _colors) { for (const auto &[key, value] : _colors) {
@ -56,8 +54,9 @@ protected:
} }
} }
private:
QGradient gradient(const std::vector<QColor> &colors) const { QGradient gradient(const std::vector<QColor> &colors) const {
auto gradient = empty_gradient(); auto gradient = static_cast<const Derived*>(this)->empty_gradient();
const auto size = colors.size(); const auto size = colors.size();
for (auto i = 0; i < size; i++) { for (auto i = 0; i < size; i++) {
gradient.setColorAt(i / (size - 1), colors[i]); gradient.setColorAt(i / (size - 1), colors[i]);
@ -73,13 +72,16 @@ protected:
} // namespace details } // namespace details
template <typename T> template <typename T>
class linear_gradients final : public details::gradients<T> { class linear_gradients final
: public details::gradients<T, linear_gradients<T>> {
using parent = details::gradients<T, linear_gradients<T>>;
public: public:
linear_gradients( linear_gradients(
base::flat_map<T, std::vector<QColor>> colors, base::flat_map<T, std::vector<QColor>> colors,
QPointF point1, QPointF point1,
QPointF point2) QPointF point2)
: details::gradients<T>(std::move(colors)) { : parent(std::move(colors)) {
set_points(point1, point2); set_points(point1, point2);
} }
@ -89,26 +91,32 @@ public:
} }
_point1 = point1; _point1 = point1;
_point2 = point2; _point2 = point2;
details::gradients<T>::cache_gradients(); parent::cache_gradients();
} }
private: private:
QGradient empty_gradient() const override { friend class details::gradients<T, linear_gradients<T>>;
QGradient empty_gradient() const {
return QLinearGradient(_point1, _point2); return QLinearGradient(_point1, _point2);
} }
QPointF _point1; QPointF _point1;
QPointF _point2; QPointF _point2;
}; };
template <typename T> template <typename T>
class radial_gradients final : public details::gradients<T> { class radial_gradients final
: public details::gradients<T, radial_gradients<T>> {
using parent = details::gradients<T, radial_gradients<T>>;
public: public:
radial_gradients( radial_gradients(
base::flat_map<T, std::vector<QColor>> colors, base::flat_map<T, std::vector<QColor>> colors,
QPointF center, QPointF center,
float radius) float radius)
: details::gradients<T>(std::move(colors)) { : parent(std::move(colors)) {
set_points(center, radius); set_points(center, radius);
} }
@ -118,16 +126,19 @@ public:
} }
_center = center; _center = center;
_radius = radius; _radius = radius;
details::gradients<T>::cache_gradients(); parent::cache_gradients();
} }
private: private:
QGradient empty_gradient() const override { friend class details::gradients<T, radial_gradients<T>>;
QGradient empty_gradient() const {
return QRadialGradient(_center, _radius); return QRadialGradient(_center, _radius);
} }
QPointF _center; QPointF _center;
float _radius = 0.; float _radius = 0.;
}; };
} // namespace anim } // namespace anim

View file

@ -18,6 +18,7 @@ public:
}; };
Blob(int n, float minSpeed = 0, float maxSpeed = 0); Blob(int n, float minSpeed = 0, float maxSpeed = 0);
virtual ~Blob() = default;
void update(float level, float speedScale); void update(float level, float speedScale);
void generateBlob(); void generateBlob();