#pragma once #include "drape/drape_routine.hpp" #include "drape/glyph_manager.hpp" #include "drape/pointers.hpp" #include "geometry/rect2d.hpp" #include #include #include #include #include #include namespace dp { class GlyphGenerator { public: struct GlyphGenerationData { m2::RectU m_rect; GlyphManager::Glyph m_glyph; GlyphGenerationData() = default; GlyphGenerationData(m2::RectU const & rect, GlyphManager::Glyph const & glyph) : m_rect(rect), m_glyph(glyph) {} void DestroyGlyph() { m_glyph.m_image.Destroy(); } }; using GlyphGenerationDataArray = std::vector; class Listener { public: virtual ~Listener() = default; virtual void OnCompleteGlyphGeneration(GlyphGenerationDataArray && glyphs) = 0; }; class GenerateGlyphTask { public: explicit GenerateGlyphTask(GlyphGenerationDataArray && glyphs) : m_glyphs(std::move(glyphs)) , m_isCancelled(false) {} void Run(uint32_t sdfScale); void Cancel() { m_isCancelled = true; } GlyphGenerationDataArray && StealGeneratedGlyphs() { return std::move(m_generatedGlyphs); } bool IsCancelled() const { return m_isCancelled; } void DestroyAllGlyphs(); private: GlyphGenerationDataArray m_glyphs; GlyphGenerationDataArray m_generatedGlyphs; std::atomic m_isCancelled; }; explicit GlyphGenerator(uint32_t sdfScale); ~GlyphGenerator(); void RegisterListener(ref_ptr listener); void UnregisterListener(ref_ptr listener); void GenerateGlyph(ref_ptr listener, m2::RectU const & rect, GlyphManager::Glyph & glyph); void GenerateGlyph(ref_ptr listener, GlyphGenerationData && data); void GenerateGlyphs(ref_ptr listener, GlyphGenerationDataArray && generationData); bool IsSuspended() const; void FinishGeneration(); private: void OnTaskFinished(ref_ptr listener, std::shared_ptr const & task); uint32_t m_sdfScale; std::set> m_listeners; ActiveTasks m_activeTasks; GlyphGenerationDataArray m_queue; size_t m_glyphsCounter = 0; mutable std::mutex m_mutex; }; } // namespace dp