From 5642ed331df56375c55cd8d56a14054af8bdf8f2 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:55:14 +0000 Subject: core: move parts of the animation system to hyprutils (#8868) * core: change animation manager to use Hyprutils::Animation * config: move animation config to hyprutils animation tree * use g_pAnimationManager->createAnimation and the new PHLANIMVAR template * core: use CGenericAnimatedVariabled::{enabled,setConfig,getStyle} and adapt callbacks * core: adapt animated variable usage (dereference the shared pointer) * misc: bump CMakeLists to hyprutils 0.3.3 --- src/helpers/AnimatedVariable.cpp | 87 ------------- src/helpers/AnimatedVariable.hpp | 275 +++------------------------------------ src/helpers/BezierCurve.cpp | 90 ------------- src/helpers/BezierCurve.hpp | 28 ---- src/helpers/Monitor.cpp | 8 +- src/helpers/WLClasses.hpp | 1 - 6 files changed, 23 insertions(+), 466 deletions(-) delete mode 100644 src/helpers/AnimatedVariable.cpp delete mode 100644 src/helpers/BezierCurve.cpp delete mode 100644 src/helpers/BezierCurve.hpp (limited to 'src/helpers') diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp deleted file mode 100644 index ab5643a6..00000000 --- a/src/helpers/AnimatedVariable.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "AnimatedVariable.hpp" -#include "../managers/AnimationManager.hpp" -#include "../config/ConfigManager.hpp" - -CBaseAnimatedVariable::CBaseAnimatedVariable(eAnimatedVarType type) : m_Type(type) { - ; // dummy var -} - -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy) { - m_eDamagePolicy = policy; - m_pConfig = pAnimConfig; - m_pWindow = pWindow; - - m_bDummy = false; -} - -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy) { - m_eDamagePolicy = policy; - m_pConfig = pAnimConfig; - m_pLayer = pLayer; - - m_bDummy = false; -} - -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy) { - m_eDamagePolicy = policy; - m_pConfig = pAnimConfig; - m_pWorkspace = pWorkspace; - - m_bDummy = false; -} - -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy) { - m_eDamagePolicy = policy; - m_pConfig = pAnimConfig; - - m_bDummy = false; -} - -CBaseAnimatedVariable::~CBaseAnimatedVariable() { - unregister(); -} - -void CBaseAnimatedVariable::unregister() { - if (!g_pAnimationManager) - return; - std::erase_if(g_pAnimationManager->m_vAnimatedVariables, [&](const auto& other) { return other == this; }); - m_bIsRegistered = false; - disconnectFromActive(); -} - -void CBaseAnimatedVariable::registerVar() { - if (!m_bIsRegistered) - g_pAnimationManager->m_vAnimatedVariables.push_back(this); - m_bIsRegistered = true; -} - -float CBaseAnimatedVariable::getPercent() { - const auto DURATIONPASSED = std::chrono::duration_cast(std::chrono::steady_clock::now() - animationBegin).count(); - return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f); -} - -float CBaseAnimatedVariable::getCurveValue() { - if (!m_bIsBeingAnimated) - return 1.f; - - const auto SPENT = getPercent(); - - if (SPENT >= 1.f) - return 1.f; - - return g_pAnimationManager->getBezier(m_pConfig->pValues->internalBezier)->getYForPoint(SPENT); -} - -void CBaseAnimatedVariable::connectToActive() { - g_pAnimationManager->scheduleTick(); // otherwise the animation manager will never pick this up - - if (!m_bIsConnectedToActive) - g_pAnimationManager->m_vActiveAnimatedVariables.push_back(this); - - m_bIsConnectedToActive = true; -} - -void CBaseAnimatedVariable::disconnectFromActive() { - std::erase_if(g_pAnimationManager->m_vActiveAnimatedVariables, [&](const auto& other) { return other == this; }); - m_bIsConnectedToActive = false; -} diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index a1da00da..e7d5fd8c 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -1,15 +1,18 @@ #pragma once -#include -#include -#include -#include -#include "math/Math.hpp" +#include + #include "Color.hpp" #include "../defines.hpp" -#include "../debug/Log.hpp" #include "../desktop/DesktopTypes.hpp" +enum eAVarDamagePolicy : int8_t { + AVARDAMAGE_NONE = -1, + AVARDAMAGE_ENTIRE = 0, + AVARDAMAGE_BORDER, + AVARDAMAGE_SHADOW +}; + enum eAnimatedVarType : int8_t { AVARTYPE_INVALID = -1, AVARTYPE_FLOAT, @@ -42,20 +45,6 @@ struct STypeToAnimatedVarType_t { template inline constexpr eAnimatedVarType typeToeAnimatedVarType = STypeToAnimatedVarType_t::value; -enum eAVarDamagePolicy : int8_t { - AVARDAMAGE_NONE = -1, - AVARDAMAGE_ENTIRE = 0, - AVARDAMAGE_BORDER, - AVARDAMAGE_SHADOW -}; - -class CAnimationManager; -struct SAnimationPropertyConfig; -class CHyprRenderer; -class CWindow; -class CWorkspace; -class CLayerSurface; - // Utility to define a concept as a list of possible type template concept OneOf = (... or std::same_as); @@ -66,245 +55,19 @@ concept OneOf = (... or std::same_as); template concept Animable = OneOf; -class CBaseAnimatedVariable { - public: - CBaseAnimatedVariable(eAnimatedVarType type); - void create(SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy); - void create(SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy); - void create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy); - void create(SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy); - - CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete; - CBaseAnimatedVariable(CBaseAnimatedVariable&&) = delete; - CBaseAnimatedVariable& operator=(const CBaseAnimatedVariable&) = delete; - CBaseAnimatedVariable& operator=(CBaseAnimatedVariable&&) = delete; - - virtual ~CBaseAnimatedVariable(); - - void unregister(); - void registerVar(); - - virtual void warp(bool endCallback = true) = 0; - - // - void setConfig(SAnimationPropertyConfig* pConfig) { - m_pConfig = pConfig; - } - - SAnimationPropertyConfig* getConfig() { - return m_pConfig; - } - - /* returns the spent (completion) % */ - float getPercent(); - - /* returns the current curve value */ - float getCurveValue(); - - // checks if an animation is in progress - bool isBeingAnimated() const { - return m_bIsBeingAnimated; - } - - /* sets a function to be ran when the animation finishes. - if an animation is not running, runs instantly. - if "remove" is set to true, will remove the callback when ran. */ - void setCallbackOnEnd(std::function func, bool remove = true) { - m_fEndCallback = std::move(func); - m_bRemoveEndAfterRan = remove; - - if (!isBeingAnimated()) - onAnimationEnd(); - } - - /* sets a function to be ran when an animation is started. - if "remove" is set to true, will remove the callback when ran. */ - void setCallbackOnBegin(std::function func, bool remove = true) { - m_fBeginCallback = std::move(func); - m_bRemoveBeginAfterRan = remove; - } - - /* Sets the update callback, called every time the value is animated and a step is done - Warning: calling unregisterVar/registerVar in this handler will cause UB */ - void setUpdateCallback(std::function func) { - m_fUpdateCallback = std::move(func); - } - - /* resets all callbacks. Does not call any. */ - void resetAllCallbacks() { - m_fBeginCallback = nullptr; - m_fEndCallback = nullptr; - m_fUpdateCallback = nullptr; - m_bRemoveBeginAfterRan = false; - m_bRemoveEndAfterRan = false; - } - - PHLWINDOW getWindow() { - return m_pWindow.lock(); - } - - protected: - PHLWINDOWREF m_pWindow; - PHLWORKSPACEREF m_pWorkspace; - PHLLSREF m_pLayer; - - SAnimationPropertyConfig* m_pConfig = nullptr; - - bool m_bDummy = true; - bool m_bIsRegistered = false; - bool m_bIsBeingAnimated = false; +struct SAnimationContext { + PHLWINDOWREF pWindow; + PHLWORKSPACEREF pWorkspace; + PHLLSREF pLayer; - std::chrono::steady_clock::time_point animationBegin; - - eAVarDamagePolicy m_eDamagePolicy = AVARDAMAGE_NONE; - eAnimatedVarType m_Type; - - bool m_bRemoveEndAfterRan = true; - bool m_bRemoveBeginAfterRan = true; - std::function m_fEndCallback; - std::function m_fBeginCallback; - std::function m_fUpdateCallback; - - bool m_bIsConnectedToActive = false; - - void connectToActive(); - - void disconnectFromActive(); - - // methods - void onAnimationEnd() { - m_bIsBeingAnimated = false; - disconnectFromActive(); - - if (m_fEndCallback) { - // loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false. - auto removeEndCallback = m_bRemoveEndAfterRan; - m_fEndCallback(this); - if (removeEndCallback) - m_fEndCallback = nullptr; // reset - } - } - - void onAnimationBegin() { - m_bIsBeingAnimated = true; - connectToActive(); - - if (m_fBeginCallback) { - m_fBeginCallback(this); - if (m_bRemoveBeginAfterRan) - m_fBeginCallback = nullptr; // reset - } - } - - friend class CAnimationManager; - friend class CWorkspace; - friend class CLayerSurface; - friend class CHyprRenderer; + eAVarDamagePolicy eDamagePolicy = AVARDAMAGE_NONE; }; template -class CAnimatedVariable : public CBaseAnimatedVariable { - public: - CAnimatedVariable() : CBaseAnimatedVariable(typeToeAnimatedVarType) { - ; - } // dummy var - - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy) { - create(pAnimConfig, pWindow, policy); - m_Value = value; - m_Goal = value; - } - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy) { - create(pAnimConfig, pLayer, policy); - m_Value = value; - m_Goal = value; - } - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy) { - create(pAnimConfig, pWorkspace, policy); - m_Value = value; - m_Goal = value; - } - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy) { - create(pAnimConfig, policy); - m_Value = value; - m_Goal = value; - } - - using CBaseAnimatedVariable::create; - - CAnimatedVariable(const CAnimatedVariable&) = delete; - CAnimatedVariable(CAnimatedVariable&&) = delete; - CAnimatedVariable& operator=(const CAnimatedVariable&) = delete; - CAnimatedVariable& operator=(CAnimatedVariable&&) = delete; - - ~CAnimatedVariable() = default; - - // gets the current vector value (real time) - const VarType& value() const { - return m_Value; - } - - // gets the goal vector value - const VarType& goal() const { - return m_Goal; - } - - CAnimatedVariable& operator=(const VarType& v) { - if (v == m_Goal) - return *this; +using CAnimatedVariable = Hyprutils::Animation::CGenericAnimatedVariable; - m_Goal = v; - animationBegin = std::chrono::steady_clock::now(); - m_Begun = m_Value; - - onAnimationBegin(); - - return *this; - } - - // Sets the actual stored value, without affecting the goal, but resets the timer - void setValue(const VarType& v) { - if (v == m_Value) - return; - - m_Value = v; - animationBegin = std::chrono::steady_clock::now(); - m_Begun = m_Value; - - onAnimationBegin(); - } - - // Sets the actual value and goal - void setValueAndWarp(const VarType& v) { - m_Goal = v; - m_bIsBeingAnimated = true; - warp(); - } - - void warp(bool endCallback = true) override { - if (!m_bIsBeingAnimated) - return; - - m_Value = m_Goal; - - m_bIsBeingAnimated = false; - - if (m_fUpdateCallback) - m_fUpdateCallback(this); - - if (endCallback) - onAnimationEnd(); - } - - private: - VarType m_Value{}; - VarType m_Goal{}; - VarType m_Begun{}; - - // owners +template +using PHLANIMVAR = SP>; - friend class CAnimationManager; - friend class CWorkspace; - friend class CLayerSurface; - friend class CHyprRenderer; -}; +template +using PHLANIMVARREF = WP>; diff --git a/src/helpers/BezierCurve.cpp b/src/helpers/BezierCurve.cpp deleted file mode 100644 index a0610fc9..00000000 --- a/src/helpers/BezierCurve.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "BezierCurve.hpp" -#include "../debug/Log.hpp" -#include "../macros.hpp" - -#include -#include - -void CBezierCurve::setup(std::vector* pVec) { - const auto BEGIN = std::chrono::high_resolution_clock::now(); - - // Avoid reallocations by reserving enough memory upfront - m_vPoints.resize(pVec->size() + 2); - m_vPoints[0] = Vector2D(0, 0); // Start point - size_t index = 1; // Start after the first element - for (const auto& vec : *pVec) { - if (index < m_vPoints.size() - 1) { // Bounds check to ensure safety - m_vPoints[index] = vec; - ++index; - } - } - m_vPoints.back() = Vector2D(1, 1); // End point - - RASSERT(m_vPoints.size() == 4, "CBezierCurve only supports cubic beziers! (points num: {})", m_vPoints.size()); - - // bake BAKEDPOINTS points for faster lookups - // T -> X ( / BAKEDPOINTS ) - for (int i = 0; i < BAKEDPOINTS; ++i) { - float const t = (i + 1) / (float)BAKEDPOINTS; - m_aPointsBaked[i] = Vector2D(getXForT(t), getYForT(t)); - } - - const auto ELAPSEDUS = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - BEGIN).count() / 1000.f; - const auto POINTSSIZE = m_aPointsBaked.size() * sizeof(m_aPointsBaked[0]) / 1000.f; - - const auto BEGINCALC = std::chrono::high_resolution_clock::now(); - for (int j = 1; j < 10; ++j) { - float i = j / 10.0f; - getYForPoint(i); - } - const auto ELAPSEDCALCAVG = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - BEGINCALC).count() / 1000.f / 10.f; - - Debug::log(LOG, "Created a bezier curve, baked {} points, mem usage: {:.2f}kB, time to bake: {:.2f}µs. Estimated average calc time: {:.2f}µs.", BAKEDPOINTS, POINTSSIZE, - ELAPSEDUS, ELAPSEDCALCAVG); -} - -float CBezierCurve::getXForT(float const& t) const { - float t2 = t * t; - float t3 = t2 * t; - - return 3 * t * (1 - t) * (1 - t) * m_vPoints[1].x + 3 * t2 * (1 - t) * m_vPoints[2].x + t3 * m_vPoints[3].x; -} - -float CBezierCurve::getYForT(float const& t) const { - float t2 = t * t; - float t3 = t2 * t; - - return 3 * t * (1 - t) * (1 - t) * m_vPoints[1].y + 3 * t2 * (1 - t) * m_vPoints[2].y + t3 * m_vPoints[3].y; -} - -// Todo: this probably can be done better and faster -float CBezierCurve::getYForPoint(float const& x) const { - if (x >= 1.f) - return 1.f; - if (x <= 0.f) - return 0.f; - - int index = 0; - bool below = true; - for (int step = (BAKEDPOINTS + 1) / 2; step > 0; step /= 2) { - if (below) - index += step; - else - index -= step; - - below = m_aPointsBaked[index].x < x; - } - - int lowerIndex = index - (!below || index == BAKEDPOINTS - 1); - - // in the name of performance i shall make a hack - const auto LOWERPOINT = &m_aPointsBaked[lowerIndex]; - const auto UPPERPOINT = &m_aPointsBaked[lowerIndex + 1]; - - const auto PERCINDELTA = (x - LOWERPOINT->x) / (UPPERPOINT->x - LOWERPOINT->x); - - if (std::isnan(PERCINDELTA) || std::isinf(PERCINDELTA)) // can sometimes happen for VERY small x - return 0.f; - - return LOWERPOINT->y + (UPPERPOINT->y - LOWERPOINT->y) * PERCINDELTA; -} diff --git a/src/helpers/BezierCurve.hpp b/src/helpers/BezierCurve.hpp deleted file mode 100644 index e643fb41..00000000 --- a/src/helpers/BezierCurve.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include -#include -#include "math/Math.hpp" - -constexpr int BAKEDPOINTS = 255; -constexpr float INVBAKEDPOINTS = 1.f / BAKEDPOINTS; - -// an implementation of a cubic bezier curve -// might do better later -class CBezierCurve { - public: - // sets up the bezier curve. - // this EXCLUDES the 0,0 and 1,1 points, - void setup(std::vector* points); - - float getYForT(float const& t) const; - float getXForT(float const& t) const; - float getYForPoint(float const& x) const; - - private: - // this INCLUDES the 0,0 and 1,1 points. - std::vector m_vPoints; - - std::array m_aPointsBaked; -}; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 76df00b3..e833e661 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1127,16 +1127,16 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { if (w->m_bIsFloating && !VECINRECT(MIDDLE, vecPosition.x, vecPosition.y, vecPosition.x + vecSize.x, vecPosition.y + vecSize.y) && !w->isX11OverrideRedirect()) { // if it's floating and the middle isnt on the current mon, move it to the center const auto PMONFROMMIDDLE = g_pCompositor->getMonitorFromVector(MIDDLE); - Vector2D pos = w->m_vRealPosition.goal(); + Vector2D pos = w->m_vRealPosition->goal(); if (!VECINRECT(MIDDLE, PMONFROMMIDDLE->vecPosition.x, PMONFROMMIDDLE->vecPosition.y, PMONFROMMIDDLE->vecPosition.x + PMONFROMMIDDLE->vecSize.x, PMONFROMMIDDLE->vecPosition.y + PMONFROMMIDDLE->vecSize.y)) { // not on any monitor, center - pos = middle() / 2.f - w->m_vRealSize.goal() / 2.f; + pos = middle() / 2.f - w->m_vRealSize->goal() / 2.f; } else pos = pos - PMONFROMMIDDLE->vecPosition + vecPosition; - w->m_vRealPosition = pos; - w->m_vPosition = pos; + *w->m_vRealPosition = pos; + w->m_vPosition = pos; } } } diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 0a6ef55d..b6e3ac12 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -5,7 +5,6 @@ #include "../desktop/Window.hpp" #include "../desktop/Subsurface.hpp" #include "../desktop/Popup.hpp" -#include "AnimatedVariable.hpp" #include "../desktop/WLSurface.hpp" #include "signal/Signal.hpp" #include "math/Math.hpp" -- cgit v1.2.3