From 86053153b36d7fa880effa8bf577210493a2f58e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 8 May 2020 01:26:32 -0300 Subject: [PATCH] Refactorized ResourceManager. Fixes for dirty layouts updates. Fixed CSS animations issues. Minor layouts refactor and fixes (WIP). --- include/eepp/core/string.hpp | 1 + include/eepp/graphics/textureatlasmanager.hpp | 2 +- include/eepp/system/resourcemanager.hpp | 329 ++++++++++++------ include/eepp/ui/uigridlayout.hpp | 3 +- include/eepp/ui/uilayout.hpp | 18 +- include/eepp/ui/uilinearlayout.hpp | 2 +- include/eepp/ui/uirelativelayout.hpp | 3 +- include/eepp/ui/uistyle.hpp | 4 + include/eepp/ui/uitabwidget.hpp | 8 +- include/eepp/ui/uitheme.hpp | 10 +- src/eepp/graphics/globaltextureatlas.cpp | 3 +- src/eepp/graphics/shaderprogrammanager.cpp | 6 +- src/eepp/graphics/textureatlas.cpp | 2 +- src/eepp/graphics/textureatlasmanager.cpp | 12 +- src/eepp/maps/mapeditor/mapeditor.cpp | 14 +- src/eepp/maps/tilemap.cpp | 8 +- src/eepp/ui/tools/textureatlaseditor.cpp | 12 +- src/eepp/ui/uigridlayout.cpp | 18 +- src/eepp/ui/uilayout.cpp | 20 +- src/eepp/ui/uilinearlayout.cpp | 6 +- src/eepp/ui/uirelativelayout.cpp | 6 +- src/eepp/ui/uiscenenode.cpp | 14 +- src/eepp/ui/uistyle.cpp | 41 ++- src/eepp/ui/uitabwidget.cpp | 50 ++- src/eepp/ui/uitheme.cpp | 11 +- src/eepp/ui/uithememanager.cpp | 2 +- src/eepp/ui/uiwidget.cpp | 3 + 27 files changed, 371 insertions(+), 237 deletions(-) diff --git a/include/eepp/core/string.hpp b/include/eepp/core/string.hpp index cd7e27d26..d40d0404f 100644 --- a/include/eepp/core/string.hpp +++ b/include/eepp/core/string.hpp @@ -52,6 +52,7 @@ class EE_API String { typedef StringType::const_iterator ConstIterator; //! Constant iterator type typedef StringType::reverse_iterator ReverseIterator; //! Reverse Iterator type typedef StringType::const_reverse_iterator ConstReverseIterator; //! Constant iterator type + typedef Uint32 HashType; static const std::size_t InvalidPos; ///< Represents an invalid position in the string diff --git a/include/eepp/graphics/textureatlasmanager.hpp b/include/eepp/graphics/textureatlasmanager.hpp index fdef8064a..854ba7fde 100644 --- a/include/eepp/graphics/textureatlasmanager.hpp +++ b/include/eepp/graphics/textureatlasmanager.hpp @@ -14,7 +14,7 @@ namespace EE { namespace Graphics { /** @brief The Texture Atlas Manager is a singleton class that manages all the instances of Texture Atlases instanciated. Releases the Texture Atlases instances automatically. So the user doesn't need to release any Texture Atlas instance. */ -class EE_API TextureAtlasManager : public ResourceManager { +class EE_API TextureAtlasManager : public ResourceManagerMulti { SINGLETON_DECLARE_HEADERS( TextureAtlasManager ) public: diff --git a/include/eepp/system/resourcemanager.hpp b/include/eepp/system/resourcemanager.hpp index a89ae41cc..41c8421e3 100644 --- a/include/eepp/system/resourcemanager.hpp +++ b/include/eepp/system/resourcemanager.hpp @@ -2,62 +2,62 @@ #define EE_SYSTEMTRESOURCEMANAGER_HPP #include -#include #include +#include namespace EE { namespace System { /** @brief A simple resource manager. It keeps a list of the resources, and free the instances of - * the resources when the manager is closed. Resources must have getId() and getName() properties. - * getId() is the string hash of getName(). + * the resources when the manager is closed. Resources must implement getId() and getName() + * properties getId() is the string hash of getName(). */ template class ResourceManager { public: /** @param UniqueId Indicates if the resources id must be unique */ - ResourceManager( bool UniqueId = true ); + ResourceManager(); /** @brief The destructor will call destroy() and destroy all the resources added to the manager */ virtual ~ResourceManager(); /** @brief Add the resource to the resource manager - ** @param Resource The resource to be managed by the manager */ - virtual T* add( T* Resource ); + ** @param resource The resource to be managed by the manager */ + virtual T* add( T* resource ); /** @brief Removes the resource from the manager - ** @param Resource The resource to remove - ** @param Delete Indicates if the resource must be destroyed after being removed from the + ** @param resource The resource to remove + ** @param remove Indicates if the resource must be destroyed after being removed from the *manager */ - bool remove( T* Resource, bool Delete = true ); + bool remove( T* resource, bool remove = true ); /** @brief Removes the resource by its id ** @see remove */ - bool removeById( const Uint32& Id, bool Delete = true ); + bool removeById( const String::HashType& id, bool remove = true ); /** @brief Removes the resource by its name ** @see remove */ - bool removeByName( const std::string& Name, bool Delete = true ); + bool removeByName( const std::string& name, bool remove = true ); /** @returns A resource by its name. If not found returns NULL. */ - T* getByName( const std::string& Name ); + T* getByName( const std::string& name ); /** @returns A resource by its id. If not found returns NULL. */ - T* getById( const Uint32& Id ); + T* getById( const String::HashType& id ); /** @returns The number of resources added */ Uint32 getCount(); /** @returns The number of resources that where added with the indicated name. */ - Uint32 setCount( const std::string& Name ); + Uint32 getCount( const std::string& name ); /** @returns The number of resources that where added with the indicated id. */ - Uint32 setCount( const Uint32& Id ); + Uint32 getCount( const String::HashType& id ); /** @returns If the resource name exists in the resources list. */ - bool exists( const std::string& Name ); + bool exists( const std::string& name ); /** @returns If the resource id exists in the resources list. */ - bool existsId( const Uint32& Id ); + bool existsId( const String::HashType& id ); /** @brief Destroy all the resources added ( delete the instances of the resources ) */ void destroy(); @@ -66,20 +66,17 @@ template class ResourceManager { void printNames(); /** @returns A reference to the resources list of the manager. */ - std::list& getResources(); + std::unordered_map& getResources(); /** @brief Indicates if the resource manager is destroy the resources. */ const bool& isDestroying() const; protected: - std::list mResources; - bool mUniqueId; + std::unordered_map mResources; bool mIsDestroying; }; -template -ResourceManager::ResourceManager( bool UniqueId ) : - mUniqueId( UniqueId ), mIsDestroying( false ) {} +template ResourceManager::ResourceManager() : mIsDestroying( false ) {} template const bool& ResourceManager::isDestroying() const { return mIsDestroying; @@ -90,12 +87,11 @@ template ResourceManager::~ResourceManager() { } template void ResourceManager::destroy() { - typename std::list::iterator it; - mIsDestroying = true; - for ( it = mResources.begin(); it != mResources.end(); it++ ) { - eeSAFE_DELETE( ( *it ) ); + for ( auto& it : mResources ) { + T* res = it.second; + eeSAFE_DELETE( res ); } mResources.clear(); @@ -103,45 +99,40 @@ template void ResourceManager::destroy() { mIsDestroying = false; } -template std::list& ResourceManager::getResources() { +template std::unordered_map& ResourceManager::getResources() { return mResources; } -template T* ResourceManager::add( T* Resource ) { - if ( NULL != Resource ) { - if ( mUniqueId ) { - Uint32 c = setCount( Resource->getId() ); +template T* ResourceManager::add( T* resource ) { + if ( NULL != resource ) { + if ( !existsId( resource->getId() ) ) { + mResources[resource->getId()] = resource; - if ( 0 == c ) { - mResources.push_back( Resource ); - - return Resource; - } else { - std::string RealName( Resource->getName() ); - - while ( setCount( Resource->getId() ) ) { - c++; - Resource->setName( RealName + String::toStr( c ) ); - } - - return add( Resource ); - } + return resource; } else { - mResources.push_back( Resource ); + std::string realName( resource->getName() ); + Uint32 c = 1; - return Resource; + while ( existsId( resource->getId() ) ) { + c++; + resource->setName( realName + String::toStr( c ) ); + } + + return add( resource ); } - } + mResources[resource->getId()] = resource; + return resource; + } return NULL; } -template bool ResourceManager::remove( T* Resource, bool Delete ) { - if ( NULL != Resource ) { - mResources.remove( Resource ); +template bool ResourceManager::remove( T* resource, bool remove ) { + if ( NULL != resource ) { + mResources.erase( resource->getId() ); - if ( Delete ) - eeSAFE_DELETE( Resource ); + if ( remove ) + eeSAFE_DELETE( resource ); return true; } @@ -149,56 +140,34 @@ template bool ResourceManager::remove( T* Resource, bool Delete ) { return false; } -template bool ResourceManager::removeById( const Uint32& Id, bool Delete ) { - return remove( getById( Id ), Delete ); +template bool ResourceManager::removeById( const String::HashType& id, bool _remove ) { + return remove( getById( id ), _remove ); } -template bool ResourceManager::removeByName( const std::string& Name, bool Delete ) { - return remove( getByName( Name ), Delete ); +template bool ResourceManager::removeByName( const std::string& name, bool _remove ) { + return remove( getByName( name ), _remove ); } -template bool ResourceManager::exists( const std::string& Name ) { - return existsId( String::hash( Name ) ); +template bool ResourceManager::exists( const std::string& name ) { + return existsId( String::hash( name ) ); } -template bool ResourceManager::existsId( const Uint32& Id ) { - typename std::list::iterator it; - - for ( it = mResources.begin(); it != mResources.end(); it++ ) - if ( ( *it )->getId() == Id ) - return true; - - return false; +template bool ResourceManager::existsId( const String::HashType& id ) { + return mResources.find( id ) != mResources.end(); } -template T* ResourceManager::getByName( const std::string& Name ) { - return getById( String::hash( Name ) ); +template T* ResourceManager::getByName( const std::string& name ) { + return getById( String::hash( name ) ); } -template T* ResourceManager::getById( const Uint32& id ) { - typename std::list::reverse_iterator it; - - T* sp = NULL; - - for ( it = mResources.rbegin(); it != mResources.rend(); it++ ) { - sp = ( *it ); - - if ( id == sp->getId() ) - return sp; - } - - return NULL; +template T* ResourceManager::getById( const String::HashType& id ) { + auto it = mResources.find( id ); + return it != mResources.end() ? it->second : nullptr; } template void ResourceManager::printNames() { - typename std::list::reverse_iterator it; - - T* sp = NULL; - - for ( it = mResources.rbegin(); it != mResources.rend(); it++ ) { - sp = ( *it ); - - eePRINT( "'%s'\n", sp->getName().c_str() ); + for ( auto& it : mResources ) { + eePRINT( "'%s'\n", it.second->getName().c_str() ); } } @@ -206,19 +175,175 @@ template Uint32 ResourceManager::getCount() { return (Uint32)mResources.size(); } -template Uint32 ResourceManager::setCount( const Uint32& Id ) { - typename std::list::iterator it; - Uint32 Count = 0; - - for ( it = mResources.begin(); it != mResources.end(); it++ ) - if ( ( *it )->getId() == Id ) - Count++; - - return Count; +template Uint32 ResourceManager::getCount( const String::HashType& id ) { + return existsId( id ) ? 1 : 0; } -template Uint32 ResourceManager::setCount( const std::string& Name ) { - return setCount( String::hash( Name ) ); +template Uint32 ResourceManager::getCount( const std::string& name ) { + return getCount( String::hash( name ) ); +} + +/** @brief A simple resource manager. It keeps a list of the resources, and free the instances of + * the resources when the manager is closed. Resources must implement getId() and getName() + * properties getId() is the string hash of getName(). Allows repeated keys. + */ +template class ResourceManagerMulti { + public: + /** @param UniqueId Indicates if the resources id must be unique */ + ResourceManagerMulti(); + + /** @brief The destructor will call destroy() and destroy all the resources added to the manager + */ + virtual ~ResourceManagerMulti(); + + /** @brief Add the resource to the resource manager + ** @param resource The resource to be managed by the manager */ + virtual T* add( T* resource ); + + /** @brief Removes the resource from the manager + ** @param resource The resource to remove + ** @param remove Indicates if the resource must be destroyed after being removed from the + *manager */ + bool remove( T* resource, bool remove = true ); + + /** @brief Removes the resource by its id + ** @see remove */ + bool removeById( const String::HashType& id, bool remove = true ); + + /** @brief Removes the resource by its name + ** @see remove */ + bool removeByName( const std::string& name, bool remove = true ); + + /** @returns A resource by its name. If not found returns NULL. */ + T* getByName( const std::string& name ); + + /** @returns A resource by its id. If not found returns NULL. */ + T* getById( const String::HashType& id ); + + /** @returns The number of resources added */ + Uint32 getCount(); + + /** @returns The number of resources that where added with the indicated name. */ + Uint32 getCount( const std::string& name ); + + /** @returns The number of resources that where added with the indicated id. */ + Uint32 getCount( const String::HashType& id ); + + /** @returns If the resource name exists in the resources list. */ + bool exists( const std::string& name ); + + /** @returns If the resource id exists in the resources list. */ + bool existsId( const String::HashType& id ); + + /** @brief Destroy all the resources added ( delete the instances of the resources ) */ + void destroy(); + + /** @brief Prints all the resources names added to the manager. */ + void printNames(); + + /** @returns A reference to the resources list of the manager. */ + std::unordered_multimap& getResources(); + + /** @brief Indicates if the resource manager is destroy the resources. */ + const bool& isDestroying() const; + + protected: + std::unordered_multimap mResources; + bool mIsDestroying; +}; + +template ResourceManagerMulti::ResourceManagerMulti() : mIsDestroying( false ) {} + +template const bool& ResourceManagerMulti::isDestroying() const { + return mIsDestroying; +} + +template ResourceManagerMulti::~ResourceManagerMulti() { + destroy(); +} + +template void ResourceManagerMulti::destroy() { + mIsDestroying = true; + + for ( auto& it : mResources ) { + T* res = it.second; + eeSAFE_DELETE( res ); + } + + mResources.clear(); + + mIsDestroying = false; +} + +template +std::unordered_multimap& ResourceManagerMulti::getResources() { + return mResources; +} + +template T* ResourceManagerMulti::add( T* resource ) { + if ( NULL != resource ) { + mResources.insert( std::pair( resource->getId(), resource ) ); + return resource; + } + return NULL; +} + +template bool ResourceManagerMulti::remove( T* resource, bool remove ) { + if ( NULL != resource ) { + mResources.erase( resource->getId() ); + + if ( remove ) + eeSAFE_DELETE( resource ); + + return true; + } + + return false; +} + +template +bool ResourceManagerMulti::removeById( const String::HashType& id, bool _remove ) { + return remove( getById( id ), _remove ); +} + +template +bool ResourceManagerMulti::removeByName( const std::string& name, bool _remove ) { + return remove( getByName( name ), _remove ); +} + +template bool ResourceManagerMulti::exists( const std::string& name ) { + return existsId( String::hash( name ) ); +} + +template bool ResourceManagerMulti::existsId( const String::HashType& id ) { + return mResources.find( id ) != mResources.end(); +} + +template T* ResourceManagerMulti::getByName( const std::string& name ) { + return getById( String::hash( name ) ); +} + +template T* ResourceManagerMulti::getById( const String::HashType& id ) { + auto it = mResources.find( id ); + return it != mResources.end() ? it->second : nullptr; +} + +template void ResourceManagerMulti::printNames() { + for ( auto& it : mResources ) { + eePRINT( "'%s'\n", it->second->getName().c_str() ); + } +} + +template Uint32 ResourceManagerMulti::getCount() { + return (Uint32)mResources.size(); +} + +template Uint32 ResourceManagerMulti::getCount( const String::HashType& id ) { + return mResources.count( id ); +} + +template Uint32 ResourceManagerMulti::getCount( const std::string& name ) { + return getCount( String::hash( name ) ); } }} // namespace EE::System diff --git a/include/eepp/ui/uigridlayout.hpp b/include/eepp/ui/uigridlayout.hpp index ef2bc29f0..56b5a8d06 100644 --- a/include/eepp/ui/uigridlayout.hpp +++ b/include/eepp/ui/uigridlayout.hpp @@ -50,7 +50,8 @@ class EE_API UIGridLayout : public UILayout { virtual bool applyProperty( const StyleSheetProperty& attribute ); - virtual void pack(); + virtual void updateLayout(); + protected: Sizei mBoxMargin; ElementMode mColumnMode; diff --git a/include/eepp/ui/uilayout.hpp b/include/eepp/ui/uilayout.hpp index e9c011292..8b2e2532f 100644 --- a/include/eepp/ui/uilayout.hpp +++ b/include/eepp/ui/uilayout.hpp @@ -15,15 +15,9 @@ class EE_API UILayout : public UIWidget { virtual bool isType( const Uint32& type ) const; - virtual void pack(); - - virtual void setLayoutDirty(); - - virtual void packConditional(); - - void packLayoutTree(); - protected: + friend class UISceneNode; + UILayout( const std::string& tag ); virtual void onSizeChange(); @@ -36,6 +30,14 @@ class EE_API UILayout : public UIWidget { virtual void onLayoutUpdate(); + virtual void tryUpdateLayout(); + + virtual void updateLayout(); + + virtual void updateLayoutTree(); + + void setLayoutDirty(); + std::unordered_set mLayouts; bool mDirtyLayout; }; diff --git a/include/eepp/ui/uilinearlayout.hpp b/include/eepp/ui/uilinearlayout.hpp index 7ba3a504e..8a8d828dc 100644 --- a/include/eepp/ui/uilinearlayout.hpp +++ b/include/eepp/ui/uilinearlayout.hpp @@ -30,7 +30,7 @@ class EE_API UILinearLayout : public UILayout { virtual std::string getPropertyString( const PropertyDefinition* propertyDef, const Uint32& propertyIndex = 0 ); - void pack(); + void updateLayout(); bool isPacking() const; diff --git a/include/eepp/ui/uirelativelayout.hpp b/include/eepp/ui/uirelativelayout.hpp index cb6809e6f..9a0c26ebc 100644 --- a/include/eepp/ui/uirelativelayout.hpp +++ b/include/eepp/ui/uirelativelayout.hpp @@ -17,7 +17,8 @@ class EE_API UIRelativeLayout : public UILayout { UIRelativeLayout* add( UIWidget* widget ); - virtual void pack(); + virtual void updateLayout(); + protected: virtual Uint32 onMessage( const NodeMessage* Msg ); diff --git a/include/eepp/ui/uistyle.hpp b/include/eepp/ui/uistyle.hpp index 05b76063d..64bacf3f0 100644 --- a/include/eepp/ui/uistyle.hpp +++ b/include/eepp/ui/uistyle.hpp @@ -122,6 +122,10 @@ class EE_API UIStyle : public UIState { const Uint32& propertyIndex ); CSS::StyleSheetProperty* getLocalProperty( Uint32 propId ); + + void addStructurallyVolatileWidgetFromParent(); + + void removeStructurallyVolatileWidgetFromParent(); }; }} // namespace EE::UI diff --git a/include/eepp/ui/uitabwidget.hpp b/include/eepp/ui/uitabwidget.hpp index 375d50159..f416637dc 100644 --- a/include/eepp/ui/uitabwidget.hpp +++ b/include/eepp/ui/uitabwidget.hpp @@ -2,12 +2,12 @@ #define EE_UICUITABWIDGET_HPP #include +#include #include -#include namespace EE { namespace UI { -class EE_API UITabWidget : public UIWidget { +class EE_API UITabWidget : public UILayout { public: class StyleConfig { public: @@ -127,11 +127,9 @@ class EE_API UITabWidget : public UIWidget { UITab* createTab( const String& Text, UINode* CtrlOwned, Drawable* Icon ); - virtual void onSizeChange(); - virtual void onChildCountChange( Node* child, const bool& removed ); - virtual void onPaddingChange(); + virtual void updateLayout(); void setContainerSize(); diff --git a/include/eepp/ui/uitheme.hpp b/include/eepp/ui/uitheme.hpp index 3c00bf284..400a0ccdc 100644 --- a/include/eepp/ui/uitheme.hpp +++ b/include/eepp/ui/uitheme.hpp @@ -17,12 +17,12 @@ class Drawable; namespace EE { namespace UI { -class EE_API UITheme : protected ResourceManager { +class EE_API UITheme : protected ResourceManagerMulti { public: - using ResourceManager::getById; - using ResourceManager::getByName; - using ResourceManager::exists; - using ResourceManager::existsId; + using ResourceManagerMulti::getById; + using ResourceManagerMulti::getByName; + using ResourceManagerMulti::exists; + using ResourceManagerMulti::existsId; static UITheme* New( const std::string& name, const std::string& abbr, Graphics::Font* defaultFont = NULL ); diff --git a/src/eepp/graphics/globaltextureatlas.cpp b/src/eepp/graphics/globaltextureatlas.cpp index 94f63ee7e..d363c91a7 100644 --- a/src/eepp/graphics/globaltextureatlas.cpp +++ b/src/eepp/graphics/globaltextureatlas.cpp @@ -7,6 +7,7 @@ SINGLETON_DECLARE_IMPLEMENTATION( GlobalTextureAtlas ) GlobalTextureAtlas::GlobalTextureAtlas() : TextureAtlas( "global" ) {} -GlobalTextureAtlas::~GlobalTextureAtlas() {} +GlobalTextureAtlas::~GlobalTextureAtlas() { +} }} // namespace EE::Graphics diff --git a/src/eepp/graphics/shaderprogrammanager.cpp b/src/eepp/graphics/shaderprogrammanager.cpp index 4250cfe78..d27c633f8 100644 --- a/src/eepp/graphics/shaderprogrammanager.cpp +++ b/src/eepp/graphics/shaderprogrammanager.cpp @@ -9,10 +9,8 @@ ShaderProgramManager::ShaderProgramManager() {} ShaderProgramManager::~ShaderProgramManager() {} void ShaderProgramManager::reload() { - std::list::iterator it; - - for ( it = mResources.begin(); it != mResources.end(); ++it ) - ( *it )->reload(); + for ( auto& res : mResources ) + res.second->reload(); } }} // namespace EE::Graphics diff --git a/src/eepp/graphics/textureatlas.cpp b/src/eepp/graphics/textureatlas.cpp index abd74b88e..4022a63e4 100644 --- a/src/eepp/graphics/textureatlas.cpp +++ b/src/eepp/graphics/textureatlas.cpp @@ -6,7 +6,7 @@ TextureAtlas* TextureAtlas::New( const std::string& name ) { return eeNew( TextureAtlas, ( name ) ); } -TextureAtlas::TextureAtlas( const std::string& name ) : ResourceManager( true ) { +TextureAtlas::TextureAtlas( const std::string& name ) : ResourceManager() { setName( name ); } diff --git a/src/eepp/graphics/textureatlasmanager.cpp b/src/eepp/graphics/textureatlasmanager.cpp index 755418c74..2d43d338f 100644 --- a/src/eepp/graphics/textureatlasmanager.cpp +++ b/src/eepp/graphics/textureatlasmanager.cpp @@ -8,7 +8,7 @@ namespace EE { namespace Graphics { SINGLETON_DECLARE_IMPLEMENTATION( TextureAtlasManager ) TextureAtlasManager::TextureAtlasManager() : - ResourceManager( false ), mWarnings( false ) { + ResourceManagerMulti(), mWarnings( false ) { add( GlobalTextureAtlas::instance() ); } @@ -57,8 +57,8 @@ TextureRegion* TextureAtlasManager::getTextureRegionById( const Uint32& Id ) { TextureAtlas* tSG = NULL; TextureRegion* tTextureRegion = NULL; - for ( it = mResources.begin(); it != mResources.end(); ++it ) { - tSG = ( *it ); + for ( auto& it : mResources ) { + tSG = it.second; tTextureRegion = tSG->getById( Id ); @@ -70,10 +70,8 @@ TextureRegion* TextureAtlasManager::getTextureRegionById( const Uint32& Id ) { } void TextureAtlasManager::printResources() { - std::list::iterator it; - - for ( it = mResources.begin(); it != mResources.end(); ++it ) - ( *it )->printNames(); + for ( auto& it : mResources ) + it.second->printNames(); } std::vector diff --git a/src/eepp/maps/mapeditor/mapeditor.cpp b/src/eepp/maps/mapeditor/mapeditor.cpp index 31dd4167a..23edad073 100644 --- a/src/eepp/maps/mapeditor/mapeditor.cpp +++ b/src/eepp/maps/mapeditor/mapeditor.cpp @@ -945,7 +945,7 @@ void MapEditor::onNewGOTypeAdded( std::string name, Uint32 hash ) { void MapEditor::fillSGCombo() { TextureAtlasManager* SGM = TextureAtlasManager::instance(); - std::list& Res = SGM->getResources(); + auto& res = SGM->getResources(); mTextureAtlasesList->getListBox()->clear(); @@ -956,9 +956,9 @@ void MapEditor::fillSGCombo() { if ( NULL != mTheme && NULL != mTheme->getTextureAtlas() ) Restricted2 = String::hash( mTheme->getTextureAtlas()->getName() ); - for ( std::list::iterator it = Res.begin(); it != Res.end(); ++it ) { - if ( ( *it )->getId() != Restricted1 && ( *it )->getId() != Restricted2 ) - items.push_back( ( *it )->getName() ); + for ( auto& it : res ) { + if ( it.second->getId() != Restricted1 && it.second->getId() != Restricted2 ) + items.push_back( it.second->getName() ); } if ( items.size() ) { @@ -974,15 +974,15 @@ void MapEditor::fillSGCombo() { void MapEditor::fillTextureRegionList() { TextureAtlasManager* SGM = TextureAtlasManager::instance(); mCurSG = SGM->getByName( mTextureAtlasesList->getText() ); - std::list& Res = mCurSG->getResources(); + auto& res = mCurSG->getResources(); mTextureRegionList->clear(); if ( NULL != mCurSG ) { std::vector items; - for ( std::list::iterator it = Res.begin(); it != Res.end(); ++it ) { - items.push_back( ( *it )->getName() ); + for ( auto& it : res ) { + items.push_back( it.second->getName() ); } if ( items.size() ) { diff --git a/src/eepp/maps/tilemap.cpp b/src/eepp/maps/tilemap.cpp index 266b988be..4336c5a05 100644 --- a/src/eepp/maps/tilemap.cpp +++ b/src/eepp/maps/tilemap.cpp @@ -1435,7 +1435,7 @@ void TileMap::saveToFile( const std::string& path ) { std::vector TileMap::getTextureAtlases() { TextureAtlasManager* SGM = TextureAtlasManager::instance(); - std::list& Res = SGM->getResources(); + auto& res = SGM->getResources(); std::vector items; @@ -1448,9 +1448,9 @@ std::vector TileMap::getTextureAtlases() { ->getTextureAtlas() ->getName() ); - for ( std::list::iterator it = Res.begin(); it != Res.end(); ++it ) { - if ( ( *it )->getId() != Restricted1 && ( *it )->getId() != Restricted2 ) - items.push_back( ( *it )->getPath() ); + for ( auto& it : res ) { + if ( it.second->getId() != Restricted1 && it.second->getId() != Restricted2 ) + items.push_back( it.second->getPath() ); } return items; diff --git a/src/eepp/ui/tools/textureatlaseditor.cpp b/src/eepp/ui/tools/textureatlaseditor.cpp index 2b4fc19fc..2f3ca7364 100644 --- a/src/eepp/ui/tools/textureatlaseditor.cpp +++ b/src/eepp/ui/tools/textureatlaseditor.cpp @@ -367,14 +367,14 @@ void TextureAtlasEditor::fillTextureRegionList() { !mTextureAtlasLoader->isLoaded() ) return; - std::list& Res = mTextureAtlasLoader->getTextureAtlas()->getResources(); + auto& res = mTextureAtlasLoader->getTextureAtlas()->getResources(); mTextureRegionList->clear(); std::vector items; - for ( std::list::iterator it = Res.begin(); it != Res.end(); ++it ) { - items.push_back( ( *it )->getName() ); + for ( auto& it : res ) { + items.push_back( it.second->getName() ); } if ( items.size() ) { @@ -387,11 +387,11 @@ void TextureAtlasEditor::fillTextureRegionList() { mTextureRegionList->getVerticalScrollBar()->setClickStep( 8.f / (Float)mTextureRegionList->getCount() ); - if ( !Res.empty() ) { + if ( !res.empty() ) { mTextureRegionGrid->childsCloseAll(); - for ( auto it = Res.begin(); it != Res.end(); ++it ) { - TextureRegion* tr = ( *it ); + for ( auto& it : res ) { + TextureRegion* tr = it.second; UITextureRegion::New() ->setTextureRegion( tr ) diff --git a/src/eepp/ui/uigridlayout.cpp b/src/eepp/ui/uigridlayout.cpp index ef7789ad0..b3131e4bf 100644 --- a/src/eepp/ui/uigridlayout.cpp +++ b/src/eepp/ui/uigridlayout.cpp @@ -42,7 +42,7 @@ UIGridLayout::ElementMode UIGridLayout::getColumnMode() const { UIGridLayout* UIGridLayout::setColumnMode( const UIGridLayout::ElementMode& mode ) { mColumnMode = mode; - pack(); + updateLayout(); invalidateDraw(); return this; } @@ -53,7 +53,7 @@ UIGridLayout::ElementMode UIGridLayout::getRowMode() const { UIGridLayout* UIGridLayout::setRowMode( const UIGridLayout::ElementMode& mode ) { mRowMode = mode; - packConditional(); + tryUpdateLayout(); invalidateDraw(); return this; } @@ -65,7 +65,7 @@ Float UIGridLayout::getColumnWeight() const { UIGridLayout* UIGridLayout::setColumnWeight( const Float& columnWeight ) { mColumnWeight = columnWeight; if ( mColumnMode == Weight ) - packConditional(); + tryUpdateLayout(); invalidateDraw(); return this; } @@ -77,7 +77,7 @@ int UIGridLayout::getColumnWidth() const { UIGridLayout* UIGridLayout::setColumnWidth( int columnWidth ) { mColumnWidth = columnWidth; if ( mColumnMode == Size ) - packConditional(); + tryUpdateLayout(); invalidateDraw(); return this; } @@ -89,7 +89,7 @@ int UIGridLayout::getRowHeight() const { UIGridLayout* UIGridLayout::setRowHeight( int rowHeight ) { mRowHeight = rowHeight; if ( mRowMode == Size ) - packConditional(); + tryUpdateLayout(); invalidateDraw(); return this; } @@ -101,12 +101,12 @@ Float UIGridLayout::getRowWeight() const { UIGridLayout* UIGridLayout::setRowWeight( const Float& rowWeight ) { mRowWeight = rowWeight; if ( mRowMode == Weight ) - packConditional(); + tryUpdateLayout(); invalidateDraw(); return this; } -void UIGridLayout::pack() { +void UIGridLayout::updateLayout() { Sizef oldSize( getSize() ); if ( getParent()->isUINode() && !getParent()->asType()->ownsChildPosition() ) { @@ -196,8 +196,8 @@ void UIGridLayout::pack() { Uint32 UIGridLayout::onMessage( const NodeMessage* Msg ) { switch ( Msg->getMsg() ) { case NodeMessage::LayoutAttributeChange: { - packConditional(); - break; + tryUpdateLayout(); + return 1; } } diff --git a/src/eepp/ui/uilayout.cpp b/src/eepp/ui/uilayout.cpp index 74dd3678c..4cf4689a1 100644 --- a/src/eepp/ui/uilayout.cpp +++ b/src/eepp/ui/uilayout.cpp @@ -27,22 +27,22 @@ void UILayout::onChildCountChange( Node* child, const bool& removed ) { } } - packConditional(); + tryUpdateLayout(); } void UILayout::onSizeChange() { UIWidget::onSizeChange(); - packConditional(); + tryUpdateLayout(); } void UILayout::onPaddingChange() { UIWidget::onPaddingChange(); - packConditional(); + tryUpdateLayout(); } void UILayout::onParentSizeChange( const Vector2f& ) { UIWidget::onParentChange(); - packConditional(); + tryUpdateLayout(); } void UILayout::onLayoutUpdate() { @@ -57,7 +57,7 @@ bool UILayout::isType( const Uint32& type ) const { return UILayout::getType() == type ? true : UIWidget::isType( type ); } -void UILayout::pack() {} +void UILayout::updateLayout() {} void UILayout::setLayoutDirty() { if ( !mDirtyLayout ) { @@ -66,19 +66,19 @@ void UILayout::setLayoutDirty() { } } -void UILayout::packConditional() { +void UILayout::tryUpdateLayout() { if ( mUISceneNode->isUpdatingLayouts() ) { - pack(); + updateLayout(); } else if ( !mDirtyLayout ) { setLayoutDirty(); } } -void UILayout::packLayoutTree() { - pack(); +void UILayout::updateLayoutTree() { + updateLayout(); for ( auto layout : mLayouts ) { - layout->packLayoutTree(); + layout->updateLayoutTree(); } onLayoutUpdate(); diff --git a/src/eepp/ui/uilinearlayout.cpp b/src/eepp/ui/uilinearlayout.cpp index f1afec76b..186f0a3b1 100644 --- a/src/eepp/ui/uilinearlayout.cpp +++ b/src/eepp/ui/uilinearlayout.cpp @@ -44,7 +44,7 @@ UILinearLayout* UILinearLayout::add( UIWidget* widget ) { return this; } -void UILinearLayout::pack() { +void UILinearLayout::updateLayout() { if ( mOrientation == UIOrientation::Vertical ) packVertical(); else @@ -477,8 +477,8 @@ bool UILinearLayout::applyProperty( const StyleSheetProperty& attribute ) { Uint32 UILinearLayout::onMessage( const NodeMessage* Msg ) { switch ( Msg->getMsg() ) { case NodeMessage::LayoutAttributeChange: { - packConditional(); - break; + tryUpdateLayout(); + return 1; } } diff --git a/src/eepp/ui/uirelativelayout.cpp b/src/eepp/ui/uirelativelayout.cpp index ac7e074a1..52fc26705 100644 --- a/src/eepp/ui/uirelativelayout.cpp +++ b/src/eepp/ui/uirelativelayout.cpp @@ -24,7 +24,7 @@ UIRelativeLayout* UIRelativeLayout::add( UIWidget* widget ) { return this; } -void UIRelativeLayout::pack() { +void UIRelativeLayout::updateLayout() { if ( getParent()->isUINode() && !getParent()->asType()->ownsChildPosition() ) { setInternalPosition( Vector2f( mLayoutMargin.Left, mLayoutMargin.Top ) ); } @@ -170,8 +170,8 @@ void UIRelativeLayout::fixChildSize( UIWidget* widget ) { Uint32 UIRelativeLayout::onMessage( const NodeMessage* Msg ) { switch ( Msg->getMsg() ) { case NodeMessage::LayoutAttributeChange: { - packConditional(); - break; + tryUpdateLayout(); + return 1; } } diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 68ca5922a..de6386285 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -577,16 +577,14 @@ void UISceneNode::setIsLoading( bool isLoading ) { void UISceneNode::updateDirtyLayouts() { if ( !mDirtyLayouts.empty() ) { - Clock clock; mUpdatingLayouts = true; for ( UILayout* layout : mDirtyLayouts ) { - layout->packLayoutTree(); + layout->updateLayoutTree(); } mDirtyLayouts.clear(); mUpdatingLayouts = false; - eePRINTL( "Layouts recalculated in %.2f ms", clock.getElapsedTime().asMilliseconds() ); } } @@ -597,7 +595,9 @@ void UISceneNode::updateDirtyStyles() { node->reloadStyle( true, false, false ); } mDirtyStyle.clear(); - eePRINTL( "CSS Styles Reloaded in %.2f ms", clock.getElapsedTime().asMilliseconds() ); + + if ( mVerbose ) + eePRINTL( "CSS Styles Reloaded in %.2f ms", clock.getElapsedTime().asMilliseconds() ); } } @@ -609,8 +609,10 @@ void UISceneNode::updateDirtyStyleStates() { } mDirtyStyleState.clear(); mDirtyStyleStateCSSAnimations.clear(); - eePRINTL( "CSS Style State Invalidated, reapplied state in %.2f ms", - clock.getElapsedTime().asMilliseconds() ); + + if ( mVerbose ) + eePRINTL( "CSS Style State Invalidated, reapplied state in %.2f ms", + clock.getElapsedTime().asMilliseconds() ); } } diff --git a/src/eepp/ui/uistyle.cpp b/src/eepp/ui/uistyle.cpp index ad4dfbf98..801039c6e 100644 --- a/src/eepp/ui/uistyle.cpp +++ b/src/eepp/ui/uistyle.cpp @@ -28,13 +28,7 @@ UIStyle::UIStyle( UIWidget* widget ) : mDisableAnimations( false ) {} UIStyle::~UIStyle() { - if ( mGlobalDefinition && mGlobalDefinition->isStructurallyVolatile() && mWidget->getParent() && - mWidget->getParent()->isWidget() && - mWidget->getParent()->asType()->getUIStyle() ) { - mWidget->getParent()->asType()->getUIStyle()->removeStructurallyVolatileChild( - mWidget ); - } - + removeStructurallyVolatileWidgetFromParent(); removeRelatedWidgets(); unsubscribeNonCacheableStyles(); } @@ -60,12 +54,7 @@ void UIStyle::setStyleSheetProperty( const StyleSheetProperty& property ) { } void UIStyle::load() { - if ( mGlobalDefinition && mGlobalDefinition->isStructurallyVolatile() && mWidget->getParent() && - mWidget->getParent()->isWidget() && - mWidget->getParent()->asType()->getUIStyle() ) { - mWidget->getParent()->asType()->getUIStyle()->removeStructurallyVolatileChild( - mWidget ); - } + removeStructurallyVolatileWidgetFromParent(); mGlobalDefinition = mWidget->getUISceneNode()->getStyleSheet().getElementStyles( mWidget, false ); @@ -74,12 +63,7 @@ void UIStyle::load() { subscribeNonCacheableStyles(); - if ( mGlobalDefinition && mGlobalDefinition->isStructurallyVolatile() && mWidget->getParent() && - mWidget->getParent()->isWidget() && - mWidget->getParent()->asType()->getUIStyle() ) { - mWidget->getParent()->asType()->getUIStyle()->addStructurallyVolatileChild( - mWidget ); - } + addStructurallyVolatileWidgetFromParent(); } void UIStyle::setStyleSheetProperties( const CSS::StyleSheetProperties& properties ) { @@ -485,6 +469,7 @@ void UIStyle::applyStyleSheetProperty( const StyleSheetProperty& property, } else { elapsed = transitionInfo.getDuration(); } + startValue = prevTransition->getEndValue(); } else if ( startValue == prevTransition->getEndValue() ) { startValue = currentValue; } @@ -706,4 +691,22 @@ StyleSheetProperty* UIStyle::getLocalProperty( Uint32 propId ) { return defProperty ? defProperty : elemProperty; } +void UIStyle::addStructurallyVolatileWidgetFromParent() { + if ( mGlobalDefinition && mGlobalDefinition->isStructurallyVolatile() && mWidget->getParent() && + mWidget->getParent()->isWidget() && + mWidget->getParent()->asType()->getUIStyle() ) { + mWidget->getParent()->asType()->getUIStyle()->addStructurallyVolatileChild( + mWidget ); + } +} + +void UIStyle::removeStructurallyVolatileWidgetFromParent() { + if ( mGlobalDefinition && mGlobalDefinition->isStructurallyVolatile() && mWidget->getParent() && + mWidget->getParent()->isWidget() && + mWidget->getParent()->asType()->getUIStyle() ) { + mWidget->getParent()->asType()->getUIStyle()->removeStructurallyVolatileChild( + mWidget ); + } +} + }} // namespace EE::UI diff --git a/src/eepp/ui/uitabwidget.cpp b/src/eepp/ui/uitabwidget.cpp index e8ed62706..1789fad49 100644 --- a/src/eepp/ui/uitabwidget.cpp +++ b/src/eepp/ui/uitabwidget.cpp @@ -14,7 +14,7 @@ UITabWidget* UITabWidget::New() { } UITabWidget::UITabWidget() : - UIWidget( "tabwidget" ), + UILayout( "tabwidget" ), mCtrlContainer( NULL ), mTabContainer( NULL ), mTabSelected( NULL ), @@ -35,8 +35,6 @@ UITabWidget::UITabWidget() : ->setPosition( 0, mStyleConfig.TabHeight ); mCtrlContainer->clipEnable(); - onSizeChange(); - applyDefaultTheme(); } @@ -47,11 +45,11 @@ Uint32 UITabWidget::getType() const { } bool UITabWidget::isType( const Uint32& type ) const { - return UITabWidget::getType() == type ? true : UIWidget::isType( type ); + return UITabWidget::getType() == type ? true : UILayout::isType( type ); } void UITabWidget::setTheme( UITheme* Theme ) { - UIWidget::setTheme( Theme ); + UILayout::setTheme( Theme ); mTabContainer->setThemeSkin( Theme, "tabwidget" ); @@ -75,9 +73,9 @@ void UITabWidget::setTheme( UITheme* Theme ) { } void UITabWidget::onThemeLoaded() { - onSizeChange(); + tryUpdateLayout(); - UIWidget::onThemeLoaded(); + UILayout::onThemeLoaded(); } void UITabWidget::setContainerSize() { @@ -86,8 +84,8 @@ void UITabWidget::setContainerSize() { mTabContainer->setPosition( mPadding.Left, mPadding.Top ); mCtrlContainer->setPosition( mPadding.Left, mPadding.Top + mStyleConfig.TabHeight ); Sizef s( mSize.getWidth() - mRealPadding.Left - mRealPadding.Right, - mSize.getHeight() - PixelDensity::dpToPx( mStyleConfig.TabHeight ) - mRealPadding.Top - - mRealPadding.Bottom ); + mSize.getHeight() - PixelDensity::dpToPx( mStyleConfig.TabHeight ) - mRealPadding.Top - + mRealPadding.Bottom ); if ( s != mCtrlContainer->getSize() ) { mCtrlContainer->setPixelsSize( s ); @@ -130,7 +128,7 @@ std::string UITabWidget::getPropertyString( const PropertyDefinition* propertyDe case PropertyId::TabHeight: return String::fromFloat( getTabsHeight(), "dp" ); default: - return UIWidget::getPropertyString( propertyDef, propertyIndex ); + return UILayout::getPropertyString( propertyDef, propertyIndex ); } } @@ -191,7 +189,7 @@ bool UITabWidget::applyProperty( const StyleSheetProperty& attribute ) { setTabsHeight( attribute.asDpDimension( this ) ); break; default: - return UIWidget::applyProperty( attribute ); + return UILayout::applyProperty( attribute ); } return true; @@ -576,17 +574,6 @@ Uint32 UITabWidget::getSelectedTabIndex() const { return mTabSelectedIndex; } -void UITabWidget::onSizeChange() { - setContainerSize(); - posTabs(); - - if ( NULL != mTabSelected && NULL != mTabSelected->getOwnedWidget() ) { - mTabSelected->getOwnedWidget()->setSize( mCtrlContainer->getSize() ); - } - - UIWidget::onSizeChange(); -} - void UITabWidget::onChildCountChange( Node* child, const bool& removed ) { if ( !removed && child != mTabContainer && child != mCtrlContainer ) { if ( child->isType( UI_TYPE_TAB ) ) { @@ -605,16 +592,27 @@ void UITabWidget::onChildCountChange( Node* child, const bool& removed ) { child->setParent( mCtrlContainer ); child->setVisible( false ); child->setEnabled( true ); + + if ( child->isLayout() ) { + mLayouts.insert( child->asType() ); + } } } - UIWidget::onChildCountChange( child, removed ); + if ( removed && child->isLayout() ) { + mLayouts.erase( child->asType() ); + } + + tryUpdateLayout(); } -void UITabWidget::onPaddingChange() { - onSizeChange(); +void UITabWidget::updateLayout() { + setContainerSize(); + posTabs(); - UIWidget::onPaddingChange(); + if ( NULL != mTabSelected && NULL != mTabSelected->getOwnedWidget() ) { + mTabSelected->getOwnedWidget()->setSize( mCtrlContainer->getSize() ); + } } void UITabWidget::applyThemeToTabs() { diff --git a/src/eepp/ui/uitheme.cpp b/src/eepp/ui/uitheme.cpp index ddce28475..6d08f4f59 100644 --- a/src/eepp/ui/uitheme.cpp +++ b/src/eepp/ui/uitheme.cpp @@ -66,13 +66,12 @@ UITheme* UITheme::loadFromTextureAtlas( UITheme* tTheme, Graphics::TextureAtlas* tTheme->setTextureAtlas( textureAtlas ); - std::list& resources = textureAtlas->getResources(); - std::list::iterator it; + auto& resources = textureAtlas->getResources(); std::string sAbbr( tTheme->getAbbr() + "_" ); std::map skins; - for ( it = resources.begin(); it != resources.end(); ++it ) { - TextureRegion* textureRegion = *it; + for ( auto& it : resources ) { + TextureRegion* textureRegion = it.second; std::string name( textureRegion->getName() ); @@ -257,7 +256,7 @@ UITheme* UITheme::loadFromTextureAtlas( Graphics::TextureAtlas* TextureAtlas, } UITheme::UITheme( const std::string& name, const std::string& Abbr, Graphics::Font* defaultFont ) : - ResourceManager( false ), + ResourceManagerMulti(), mName( name ), mNameHash( String::hash( mName ) ), mAbbr( Abbr ), @@ -285,7 +284,7 @@ const std::string& UITheme::getAbbr() const { } UISkin* UITheme::add( UISkin* Resource ) { - return ResourceManager::add( Resource ); + return ResourceManagerMulti::add( Resource ); } Graphics::TextureAtlas* UITheme::getTextureAtlas() const { diff --git a/src/eepp/ui/uithememanager.cpp b/src/eepp/ui/uithememanager.cpp index d0fb3298c..62442d66a 100644 --- a/src/eepp/ui/uithememanager.cpp +++ b/src/eepp/ui/uithememanager.cpp @@ -8,7 +8,7 @@ UIThemeManager* UIThemeManager::New() { } UIThemeManager::UIThemeManager() : - ResourceManager( true ), + ResourceManager(), mFont( NULL ), mFontSize( 12 ), mThemeDefault( NULL ), diff --git a/src/eepp/ui/uiwidget.cpp b/src/eepp/ui/uiwidget.cpp index 3fc0983c2..c6bb219a7 100644 --- a/src/eepp/ui/uiwidget.cpp +++ b/src/eepp/ui/uiwidget.cpp @@ -235,6 +235,9 @@ void UIWidget::onChildCountChange( Node* child, const bool& removed ) { } if ( !isSceneNodeLoading() && mUISceneNode != NULL && mStyle != NULL ) { + // Childs that are structurally volatile can change states when a new + // element is added to the parent. We pre-store them and invalidate its + // state if that's the case. auto& svc = mStyle->getStructurallyVolatileChilds(); for ( auto& child : svc ) { mUISceneNode->invalidateStyleState( child );