1
0
Fork 0
Univerxel/src/world/Universe.hpp

109 lines
3.5 KiB
C++
Raw Normal View History

2020-07-25 16:45:03 +00:00
#pragma once
2020-07-31 17:09:44 +00:00
#include <string>
2020-07-25 16:45:03 +00:00
#include <memory>
#include <thread>
2020-07-31 17:09:44 +00:00
#include <shared_mutex>
#include "../data/math.hpp"
2020-07-25 16:45:03 +00:00
#include "../data/safe_queue.hpp"
#include "../data/safe_priority_queue.hpp"
#include "../data/circular_buffer.hpp"
#include "../data/geometry/Ray.hpp"
2020-07-31 17:09:44 +00:00
#include "forward.h"
#include "Voxel.hpp"
2020-07-31 20:26:07 +00:00
#include "region/index.hpp"
2020-07-31 17:09:44 +00:00
#include "Generator.hpp"
typedef glm::vec3 camera_pos;
2020-07-25 16:45:03 +00:00
#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;
2020-07-26 20:53:14 +00:00
/// Storage path
std::string folderPath = "world";
2020-07-25 16:45:03 +00:00
};
/// Reports to UI
struct report {
/// Chunks in memory
circular_buffer<float> chunk_count = circular_buffer<float>(REPORT_BUFFER_SIZE, 0); // MAYBE: store int
/// Loaded chunks
circular_buffer<float> chunk_load = circular_buffer<float>(REPORT_BUFFER_SIZE, 0);
/// Saved chunks
circular_buffer<float> chunk_unload = circular_buffer<float>(REPORT_BUFFER_SIZE, 0);
2020-07-31 17:09:44 +00:00
/// Regions in memory
circular_buffer<float> region_count = circular_buffer<float>(REPORT_BUFFER_SIZE, 0);
2020-07-25 16:45:03 +00:00
};
2020-07-31 17:09:44 +00:00
Universe(const options &);
2020-07-25 16:45:03 +00:00
~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<std::pair<voxel_pos, Voxel>> raycast(const geometry::Ray &ray) const;
/// Set voxel at pos
std::optional<Item> 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<contouring::Abstract>);
/// Get current contouring worker
std::shared_ptr<contouring::Abstract> getContouring() const {
return contouring;
}
private:
chunk_pos last_pos = chunk_pos(INT_MAX);
/// Data
2020-07-31 17:09:44 +00:00
chunk_map chunks;
2020-07-25 16:45:03 +00:00
std::optional<std::shared_ptr<Chunk>> at(const chunk_pos& pos) const {
const auto it = chunks.find(pos);
if(it == chunks.end())
return {};
return {it->second};
}
2020-07-30 16:35:13 +00:00
Generator generator;
2020-07-25 16:45:03 +00:00
2020-07-30 16:35:13 +00:00
bool running = true;
std::vector<std::thread> loadWorkers;
safe_priority_queue<chunk_pos, int> loadQueue;
safe_queue<robin_hood::pair<chunk_pos, std::shared_ptr<Chunk>>> loadedQueue;
2020-07-25 16:45:03 +00:00
2020-07-30 16:35:13 +00:00
std::vector<std::thread> saveWorkers;
safe_queue<robin_hood::pair<chunk_pos, std::shared_ptr<Chunk>>> saveQueue; //NOTE: consider const Chunk
2020-07-25 16:45:03 +00:00
int loadDistance;
int keepDistance;
2020-07-26 20:53:14 +00:00
std::string folderPath;
2020-07-25 16:45:03 +00:00
2020-07-30 16:35:13 +00:00
std::shared_mutex regionMutex; //MAYBE: shared_guard
robin_hood::unordered_map<region_pos, std::shared_ptr<Region>> regionCache;
2020-07-31 20:26:07 +00:00
dict_set regionDict;
2020-07-30 16:35:13 +00:00
std::shared_ptr<Region> getRegion(const region_pos &);
2020-07-25 16:45:03 +00:00
/// Contouring worker
std::shared_ptr<contouring::Abstract> contouring;
};
}