Make pools with generations and bind mouse position logic
This commit is contained in:
+31
-21
@@ -154,12 +154,13 @@ struct Rect {
|
||||
|
||||
template <typename T = void *>
|
||||
struct Pool {
|
||||
T *operator[](int index) {
|
||||
T *operator[](uint64_t index) {
|
||||
if (!is_valid(index)) {
|
||||
fprintf(stderr, "Invalid pool index: %d\n", index);
|
||||
fprintf(stderr, "Invalid pool index: %llu\n", (unsigned long long)index);
|
||||
return nullptr;
|
||||
}
|
||||
return slots[index].ptr;
|
||||
uint32_t id = (uint32_t)(index & 0xFFFFFFFFULL);
|
||||
return slots[id].ptr;
|
||||
}
|
||||
|
||||
const std::vector<T *> &all() {
|
||||
@@ -171,43 +172,51 @@ struct Pool {
|
||||
return all_items;
|
||||
}
|
||||
|
||||
int acquire(T *item) {
|
||||
int index;
|
||||
uint64_t acquire(T *item) {
|
||||
uint32_t id;
|
||||
if (!free_indices.empty()) {
|
||||
index = free_indices.back();
|
||||
id = free_indices.back();
|
||||
free_indices.pop_back();
|
||||
} else {
|
||||
index = slots.size();
|
||||
id = slots.size();
|
||||
slots.push_back({});
|
||||
}
|
||||
slots[index].ptr = item;
|
||||
slots[index].refcount = 1;
|
||||
slots[index].alive = true;
|
||||
slots[id].ptr = item;
|
||||
slots[id].refcount = 1;
|
||||
slots[id].alive = true;
|
||||
slots[id].generation++;
|
||||
uint64_t index = ((uint64_t)slots[id].generation << 32) | id;
|
||||
return index;
|
||||
}
|
||||
|
||||
void use(int index) {
|
||||
if (is_valid(index))
|
||||
slots[index].refcount++;
|
||||
void use(uint64_t index) {
|
||||
if (is_valid(index)) {
|
||||
uint64_t id = (uint32_t)(index & 0xFFFFFFFFULL);
|
||||
slots[id].refcount++;
|
||||
}
|
||||
}
|
||||
|
||||
void release(int index) {
|
||||
void release(uint64_t index) {
|
||||
if (!is_valid(index))
|
||||
return;
|
||||
auto &slot = slots[index];
|
||||
uint32_t id = (uint32_t)(index & 0xFFFFFFFFULL);
|
||||
auto &slot = slots[id];
|
||||
slot.refcount--;
|
||||
if (slot.refcount <= 0) {
|
||||
delete slot.ptr;
|
||||
slot.ptr = nullptr;
|
||||
slot.alive = false;
|
||||
free_indices.push_back(index);
|
||||
free_indices.push_back(id);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_valid(int index) const {
|
||||
return index >= 0
|
||||
&& index < (int)slots.size()
|
||||
&& slots[index].alive;
|
||||
bool is_valid(uint64_t index) const {
|
||||
uint32_t id = (uint32_t)(index & 0xFFFFFFFFULL);
|
||||
uint32_t gen = (uint32_t)(index >> 32);
|
||||
return id >= 0
|
||||
&& id < slots.size()
|
||||
&& slots[id].alive
|
||||
&& slots[id].generation == gen;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -215,9 +224,10 @@ private:
|
||||
T *ptr = nullptr;
|
||||
int refcount = 0;
|
||||
bool alive = false;
|
||||
uint32_t generation = 0;
|
||||
};
|
||||
std::vector<Slot> slots;
|
||||
std::vector<int> free_indices;
|
||||
std::vector<uint32_t> free_indices;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user