Fix case where a block gets saved but is requested for loading very shortly after

When a block gets saved, a thread event comes back to confirm it,
but that event can be mistaken for a loading event because nothing was
explicitely checking for it. It worked so far because the "loading blocks"
check was luckily taking "care" of it, except in that edge case.
This commit is contained in:
Marc Gilleron 2020-02-04 15:37:52 +01:00
parent 88d170adff
commit e9d431360b
4 changed files with 17 additions and 1 deletions

View File

@ -104,6 +104,7 @@ void VoxelDataLoader::process_blocks_thread_func(const ArraySlice<InputBlock> in
if (ib.data.voxels_to_save.is_null()) {
output.type = TYPE_LOAD;
output.voxels_loaded = emerge_requests.write[iload].voxel_buffer;
CRASH_COND(output.voxels_loaded.is_null());
++iload;
} else {

View File

@ -13,7 +13,8 @@ public:
};
enum RequestType {
TYPE_SAVE = 0,
TYPE_NOT_INITIALIZED = 0, // For error detection
TYPE_SAVE,
TYPE_LOAD
};

View File

@ -980,6 +980,13 @@ void VoxelLodTerrain::_process() {
const VoxelDataLoader::OutputBlock &ob = output.blocks[i];
if(ob.data.type == VoxelDataLoader::TYPE_SAVE) {
// That's a save confirmation event.
// Note: in the future, if blocks don't get copied before being sent for saving,
// we will need to use block versionning to know when we can reset the `modified` flag properly
continue;
}
if (ob.lod >= get_lod_count()) {
// That block was requested at a time where LOD was higher... drop it
++_stats.dropped_block_loads;
@ -1657,6 +1664,7 @@ void VoxelLodTerrain::_bind_methods() {
ClassDB::bind_method(D_METHOD("debug_get_block_info", "block_pos", "lod"), &VoxelLodTerrain::debug_get_block_info);
ClassDB::bind_method(D_METHOD("debug_get_last_unexpected_block_drops"), &VoxelLodTerrain::debug_get_last_unexpected_block_drops);
ClassDB::bind_method(D_METHOD("debug_get_octrees"), &VoxelLodTerrain::debug_get_octrees);
ClassDB::bind_method(D_METHOD("debug_save_all_modified_blocks"), &VoxelLodTerrain::_b_save_all_modified_blocks);
ClassDB::bind_method(D_METHOD("_on_stream_params_changed"), &VoxelLodTerrain::_on_stream_params_changed);
@ -1669,3 +1677,7 @@ void VoxelLodTerrain::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_collisions"), "set_generate_collisions", "get_generate_collisions");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_lod_count"), "set_collision_lod_count", "get_collision_lod_count");
}
void VoxelLodTerrain::_b_save_all_modified_blocks() {
save_all_modified_blocks(true);
}

View File

@ -115,6 +115,8 @@ private:
void process_transition_updates();
uint8_t get_transition_mask(Vector3i block_pos, int lod_index) const;
void _b_save_all_modified_blocks();
struct OctreeItem {
LodOctree octree;
};