From ba079eaf731e4cab953135955389f6b70bac69ce Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 2 Dec 2024 19:30:02 +0700 Subject: [PATCH] registry.include/exclude doesn't modify query's include/exclude lists --- ROADMAP.md | 4 ++-- evolved/registry.lua | 46 ++++++++++++++++++++++++++++++-------------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 6b574d2..085067d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -13,7 +13,7 @@ - [x] support queries without fragments - [ ] add assertions for input arguments - [x] registry.assign should not change chunks' tree -- [ ] add deferred changes api +- [x] add deferred changes api - [ ] add multi apply/batch_apply - [ ] add batch vector operations -- [ ] add inplace vector operations \ No newline at end of file +- [ ] add inplace vector operations diff --git a/evolved/registry.lua b/evolved/registry.lua index 39969b8..387d369 100644 --- a/evolved/registry.lua +++ b/evolved/registry.lua @@ -1009,23 +1009,32 @@ end ---@param ... evolved.entity fragments ---@return evolved.query function registry.include(query, ...) - local include_list = query.__include_list - local include_set = query.__include_set + -- we create a new include list/set instead of modifying the old one + -- to prevent problems modifying the query while iterating over it + local new_include_list, new_include_set = {}, {} for i = 1, select('#', ...) do local f = select(i, ...) - if not include_set[f] then - include_set[f] = true - include_list[#include_list + 1] = f + if not new_include_set[f] then + new_include_set[f] = true + new_include_list[#new_include_list + 1] = f end end - query.__changes = query.__changes + 1 + for _, f in ipairs(query.__include_list) do + if not new_include_set[f] then + new_include_set[f] = true + new_include_list[#new_include_list + 1] = f + end + end - table.sort(include_list, function(a, b) + table.sort(new_include_list, function(a, b) return a.__guid < b.__guid end) + query.__include_list = new_include_list + query.__include_set = new_include_set + return query end @@ -1033,23 +1042,32 @@ end ---@param ... evolved.entity fragments ---@return evolved.query function registry.exclude(query, ...) - local exclude_list = query.__exclude_list - local exclude_set = query.__exclude_set + -- we create a new exclude list/set instead of modifying the old one + -- to prevent problems modifying the query while iterating over it + local new_exclude_list, new_exclude_set = {}, {} for i = 1, select('#', ...) do local f = select(i, ...) - if not exclude_set[f] then - exclude_set[f] = true - exclude_list[#exclude_list + 1] = f + if not new_exclude_set[f] then + new_exclude_set[f] = true + new_exclude_list[#new_exclude_list + 1] = f end end - query.__changes = query.__changes + 1 + for _, f in ipairs(query.__exclude_list) do + if not new_exclude_set[f] then + new_exclude_set[f] = true + new_exclude_list[#new_exclude_list + 1] = f + end + end - table.sort(exclude_list, function(a, b) + table.sort(new_exclude_list, function(a, b) return a.__guid < b.__guid end) + query.__exclude_list = new_exclude_list + query.__exclude_set = new_exclude_set + return query end