Fix bad discarding code when block management threads are told to exit

In short, std::remove_if does NOT remove anything
master
Marc Gilleron 2020-01-19 18:13:00 +00:00
parent 3263001c5f
commit e76e4d2b49
4 changed files with 49 additions and 36 deletions

View File

@ -388,8 +388,13 @@ private:
if (!data.input.blocks.empty()) {
if (data.thread_exit) {
// Remove all queries except those that can't be discarded
std::remove_if(data.input.blocks.begin(), data.input.blocks.end(),
// Flush inputs we processed already
shift_up(data.input.blocks, queue_index);
queue_index = 0;
// Remove all remaining queries except those that can't be discarded.
// Since the thread is exiting, we don't care anymore about sorting.
unordered_remove_if(data.input.blocks,
[](const InputBlock &b) {
return b.can_be_discarded;
});
@ -418,7 +423,7 @@ private:
}
data.processor(
ArraySlice<InputBlock>(&data.input.blocks[0], input_begin, input_begin + batch_count),
ArraySlice<InputBlock>(data.input.blocks, input_begin, input_begin + batch_count),
ArraySlice<OutputBlock>(&data.output.blocks.write[0], output_begin, output_begin + batch_count),
stats.processor);

View File

@ -590,17 +590,6 @@ bool VoxelLodTerrain::check_block_loaded_and_updated(VoxelBlock *block) {
return true;
}
template <typename T, typename F>
inline void unordered_remove_if(std::vector<T> &vec, F predicate) {
for (unsigned int i = 0; i < vec.size(); ++i) {
if (predicate(vec[i])) {
vec[i] = vec.back();
vec.pop_back();
--i;
}
}
}
void VoxelLodTerrain::send_block_data_requests() {
VoxelDataLoader::Input input;

View File

@ -3,17 +3,27 @@
#include "fixed_array.h"
#include <core/error_macros.h>
#include <vector>
// View into an array, referencing a pointer and a size.
template <typename T>
class ArraySlice {
public:
// TODO Get rid of unsafe constructor, use specialized ones
inline ArraySlice(T *p_ptr, size_t p_begin, size_t p_end) {
CRASH_COND(p_end <= p_begin);
_ptr = p_ptr + p_begin;
_size = p_end - p_begin;
}
inline ArraySlice(std::vector<T> &vec, size_t p_begin, size_t p_end) {
CRASH_COND(p_end <= p_begin);
CRASH_COND(p_begin >= vec.size());
CRASH_COND(p_end > vec.size()); // `>` because p_end is typically `p_begin + size`
_ptr = &vec[p_begin];
_size = p_end - p_begin;
}
template <unsigned int N>
inline ArraySlice(FixedArray<T, N> &a) {
_ptr = a.data();

View File

@ -42,6 +42,37 @@ void unordered_remove(Vector<T> &v, unsigned int pos) {
v.resize(last);
}
// Removes all items satisfying the given predicate.
// This can change the size of the container, and original order of items is not preserved.
template <typename T, typename F>
inline void unordered_remove_if(std::vector<T> &vec, F predicate) {
for (unsigned int i = 0; i < vec.size(); ++i) {
if (predicate(vec[i])) {
vec[i] = vec.back();
vec.pop_back();
--i;
}
}
}
// Removes all items satisfying the given predicate.
// This can reduce the size of the container. Items are moved to preserve order.
//template <typename T, typename F>
//inline void remove_if(std::vector<T> &vec, F predicate) {
// unsigned int j = 0;
// for (unsigned int i = 0; i < vec.size(); ++i) {
// if (predicate(vec[i])) {
// continue;
// } else {
// if (i != j) {
// vec[j] = vec[i];
// }
// ++j;
// }
// }
// vec.resize(j);
//}
template <typename T>
void copy_to(PoolVector<T> &to, const Vector<T> &from) {
@ -127,28 +158,6 @@ inline int wrap(int x, int d) {
return ((x % d) + d) % d;
}
//inline Vector3 get_gradient_normal(float left, float right, float bottom, float top, float back, float front, float middle) {
// float gx, gy, gz;
// // Float equality, but based on the assumption these come from voxels. Voxels are quantized integer values.
// if (left == right && bottom == top && back == front) {
// // Sided gradient
// // Won't be zero in cells that have triangles in them
// gx = left - middle;
// gy = bottom - middle;
// gz = back - middle;
// } else {
// // Symetric gradient
// gx = left - right;
// gy = bottom - top;
// gz = back - front;
// }
// return Vector3(gx, gy, gz).normalized();
//}
#if TOOLS_ENABLED
namespace VoxelDebug {
void create_debug_box_mesh();