mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 03:40:05 +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 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}; | ||||
| 
 | ||||
|  | @ -134,6 +135,8 @@ public: | |||
|    std::mutex                     refreshMutex_ {}; | ||||
|    std::mutex                     timerMutex_ {}; | ||||
| 
 | ||||
|    std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> images_ {}; | ||||
| 
 | ||||
|    std::string                           lastRadarSite_ {}; | ||||
|    std::chrono::system_clock::time_point lastUpdateTime_ {}; | ||||
| }; | ||||
|  | @ -276,6 +279,7 @@ void PlacefileManager::set_placefile_url(const std::string& name, | |||
|       auto placefileRecord        = it->second; | ||||
|       placefileRecord->name_      = normalizedUrl; | ||||
|       placefileRecord->placefile_ = nullptr; | ||||
|       placefileRecord->images_.clear(); | ||||
|       p->placefileRecordMap_.erase(it); | ||||
|       p->placefileRecordMap_.insert_or_assign(normalizedUrl, placefileRecord); | ||||
| 
 | ||||
|  | @ -633,7 +637,7 @@ void PlacefileManager::Impl::PlacefileRecord::Update() | |||
|    if (updatedPlacefile != nullptr) | ||||
|    { | ||||
|       // Load placefile resources
 | ||||
|       Impl::LoadResources(updatedPlacefile); | ||||
|       auto newImages = Impl::LoadResources(updatedPlacefile); | ||||
| 
 | ||||
|       // Check the name matches, in case the name updated
 | ||||
|       if (name_ == name) | ||||
|  | @ -643,6 +647,10 @@ void PlacefileManager::Impl::PlacefileRecord::Update() | |||
|          title_          = placefile_->title(); | ||||
|          lastUpdateTime_ = std::chrono::system_clock::now(); | ||||
| 
 | ||||
|          // Update image resources
 | ||||
|          images_.swap(newImages); | ||||
|          newImages.clear(); | ||||
| 
 | ||||
|          if (p->radarSite_ != nullptr) | ||||
|          { | ||||
|             lastRadarSite_ = p->radarSite_->id(); | ||||
|  | @ -736,7 +744,8 @@ std::shared_ptr<PlacefileManager> PlacefileManager::Instance() | |||
|    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 auto iconFiles = placefile->icon_files(); | ||||
|  | @ -790,7 +799,7 @@ void PlacefileManager::Impl::LoadResources( | |||
|       } | ||||
|    } | ||||
| 
 | ||||
|    ResourceManager::LoadImageResources(urlStrings); | ||||
|    return ResourceManager::LoadImageResources(urlStrings); | ||||
| } | ||||
| 
 | ||||
| } // namespace manager
 | ||||
|  |  | |||
|  | @ -64,36 +64,40 @@ std::shared_ptr<util::Font> Font(types::Font font) | |||
|    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(); | ||||
|    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 {}; | ||||
|    bool       textureCached = false; | ||||
|    std::mutex                                              m {}; | ||||
|    std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> images {}; | ||||
| 
 | ||||
|    std::for_each(std::execution::par_unseq, | ||||
|                  urlStrings.begin(), | ||||
|                  urlStrings.end(), | ||||
|                  [&](auto& urlString) | ||||
|                  { | ||||
|                     bool value = LoadImageResource(urlString); | ||||
|                     auto image = LoadImageResource(urlString); | ||||
| 
 | ||||
|                     if (value) | ||||
|                     if (image != nullptr) | ||||
|                     { | ||||
|                        std::unique_lock lock {m}; | ||||
|                        textureCached = true; | ||||
|                        images.emplace_back(std::move(image)); | ||||
|                     } | ||||
|                  }); | ||||
| 
 | ||||
|    if (textureCached) | ||||
|    if (!images.empty()) | ||||
|    { | ||||
|       util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); | ||||
|       textureAtlas.BuildAtlas(2048, 2048); | ||||
|    } | ||||
| 
 | ||||
|    return images; | ||||
| } | ||||
| 
 | ||||
| static void LoadFonts() | ||||
|  |  | |||
|  | @ -3,6 +3,10 @@ | |||
| #include <scwx/qt/types/font_types.hpp> | ||||
| #include <scwx/qt/util/font.hpp> | ||||
| 
 | ||||
| #include <vector> | ||||
| 
 | ||||
| #include <boost/gil/typedefs.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
|  | @ -18,8 +22,10 @@ void Shutdown(); | |||
| int                         FontId(types::Font font); | ||||
| std::shared_ptr<util::Font> Font(types::Font font); | ||||
| 
 | ||||
| bool LoadImageResource(const std::string& urlString); | ||||
| void LoadImageResources(const std::vector<std::string>& urlStrings); | ||||
| std::shared_ptr<boost::gil::rgba8_image_t> | ||||
| 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 manager
 | ||||
|  |  | |||
|  | @ -48,11 +48,12 @@ public: | |||
|    static std::shared_ptr<boost::gil::rgba8_image_t> | ||||
|    LoadImage(const std::string& imagePath); | ||||
| 
 | ||||
|    std::unordered_map<std::string, std::string> texturePathMap_ {}; | ||||
|    std::shared_mutex                            texturePathMutex_ {}; | ||||
|    std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> | ||||
|                      registeredTextures_ {}; | ||||
|    std::shared_mutex registeredTextureMutex_ {}; | ||||
| 
 | ||||
|    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_ {}; | ||||
| 
 | ||||
|    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, | ||||
|                                    const std::string& path) | ||||
| { | ||||
|    std::unique_lock lock(p->texturePathMutex_); | ||||
|    p->texturePathMap_.insert_or_assign(name, path); | ||||
|    std::unique_lock lock(p->registeredTextureMutex_); | ||||
| 
 | ||||
|    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, | ||||
|                                 const std::string& path) | ||||
| std::shared_ptr<boost::gil::rgba8_image_t> | ||||
| TextureAtlas::CacheTexture(const std::string& name, const std::string& path) | ||||
| { | ||||
|    // Attempt to load the 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
 | ||||
|       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) | ||||
|  | @ -118,50 +121,28 @@ void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height) | |||
|    ImageVector             images {}; | ||||
|    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
 | ||||
|    { | ||||
|       // Take a read lock on the texture cache map while adding textures images
 | ||||
|       // to the atlas vector.
 | ||||
|       std::shared_lock textureCacheLock(p->textureCacheMutex_); | ||||
|       // Take a lock on the texture cache map while adding textures images to
 | ||||
|       // the atlas vector.
 | ||||
|       std::unique_lock textureCacheLock(p->textureCacheMutex_); | ||||
| 
 | ||||
|       // 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
 | ||||
|             stbrpRects.push_back( | ||||
|  | @ -175,6 +156,9 @@ void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height) | |||
|             // Store image data in a vector
 | ||||
|             images.push_back({texture.first, image}); | ||||
|          } | ||||
| 
 | ||||
|          // Increment iterator
 | ||||
|          ++it; | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #include <string> | ||||
| 
 | ||||
| #include <boost/gil/point.hpp> | ||||
| #include <boost/gil/typedefs.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -73,7 +74,8 @@ public: | |||
|    std::uint64_t BuildCount() const; | ||||
| 
 | ||||
|    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 BufferAtlas(gl::OpenGLFunctions& gl, GLuint texture); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat