#pragma once #include #include #include #include #include "../DrawData.hpp" #include "../DrawComponents/DrawComponent.hpp" class DrawingProgram; class DrawingProgramCache; class DrawingProgramCacheBVHNode { public: SCollision::AABB bounds; std::vector components; std::vector> children; CoordSpaceHelper coords; Vector2i resolution; struct DrawCacheData { uint64_t lastDrawnComponentPlacement; sk_sp surface; std::chrono::steady_clock::time_point lastRenderTime; DrawingProgramCache* attachedCache; std::optional> invalidBounds; bool isInvalid = false; }; std::optional drawCache; }; class DrawingProgramCache { public: DrawingProgramCache(DrawingProgram& initDrawP); ~DrawingProgramCache(); static constexpr size_t MINIMUM_COMPONENTS_TO_START_REBUILD = 1000; static constexpr size_t MAXIMUM_COMPONENTS_IN_SINGLE_NODE = 50; bool check_if_rebuild_should_occur(); void test_rebuild(const std::vector& comps, bool force = false); void test_rebuild_dont_include_set(const std::vector& comps, const std::unordered_set& objsToNotInclude, bool force = false); void test_rebuild_dont_include_set_dont_include_nodes(const std::vector& comps, const std::unordered_set& objsToNotInclude, const std::unordered_set>& nodesToNotInclude, bool force = false); static void move_components_from_bvh_nodes_to_set(std::unordered_set& s, const std::unordered_set>& bvhNodes); static void move_components_from_bvh_node_to_set(std::unordered_set& s, const std::shared_ptr& bvhNode); void erase_component(const CollabListType::ObjectInfoPtr& c); void add_component(const CollabListType::ObjectInfoPtr& c); void refresh_all_draw_cache(const DrawData& drawData); void traverse_bvh_run_function(const SCollision::AABB& aabb, std::function& node, const std::vector& components)> f); void traverse_bvh_erase_function(const SCollision::AABB& aabb, std::function& node, std::vector& components)> f); // Run before actually updating the component void preupdate_component(const CollabListType::ObjectInfoPtr& c); void invalidate_cache_before_pos(uint64_t placementToInvalidateAt); void invalidate_cache_at_aabb_before_pos(const SCollision::AABB& aabb, uint64_t placementToInvalidateAt); void invalidate_cache_at_optional_aabb_before_pos(const std::optional>& aabb, uint64_t placementToInvalidateAt); void clear(); struct DrawComponentsToCanvasOptionalData { uint64_t* lastDrawnComponentPlacement = nullptr; std::optional> drawBounds; }; void draw_components_to_canvas(SkCanvas* canvas, const DrawData& drawData, DrawComponentsToCanvasOptionalData optData); const std::vector& get_unsorted_component_list() const; const std::chrono::steady_clock::time_point& get_last_bvh_build_time() const; void clear_own_cached_surfaces(); CollabListType::ObjectInfoPtr get_front_object_colliding_with(const SCollision::ColliderCollection& cC); private: static std::unordered_set> nodesWithCachedSurfaces; void draw_cache_image_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::shared_ptr& bvhNode); void force_rebuild_dont_include_objs(std::vector componentsToBuild, const std::unordered_set& objsToNotInclude); void force_rebuild(const std::vector& componentsToBuild); bool traverse_bvh_erase_function_recursive(const std::shared_ptr& bvhNode, const SCollision::AABB& aabb, std::function& node, std::vector& components)> f); void build_bvh_node_coords_and_resolution(DrawingProgramCacheBVHNode& node); void refresh_draw_cache(const std::shared_ptr& bvhNode, const DrawData& drawData); void build(std::vector components); void traverse_bvh_run_function_recursive(const std::shared_ptr& bvhNode, const SCollision::AABB& aabb, std::function& node, const std::vector& components)> f); std::pair, std::vector::iterator> get_bvh_node_fully_containing_recursive(const std::shared_ptr& bvhNode, DrawComponent* c); void build_bvh_node(const std::shared_ptr& bvhNode, const std::vector& components); std::chrono::steady_clock::time_point lastBvhBuildTime; std::shared_ptr bvhRoot; std::vector unsortedComponents; DrawingProgram& drawP; };