#pragma once #include #include #include #include "../data/safe_queue.hpp" #include "../data/safe_priority_queue.hpp" #include "../data/circular_buffer.hpp" #include "Chunk.hpp" #include "../data/geometry/Ray.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 circular_buffer chunk_count = circular_buffer(REPORT_BUFFER_SIZE, 0); // MAYBE: store int /// Loaded chunks circular_buffer chunk_load = circular_buffer(REPORT_BUFFER_SIZE, 0); /// Saved chunks circular_buffer chunk_unload = circular_buffer(REPORT_BUFFER_SIZE, 0); }; Universe(const options&); ~Universe(); /// Update physics and contouring void update(const camera_pos& pos, report& rep); /// Apply new options void setOptions(const options &); /// 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 voxel_pos &pos, const Voxel &val); /// Set cube of voxel with pos as center ItemList setCube(const voxel_pos &pos, const Voxel &val, int radius); /// Change contouring worker void setContouring(std::shared_ptr); /// Get current contouring worker std::shared_ptr getContouring() const { return contouring; } private: chunk_pos last_pos = chunk_pos(INT_MAX); /// Data robin_hood::unordered_map> chunks; std::optional> at(const chunk_pos& pos) const { const auto it = chunks.find(pos); if(it == chunks.end()) return {}; return {it->second}; } /// Generating worker pool class LoadPool { public: LoadPool(size_t size, const std::string& folderPath); ~LoadPool(); Generator generator; inline void push(const chunk_pos &pos, int weight); inline bool pop(robin_hood::pair> &out); inline size_t size(); private: std::string folderPath; std::vector workers; bool running = true; safe_priority_queue loadQueue; safe_queue>> loadedQueue; }; LoadPool loadPool; /// Write to file worker pool class SavePool { public: SavePool(size_t size, const std::string& folderPath); ~SavePool(); inline void push(const robin_hood::pair> &chunk); inline size_t size(); private: std::string folderPath; std::vector workers; bool running = true; safe_queue>> queue; //NOTE: consider const Chunk }; SavePool savePool; int loadDistance; int keepDistance; std::string folderPath; /// Contouring worker std::shared_ptr contouring; }; }