mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-01 18:50:16 +03:00
Reduce allocations in CSS parsing and style updates
- reuse reentrant property-resolution storage during variable substitution - skip redundant resolution-slot copies using structural source comparison - retain variable cache capacity and resolve variables in place - avoid copying canonical names for definition-backed properties - propagate resolved inherited properties by reference through widget trees - parse animation and transition declarations with allocation-light string views - share declaration tokenization between animation and transition parsers - avoid empty animation-map and action-query allocations - parse border radii without temporary split vectors - accept string views when converting UI lengths - format color hex values directly without string streams - use inline storage for small polygon point collections - preserve animation parsing semantics and fix longhand direction handling - save eeiv configuration when closing through keyboard shortcuts - extend animation, variable-resolution, property-name, and color tests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#ifndef EE_MATHPOLIGON2_H
|
||||
#define EE_MATHPOLIGON2_H
|
||||
|
||||
#include <eepp/core/small_vector.hpp>
|
||||
#include <eepp/math/line2.hpp>
|
||||
#include <eepp/math/quad2.hpp>
|
||||
#include <eepp/math/rect.hpp>
|
||||
@@ -105,7 +106,7 @@ template <typename T> class Polygon2 {
|
||||
Uint32 closestPoint( const Vector2<T>& to, T* distance = NULL );
|
||||
|
||||
private:
|
||||
std::vector<Vector2<T>> Vector;
|
||||
SmallVector<Vector2<T>, 4> Vector;
|
||||
Vector2<T> Position;
|
||||
};
|
||||
|
||||
|
||||
@@ -100,6 +100,12 @@ class EE_API AnimationDefinition {
|
||||
AnimationDirection mDirection = Normal;
|
||||
AnimationFillMode mFillMode = None;
|
||||
bool mPaused = false;
|
||||
|
||||
static bool isDirectionStringView( std::string_view str );
|
||||
static AnimationDirection directionFromStringView( std::string_view str );
|
||||
static bool isAnimationFillModeStringView( std::string_view str );
|
||||
static AnimationFillMode fillModeFromStringView( std::string_view str );
|
||||
void setNameView( std::string_view value );
|
||||
};
|
||||
|
||||
inline bool operator==( const AnimationDefinition& a, const AnimationDefinition& b ) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <eepp/ui/css/propertyids.hpp>
|
||||
#include <eepp/ui/css/stylesheetlength.hpp>
|
||||
#include <span>
|
||||
#include <string>
|
||||
|
||||
using namespace EE::System;
|
||||
@@ -19,6 +20,7 @@ using namespace EE::Graphics;
|
||||
|
||||
namespace EE { namespace UI {
|
||||
class UINode;
|
||||
class UIStyle;
|
||||
}} // namespace EE::UI
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
@@ -29,9 +31,15 @@ class ShorthandDefinition;
|
||||
struct VariableFunctionCache {
|
||||
std::string definition;
|
||||
std::vector<std::string> variableList;
|
||||
|
||||
void clear() { variableList.clear(); }
|
||||
|
||||
void addVariable( std::string_view variable ) { variableList.emplace_back( variable ); }
|
||||
};
|
||||
|
||||
class EE_API StyleSheetProperty {
|
||||
friend class EE::UI::UIStyle;
|
||||
|
||||
public:
|
||||
StyleSheetProperty();
|
||||
|
||||
@@ -196,7 +204,7 @@ class EE_API StyleSheetProperty {
|
||||
|
||||
const String::HashType& getValueHash() const;
|
||||
|
||||
const std::vector<VariableFunctionCache>& getVarCache() const;
|
||||
std::span<const VariableFunctionCache> getVarCache() const;
|
||||
|
||||
StyleSheetProperty& setCachedProperty( bool cached );
|
||||
|
||||
@@ -205,6 +213,8 @@ class EE_API StyleSheetProperty {
|
||||
void setImportant( bool important );
|
||||
|
||||
protected:
|
||||
bool hasSameResolutionSource( const StyleSheetProperty& property ) const;
|
||||
|
||||
std::string mName;
|
||||
String::HashType mNameHash{ 0 };
|
||||
std::string mValue;
|
||||
@@ -220,6 +230,7 @@ class EE_API StyleSheetProperty {
|
||||
const ShorthandDefinition* mShorthandDefinition{ nullptr };
|
||||
std::vector<StyleSheetProperty> mIndexedProperty;
|
||||
std::vector<VariableFunctionCache> mVarCache;
|
||||
size_t mVarCacheSize{ 0 };
|
||||
|
||||
explicit StyleSheetProperty( bool isVolatile, const PropertyDefinition* definition,
|
||||
const std::string& value, const Int64& specificity = 0,
|
||||
@@ -229,7 +240,7 @@ class EE_API StyleSheetProperty {
|
||||
void checkImportant();
|
||||
void createIndexed();
|
||||
void checkVars();
|
||||
std::vector<VariableFunctionCache> checkVars( const std::string& value );
|
||||
std::string& mutableValue() { return mValue; }
|
||||
};
|
||||
|
||||
typedef UnorderedMap<Uint32, StyleSheetProperty> StyleSheetProperties;
|
||||
|
||||
@@ -1151,6 +1151,13 @@ class EE_API UINode : public Node {
|
||||
Float convertLengthAsDp( const CSS::StyleSheetLength& length,
|
||||
const Float& containerLength ) const;
|
||||
|
||||
inline Float lengthFromValue( const std::string& value,
|
||||
const CSS::PropertyRelativeTarget& relativeTarget,
|
||||
const Float& defaultValue, const Uint32& propertyIndex ) const {
|
||||
return lengthFromValue( std::string_view{ value }, relativeTarget, defaultValue,
|
||||
propertyIndex );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Evaluates a CSS length string to a pixel value.
|
||||
*
|
||||
@@ -1163,10 +1170,18 @@ class EE_API UINode : public Node {
|
||||
* @param propertyIndex The property index for multi-value properties (default: 0).
|
||||
* @return The computed length in pixels.
|
||||
*/
|
||||
Float lengthFromValue( const std::string& value,
|
||||
Float lengthFromValue( std::string_view value,
|
||||
const CSS::PropertyRelativeTarget& relativeTarget,
|
||||
const Float& defaultValue = 0, const Uint32& propertyIndex = 0 ) const;
|
||||
|
||||
inline Float lengthFromValue( const char* value,
|
||||
const CSS::PropertyRelativeTarget& relativeTarget,
|
||||
const Float& defaultValue = 0,
|
||||
const Uint32& propertyIndex = 0 ) const {
|
||||
return lengthFromValue( std::string_view{ value }, relativeTarget, defaultValue,
|
||||
propertyIndex );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Evaluates a CSS property to a pixel value.
|
||||
*
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <eepp/ui/css/stylesheetstyle.hpp>
|
||||
#include <eepp/ui/css/transitiondefinition.hpp>
|
||||
#include <eepp/ui/uistate.hpp>
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
class Font;
|
||||
@@ -96,6 +96,31 @@ class EE_API UIStyle : public UIState {
|
||||
void applyVarValues( CSS::StyleSheetProperty* style );
|
||||
|
||||
protected:
|
||||
class PropertyResolution {
|
||||
public:
|
||||
PropertyResolution( const PropertyResolution& ) = delete;
|
||||
PropertyResolution& operator=( const PropertyResolution& ) = delete;
|
||||
PropertyResolution( PropertyResolution&& other ) noexcept;
|
||||
PropertyResolution& operator=( PropertyResolution&& ) = delete;
|
||||
~PropertyResolution();
|
||||
|
||||
const CSS::StyleSheetProperty* get() const { return mProperty; }
|
||||
|
||||
private:
|
||||
friend class UIStyle;
|
||||
static constexpr Uint32 NoSlot = static_cast<Uint32>( -1 );
|
||||
|
||||
PropertyResolution( UIStyle* owner, const CSS::StyleSheetProperty* property,
|
||||
Uint32 slot = NoSlot ) :
|
||||
mOwner( owner ), mProperty( property ), mSlot( slot ) {}
|
||||
|
||||
void release();
|
||||
|
||||
UIStyle* mOwner;
|
||||
const CSS::StyleSheetProperty* mProperty;
|
||||
Uint32 mSlot;
|
||||
};
|
||||
|
||||
UIWidget* mWidget;
|
||||
std::shared_ptr<CSS::StyleSheetStyle> mElementStyle;
|
||||
std::shared_ptr<CSS::ElementDefinition> mGlobalDefinition;
|
||||
@@ -105,8 +130,12 @@ class EE_API UIStyle : public UIState {
|
||||
UnorderedSet<UIWidget*> mSubscribedWidgets;
|
||||
UnorderedSet<UIWidget*> mStructurallyVolatileChildren;
|
||||
Uint32 mStateDepthCounter{ 0 };
|
||||
Uint32 mPropertyResolutionDepth{ 0 };
|
||||
Uint64 mLoadedVersion{ 0 };
|
||||
const CSS::StyleSheet* mLoadedStyleSheet{ nullptr };
|
||||
/** Lazily allocated for styles that use substitutions. The pointed-to properties remain stable
|
||||
* during nested resolutions and retain their string/vector capacities between state changes. */
|
||||
SmallVector<std::unique_ptr<CSS::StyleSheetProperty>, 1> mPropertyResolutionSlots;
|
||||
bool mChangingState;
|
||||
bool mForceReapplyProperties;
|
||||
bool mDisableAnimations;
|
||||
@@ -118,7 +147,9 @@ class EE_API UIStyle : public UIState {
|
||||
|
||||
void applyLightDarkValue( std::string& newValue );
|
||||
|
||||
void setVariableFromValue( CSS::StyleSheetProperty* property, const std::string& value );
|
||||
const CSS::StyleSheetVariable* getVariableRef( const std::string& variable );
|
||||
|
||||
void setVariableFromValue( CSS::StyleSheetProperty* property );
|
||||
|
||||
void updateState();
|
||||
|
||||
@@ -150,9 +181,9 @@ class EE_API UIStyle : public UIState {
|
||||
|
||||
CSS::StyleSheetProperty* getLocalProperty( CSS::PropertyId propId );
|
||||
|
||||
CSS::StyleSheetProperty*
|
||||
getResolvedLocalProperty( CSS::PropertyId propId,
|
||||
std::optional<CSS::StyleSheetProperty>& resolvedProperty );
|
||||
PropertyResolution resolveProperty( const CSS::StyleSheetProperty* property );
|
||||
|
||||
PropertyResolution getResolvedLocalProperty( CSS::PropertyId propId );
|
||||
|
||||
void addStructurallyVolatileWidgetFromParent();
|
||||
|
||||
|
||||
@@ -1526,6 +1526,7 @@ class EE_API UIWidget : public UINode {
|
||||
|
||||
void calculateAutoMargin();
|
||||
void rebuildClassHashes();
|
||||
void propagateInheritedPropertyResolved( const CSS::StyleSheetProperty& property );
|
||||
|
||||
/**
|
||||
* @brief Default constructor.
|
||||
|
||||
Reference in New Issue
Block a user