#ifndef VOXEL_PROVIDER_THREAD_H #define VOXEL_PROVIDER_THREAD_H #include "../math/rect3i.h" #include #include class VoxelProvider; class VoxelBuffer; class Thread; class Semaphore; class VoxelProviderThread { public: struct ImmergeInput { Vector3i origin; Ref voxels; int lod = 0; }; struct EmergeInput { Vector3i block_position; int lod = 0; }; struct InputData { std::vector blocks_to_immerge; std::vector blocks_to_emerge; Vector3i priority_block_position; // In LOD0 block coordinates int exclusive_region_extent = 0; bool use_exclusive_region = false; inline bool is_empty() { return blocks_to_emerge.empty() && blocks_to_immerge.empty(); } }; struct EmergeOutput { Ref voxels; Vector3i origin_in_voxels; // TODO Remove this, redundant now Vector3i block_position; int lod = 0; }; struct Stats { bool first = true; uint64_t min_time = 0; uint64_t max_time = 0; int remaining_blocks = 0; uint64_t sort_time = 0; }; struct OutputData { Vector emerged_blocks; Stats stats; }; VoxelProviderThread(Ref provider, int block_size_pow2); ~VoxelProviderThread(); void push(const InputData &input); void pop(OutputData &out_data); static Dictionary to_dictionary(const Stats &stats); private: static void _thread_func(void *p_self); void thread_func(); void thread_sync(int emerge_index, Stats stats, uint64_t &out_sort_time); private: InputData _shared_input; Mutex *_input_mutex; Vector _shared_output; Stats _shared_stats; Mutex *_output_mutex; Semaphore *_semaphore; bool _thread_exit; Thread *_thread; InputData _input; Vector _output; int _block_size_pow2; Ref _voxel_provider; }; #endif // VOXEL_PROVIDER_THREAD_H