#pragma once #include #include #include "../data/math.hpp" #include "../data/safe_queue.hpp" #include "../data/safe_priority_queue.hpp" #include "../data/circular_buffer.hpp" #include "../data/geometry/Ray.hpp" #include "forward.h" #include "Area.hpp" #include "Voxel.hpp" #define REPORT_BUFFER_SIZE 128 namespace contouring { class Abstract; }; using namespace data; /// Universe data namespace world { /// Whole universe container class Universe { public: /// Distance management struct options { /// Radius in chunks to load if missing int loadDistance = 5; /// Radius in chunks to keep in memory int keepDistance = 6; /// Storage path std::string folderPath = "world"; }; /// Reports to UI struct report { /// Chunks in memory report_buffer chunk_count; /// Loaded chunks report_buffer chunk_load; /// Saved chunks report_buffer chunk_unload; /// Regions in memory report_buffer region_count; }; Universe(const options &); ~Universe(); /// Update physics and contouring void update(const voxel_pos &pos, float deltaTime, report &rep); /// Apply new options void setOptions(const options &); struct ray_target { area_ pos; Voxel value; voxel_pos offset; }; /// Get nearest voxel colliding ray /// @note ray in world scale std::optional raycast(const geometry::Ray &ray) const; /// Set voxel at pos std::optional set(const area_ &pos, const Voxel &val); /// Set cube of voxel with pos as center /// MAYBE: allow set multi area ItemList setCube(const area_ &pos, const Voxel &val, int radius); /// Change contouring worker void setContouring(const std::shared_ptr& ct); /// Get current contouring worker std::shared_ptr getContouring() const { return contouring; } private: chunk_pos last_pos = chunk_pos(INT_MAX); /// Alive areas containing chunks area_map areas; using area_it_t = robin_hood::pair>; /// Dead areas data::generational::vector far_areas; void saveAreas() const; bool running = true; std::vector loadWorkers; safe_priority_queue_map, std::shared_ptr, int, area_hash> loadQueue; //NOTE: consider Area const (getRegion uses mutex) safe_queue, std::shared_ptr>> loadedQueue; std::vector saveWorkers; using save_task_t = std::pair>>; data::safe_queue saveQueue; //NOTE: consider Area and Chunk const int loadDistance; int keepDistance; std::string folderPath; dict_set dicts; /// Contouring worker std::shared_ptr contouring; }; }