mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 02:20:04 +00:00 
			
		
		
		
	Hold a reference to current images in the placefile manager, removing old, unused images
This commit is contained in:
		
							parent
							
								
									9165d66a33
								
							
						
					
					
						commit
						bbaae5d1ba
					
				
					 5 changed files with 68 additions and 63 deletions
				
			
		|  | @ -51,7 +51,8 @@ public: | ||||||
|    void ReadPlacefileSettings(); |    void ReadPlacefileSettings(); | ||||||
|    void WritePlacefileSettings(); |    void WritePlacefileSettings(); | ||||||
| 
 | 
 | ||||||
|    static void LoadResources(const std::shared_ptr<gr::Placefile>& placefile); |    static std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> | ||||||
|  |    LoadResources(const std::shared_ptr<gr::Placefile>& placefile); | ||||||
| 
 | 
 | ||||||
|    boost::asio::thread_pool threadPool_ {1u}; |    boost::asio::thread_pool threadPool_ {1u}; | ||||||
| 
 | 
 | ||||||
|  | @ -134,6 +135,8 @@ public: | ||||||
|    std::mutex                     refreshMutex_ {}; |    std::mutex                     refreshMutex_ {}; | ||||||
|    std::mutex                     timerMutex_ {}; |    std::mutex                     timerMutex_ {}; | ||||||
| 
 | 
 | ||||||
|  |    std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> images_ {}; | ||||||
|  | 
 | ||||||
|    std::string                           lastRadarSite_ {}; |    std::string                           lastRadarSite_ {}; | ||||||
|    std::chrono::system_clock::time_point lastUpdateTime_ {}; |    std::chrono::system_clock::time_point lastUpdateTime_ {}; | ||||||
| }; | }; | ||||||
|  | @ -276,6 +279,7 @@ void PlacefileManager::set_placefile_url(const std::string& name, | ||||||
|       auto placefileRecord        = it->second; |       auto placefileRecord        = it->second; | ||||||
|       placefileRecord->name_      = normalizedUrl; |       placefileRecord->name_      = normalizedUrl; | ||||||
|       placefileRecord->placefile_ = nullptr; |       placefileRecord->placefile_ = nullptr; | ||||||
|  |       placefileRecord->images_.clear(); | ||||||
|       p->placefileRecordMap_.erase(it); |       p->placefileRecordMap_.erase(it); | ||||||
|       p->placefileRecordMap_.insert_or_assign(normalizedUrl, placefileRecord); |       p->placefileRecordMap_.insert_or_assign(normalizedUrl, placefileRecord); | ||||||
| 
 | 
 | ||||||
|  | @ -633,7 +637,7 @@ void PlacefileManager::Impl::PlacefileRecord::Update() | ||||||
|    if (updatedPlacefile != nullptr) |    if (updatedPlacefile != nullptr) | ||||||
|    { |    { | ||||||
|       // Load placefile resources
 |       // Load placefile resources
 | ||||||
|       Impl::LoadResources(updatedPlacefile); |       auto newImages = Impl::LoadResources(updatedPlacefile); | ||||||
| 
 | 
 | ||||||
|       // Check the name matches, in case the name updated
 |       // Check the name matches, in case the name updated
 | ||||||
|       if (name_ == name) |       if (name_ == name) | ||||||
|  | @ -643,6 +647,10 @@ void PlacefileManager::Impl::PlacefileRecord::Update() | ||||||
|          title_          = placefile_->title(); |          title_          = placefile_->title(); | ||||||
|          lastUpdateTime_ = std::chrono::system_clock::now(); |          lastUpdateTime_ = std::chrono::system_clock::now(); | ||||||
| 
 | 
 | ||||||
|  |          // Update image resources
 | ||||||
|  |          images_.swap(newImages); | ||||||
|  |          newImages.clear(); | ||||||
|  | 
 | ||||||
|          if (p->radarSite_ != nullptr) |          if (p->radarSite_ != nullptr) | ||||||
|          { |          { | ||||||
|             lastRadarSite_ = p->radarSite_->id(); |             lastRadarSite_ = p->radarSite_->id(); | ||||||
|  | @ -736,7 +744,8 @@ std::shared_ptr<PlacefileManager> PlacefileManager::Instance() | ||||||
|    return placefileManager; |    return placefileManager; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileManager::Impl::LoadResources( | std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> | ||||||
|  | PlacefileManager::Impl::LoadResources( | ||||||
|    const std::shared_ptr<gr::Placefile>& placefile) |    const std::shared_ptr<gr::Placefile>& placefile) | ||||||
| { | { | ||||||
|    const auto iconFiles = placefile->icon_files(); |    const auto iconFiles = placefile->icon_files(); | ||||||
|  | @ -790,7 +799,7 @@ void PlacefileManager::Impl::LoadResources( | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    ResourceManager::LoadImageResources(urlStrings); |    return ResourceManager::LoadImageResources(urlStrings); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace manager
 | } // namespace manager
 | ||||||
|  |  | ||||||
|  | @ -64,36 +64,40 @@ std::shared_ptr<util::Font> Font(types::Font font) | ||||||
|    return nullptr; |    return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool LoadImageResource(const std::string& urlString) | std::shared_ptr<boost::gil::rgba8_image_t> | ||||||
|  | LoadImageResource(const std::string& urlString) | ||||||
| { | { | ||||||
|    util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); |    util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); | ||||||
|    return textureAtlas.CacheTexture(urlString, urlString); |    return textureAtlas.CacheTexture(urlString, urlString); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LoadImageResources(const std::vector<std::string>& urlStrings) | std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> | ||||||
|  | LoadImageResources(const std::vector<std::string>& urlStrings) | ||||||
| { | { | ||||||
|    std::mutex m {}; |    std::mutex                                              m {}; | ||||||
|    bool       textureCached = false; |    std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> images {}; | ||||||
| 
 | 
 | ||||||
|    std::for_each(std::execution::par_unseq, |    std::for_each(std::execution::par_unseq, | ||||||
|                  urlStrings.begin(), |                  urlStrings.begin(), | ||||||
|                  urlStrings.end(), |                  urlStrings.end(), | ||||||
|                  [&](auto& urlString) |                  [&](auto& urlString) | ||||||
|                  { |                  { | ||||||
|                     bool value = LoadImageResource(urlString); |                     auto image = LoadImageResource(urlString); | ||||||
| 
 | 
 | ||||||
|                     if (value) |                     if (image != nullptr) | ||||||
|                     { |                     { | ||||||
|                        std::unique_lock lock {m}; |                        std::unique_lock lock {m}; | ||||||
|                        textureCached = true; |                        images.emplace_back(std::move(image)); | ||||||
|                     } |                     } | ||||||
|                  }); |                  }); | ||||||
| 
 | 
 | ||||||
|    if (textureCached) |    if (!images.empty()) | ||||||
|    { |    { | ||||||
|       util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); |       util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); | ||||||
|       textureAtlas.BuildAtlas(2048, 2048); |       textureAtlas.BuildAtlas(2048, 2048); | ||||||
|    } |    } | ||||||
|  | 
 | ||||||
|  |    return images; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void LoadFonts() | static void LoadFonts() | ||||||
|  |  | ||||||
|  | @ -3,6 +3,10 @@ | ||||||
| #include <scwx/qt/types/font_types.hpp> | #include <scwx/qt/types/font_types.hpp> | ||||||
| #include <scwx/qt/util/font.hpp> | #include <scwx/qt/util/font.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <boost/gil/typedefs.hpp> | ||||||
|  | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
| namespace qt | namespace qt | ||||||
|  | @ -18,8 +22,10 @@ void Shutdown(); | ||||||
| int                         FontId(types::Font font); | int                         FontId(types::Font font); | ||||||
| std::shared_ptr<util::Font> Font(types::Font font); | std::shared_ptr<util::Font> Font(types::Font font); | ||||||
| 
 | 
 | ||||||
| bool LoadImageResource(const std::string& urlString); | std::shared_ptr<boost::gil::rgba8_image_t> | ||||||
| void LoadImageResources(const std::vector<std::string>& urlStrings); | LoadImageResource(const std::string& urlString); | ||||||
|  | std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> | ||||||
|  | LoadImageResources(const std::vector<std::string>& urlStrings); | ||||||
| 
 | 
 | ||||||
| } // namespace ResourceManager
 | } // namespace ResourceManager
 | ||||||
| } // namespace manager
 | } // namespace manager
 | ||||||
|  |  | ||||||
|  | @ -48,11 +48,12 @@ public: | ||||||
|    static std::shared_ptr<boost::gil::rgba8_image_t> |    static std::shared_ptr<boost::gil::rgba8_image_t> | ||||||
|    LoadImage(const std::string& imagePath); |    LoadImage(const std::string& imagePath); | ||||||
| 
 | 
 | ||||||
|    std::unordered_map<std::string, std::string> texturePathMap_ {}; |    std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> | ||||||
|    std::shared_mutex                            texturePathMutex_ {}; |                      registeredTextures_ {}; | ||||||
|  |    std::shared_mutex registeredTextureMutex_ {}; | ||||||
| 
 | 
 | ||||||
|    std::shared_mutex textureCacheMutex_ {}; |    std::shared_mutex textureCacheMutex_ {}; | ||||||
|    std::unordered_map<std::string, std::shared_ptr<boost::gil::rgba8_image_t>> |    std::unordered_map<std::string, std::weak_ptr<boost::gil::rgba8_image_t>> | ||||||
|       textureCache_ {}; |       textureCache_ {}; | ||||||
| 
 | 
 | ||||||
|    std::vector<boost::gil::rgba8_image_t>             atlasArray_ {}; |    std::vector<boost::gil::rgba8_image_t>             atlasArray_ {}; | ||||||
|  | @ -76,12 +77,14 @@ std::uint64_t TextureAtlas::BuildCount() const | ||||||
| void TextureAtlas::RegisterTexture(const std::string& name, | void TextureAtlas::RegisterTexture(const std::string& name, | ||||||
|                                    const std::string& path) |                                    const std::string& path) | ||||||
| { | { | ||||||
|    std::unique_lock lock(p->texturePathMutex_); |    std::unique_lock lock(p->registeredTextureMutex_); | ||||||
|    p->texturePathMap_.insert_or_assign(name, path); | 
 | ||||||
|  |    std::shared_ptr<boost::gil::rgba8_image_t> image = CacheTexture(name, path); | ||||||
|  |    p->registeredTextures_.emplace_back(std::move(image)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool TextureAtlas::CacheTexture(const std::string& name, | std::shared_ptr<boost::gil::rgba8_image_t> | ||||||
|                                 const std::string& path) | TextureAtlas::CacheTexture(const std::string& name, const std::string& path) | ||||||
| { | { | ||||||
|    // Attempt to load the image
 |    // Attempt to load the image
 | ||||||
|    std::shared_ptr<boost::gil::rgba8_image_t> image = |    std::shared_ptr<boost::gil::rgba8_image_t> image = | ||||||
|  | @ -93,12 +96,12 @@ bool TextureAtlas::CacheTexture(const std::string& name, | ||||||
|       // Store it in the texture cache
 |       // Store it in the texture cache
 | ||||||
|       std::unique_lock lock(p->textureCacheMutex_); |       std::unique_lock lock(p->textureCacheMutex_); | ||||||
| 
 | 
 | ||||||
|       p->textureCache_.insert_or_assign(name, std::move(image)); |       p->textureCache_.insert_or_assign(name, image); | ||||||
| 
 | 
 | ||||||
|       return true; |       return image; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return false; |    return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height) | void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height) | ||||||
|  | @ -118,50 +121,28 @@ void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height) | ||||||
|    ImageVector             images {}; |    ImageVector             images {}; | ||||||
|    std::vector<stbrp_rect> stbrpRects {}; |    std::vector<stbrp_rect> stbrpRects {}; | ||||||
| 
 | 
 | ||||||
|    // Load images
 |  | ||||||
|    { |  | ||||||
|       // Take a read lock on the texture path map
 |  | ||||||
|       std::shared_lock lock(p->texturePathMutex_); |  | ||||||
| 
 |  | ||||||
|       // For each registered texture
 |  | ||||||
|       std::for_each( |  | ||||||
|          p->texturePathMap_.cbegin(), |  | ||||||
|          p->texturePathMap_.cend(), |  | ||||||
|          [&](const auto& pair) |  | ||||||
|          { |  | ||||||
|             // Load texture image
 |  | ||||||
|             std::shared_ptr<boost::gil::rgba8_image_t> image = |  | ||||||
|                Impl::LoadImage(pair.second); |  | ||||||
| 
 |  | ||||||
|             if (image != nullptr && image->width() > 0u && image->height() > 0u) |  | ||||||
|             { |  | ||||||
|                // Store STB rectangle pack data in a vector
 |  | ||||||
|                stbrpRects.push_back( |  | ||||||
|                   stbrp_rect {0, |  | ||||||
|                               static_cast<stbrp_coord>(image->width()), |  | ||||||
|                               static_cast<stbrp_coord>(image->height()), |  | ||||||
|                               0, |  | ||||||
|                               0, |  | ||||||
|                               0}); |  | ||||||
| 
 |  | ||||||
|                // Store image data in a vector
 |  | ||||||
|                images.emplace_back(pair.first, std::move(image)); |  | ||||||
|             } |  | ||||||
|          }); |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    // Cached images
 |    // Cached images
 | ||||||
|    { |    { | ||||||
|       // Take a read lock on the texture cache map while adding textures images
 |       // Take a lock on the texture cache map while adding textures images to
 | ||||||
|       // to the atlas vector.
 |       // the atlas vector.
 | ||||||
|       std::shared_lock textureCacheLock(p->textureCacheMutex_); |       std::unique_lock textureCacheLock(p->textureCacheMutex_); | ||||||
| 
 | 
 | ||||||
|       // For each cached texture
 |       // For each cached texture
 | ||||||
|       for (auto& texture : p->textureCache_) |       for (auto it = p->textureCache_.begin(); it != p->textureCache_.end();) | ||||||
|       { |       { | ||||||
|          auto& image = texture.second; |          auto& texture = *it; | ||||||
|  |          auto  image   = texture.second.lock(); | ||||||
| 
 | 
 | ||||||
|          if (image != nullptr && image->width() > 0u && image->height() > 0u) |          if (image == nullptr) | ||||||
|  |          { | ||||||
|  |             logger_->trace("Removing texture from the cache: {}", | ||||||
|  |                            texture.first); | ||||||
|  | 
 | ||||||
|  |             // If the image is no longer cached, erase the iterator and continue
 | ||||||
|  |             it = p->textureCache_.erase(it); | ||||||
|  |             continue; | ||||||
|  |          } | ||||||
|  |          else if (image->width() > 0u && image->height() > 0u) | ||||||
|          { |          { | ||||||
|             // Store STB rectangle pack data in a vector
 |             // Store STB rectangle pack data in a vector
 | ||||||
|             stbrpRects.push_back( |             stbrpRects.push_back( | ||||||
|  | @ -175,6 +156,9 @@ void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height) | ||||||
|             // Store image data in a vector
 |             // Store image data in a vector
 | ||||||
|             images.push_back({texture.first, image}); |             images.push_back({texture.first, image}); | ||||||
|          } |          } | ||||||
|  | 
 | ||||||
|  |          // Increment iterator
 | ||||||
|  |          ++it; | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| #include <string> | #include <string> | ||||||
| 
 | 
 | ||||||
| #include <boost/gil/point.hpp> | #include <boost/gil/point.hpp> | ||||||
|  | #include <boost/gil/typedefs.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  | @ -73,7 +74,8 @@ public: | ||||||
|    std::uint64_t BuildCount() const; |    std::uint64_t BuildCount() const; | ||||||
| 
 | 
 | ||||||
|    void RegisterTexture(const std::string& name, const std::string& path); |    void RegisterTexture(const std::string& name, const std::string& path); | ||||||
|    bool CacheTexture(const std::string& name, const std::string& path); |    std::shared_ptr<boost::gil::rgba8_image_t> | ||||||
|  |         CacheTexture(const std::string& name, const std::string& path); | ||||||
|    void BuildAtlas(std::size_t width, std::size_t height); |    void BuildAtlas(std::size_t width, std::size_t height); | ||||||
|    void BufferAtlas(gl::OpenGLFunctions& gl, GLuint texture); |    void BufferAtlas(gl::OpenGLFunctions& gl, GLuint texture); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat