@@ -124,6 +124,8 @@ local __query_sorted_excludes = {} ---@type table<evolved.query, evolved.assoc_l
124124--- @field package __has_assign_hooks boolean
125125--- @field package __has_insert_hooks boolean
126126--- @field package __has_remove_hooks boolean
127+ --- @field package __has_hidden_major boolean
128+ --- @field package __has_hidden_minors boolean
127129--- @field package __has_hidden_fragments boolean
128130local __chunk_mt = {}
129131__chunk_mt .__index = __chunk_mt
@@ -619,22 +621,18 @@ local function __execute_iterator(execute_state)
619621 local chunk_child_list = chunk .__child_list
620622 local chunk_child_count = chunk .__child_count
621623
622- if exclude_set then
623- for i = 1 , chunk_child_count do
624- local chunk_child = chunk_child_list [i ]
625- local chunk_child_fragment = chunk_child .__fragment
624+ for i = 1 , chunk_child_count do
625+ local chunk_child = chunk_child_list [i ]
626+ local chunk_child_fragment = chunk_child .__fragment
626627
627- if not exclude_set [chunk_child_fragment ] then
628- chunk_stack_size = chunk_stack_size + 1
629- chunk_stack [chunk_stack_size ] = chunk_child
630- end
631- end
632- else
633- __lua_table_move (
634- chunk_child_list , 1 , chunk_child_count ,
635- chunk_stack_size + 1 , chunk_stack )
628+ local is_chunk_child_matched =
629+ (not chunk_child .__has_hidden_major ) and
630+ (not exclude_set or not exclude_set [chunk_child_fragment ])
636631
637- chunk_stack_size = chunk_stack_size + chunk_child_count
632+ if is_chunk_child_matched then
633+ chunk_stack_size = chunk_stack_size + 1
634+ chunk_stack [chunk_stack_size ] = chunk_child
635+ end
638636 end
639637
640638 local chunk_entity_list = chunk .__entity_list
@@ -693,6 +691,12 @@ local __DESTROY_POLICY_REMOVE_FRAGMENT = __acquire_id()
693691---
694692
695693local __safe_tbls = {
694+ --- @type evolved.entity[]
695+ __EMPTY_ENTITY_LIST = __lua_setmetatable ({}, {
696+ __tostring = function () return ' empty entity list' end ,
697+ __newindex = function () __error_fmt ' attempt to modify empty entity list' end
698+ }),
699+
696700 --- @type table<evolved.fragment , integer>
697701 __EMPTY_FRAGMENT_SET = __lua_setmetatable ({}, {
698702 __tostring = function () return ' empty fragment set' end ,
@@ -1002,20 +1006,21 @@ local function __new_chunk(chunk_parent, chunk_fragment)
10021006 --- @type evolved.fragment[]
10031007 local chunk_component_fragments = {}
10041008
1005- local has_setup_hooks = (chunk_parent and chunk_parent .__has_setup_hooks )
1009+ local has_setup_hooks = (chunk_parent ~= nil and chunk_parent .__has_setup_hooks )
10061010 or __evolved_has_any (chunk_fragment , __DEFAULT , __DUPLICATE )
10071011
1008- local has_assign_hooks = (chunk_parent and chunk_parent .__has_assign_hooks )
1012+ local has_assign_hooks = (chunk_parent ~= nil and chunk_parent .__has_assign_hooks )
10091013 or __evolved_has_any (chunk_fragment , __ON_SET , __ON_ASSIGN )
10101014
1011- local has_insert_hooks = (chunk_parent and chunk_parent .__has_insert_hooks )
1015+ local has_insert_hooks = (chunk_parent ~= nil and chunk_parent .__has_insert_hooks )
10121016 or __evolved_has_any (chunk_fragment , __ON_SET , __ON_INSERT )
10131017
1014- local has_remove_hooks = (chunk_parent and chunk_parent .__has_remove_hooks )
1018+ local has_remove_hooks = (chunk_parent ~= nil and chunk_parent .__has_remove_hooks )
10151019 or __evolved_has (chunk_fragment , __ON_REMOVE )
10161020
1017- local has_hidden_fragments = (chunk_parent and chunk_parent .__has_hidden_fragments )
1018- or __evolved_has (chunk_fragment , __HIDDEN )
1021+ local has_hidden_major = __evolved_has (chunk_fragment , __HIDDEN )
1022+ local has_hidden_minors = chunk_parent ~= nil and chunk_parent .__has_hidden_fragments
1023+ local has_hidden_fragments = has_hidden_major or has_hidden_minors
10191024
10201025 --- @type evolved.chunk
10211026 local chunk = __lua_setmetatable ({
@@ -1040,6 +1045,8 @@ local function __new_chunk(chunk_parent, chunk_fragment)
10401045 __has_assign_hooks = has_assign_hooks ,
10411046 __has_insert_hooks = has_insert_hooks ,
10421047 __has_remove_hooks = has_remove_hooks ,
1048+ __has_hidden_major = has_hidden_major ,
1049+ __has_hidden_minors = has_hidden_minors ,
10431050 __has_hidden_fragments = has_hidden_fragments ,
10441051 }, __chunk_mt )
10451052
@@ -1237,18 +1244,26 @@ local function __chunk_without_hidden_fragments(chunk)
12371244 return chunk
12381245 end
12391246
1240- local chunk_fragment_list = chunk .__fragment_list
1241- local chunk_fragment_count = chunk .__fragment_count
1247+ while chunk and chunk .__has_hidden_major do
1248+ chunk = chunk .__parent
1249+ end
1250+
1251+ local new_chunk = nil
1252+
1253+ if chunk then
1254+ local chunk_fragment_list = chunk .__fragment_list
1255+ local chunk_fragment_count = chunk .__fragment_count
12421256
1243- for i = chunk_fragment_count , 1 , - 1 do
1244- local fragment = chunk_fragment_list [i ]
1257+ for i = 1 , chunk_fragment_count do
1258+ local fragment = chunk_fragment_list [i ]
12451259
1246- if __evolved_has (fragment , __HIDDEN ) then
1247- chunk = __chunk_without_fragment (chunk , fragment )
1260+ if not __evolved_has (fragment , __HIDDEN ) then
1261+ new_chunk = __chunk_with_fragment (new_chunk , fragment )
1262+ end
12481263 end
12491264 end
12501265
1251- return chunk
1266+ return new_chunk
12521267end
12531268
12541269---
@@ -4329,6 +4344,7 @@ function __evolved_execute(query)
43294344 local chunk_stack_size = 0
43304345
43314346 local query_includes = __query_sorted_includes [query ]
4347+ local query_include_set = query_includes and query_includes .__item_set --[[ @as table<evolved.fragment, integer>]]
43324348 local query_include_list = query_includes and query_includes .__item_list --[=[ @as evolved.fragment[]]=]
43334349 local query_include_count = query_includes and query_includes .__item_count or 0 --[[ @as integer]]
43344350
@@ -4353,22 +4369,45 @@ function __evolved_execute(query)
43534369 (query_exclude_count == 0 or not __chunk_has_any_fragment_list (
43544370 major_chunk , query_exclude_list , query_exclude_count ))
43554371
4372+ if is_major_chunk_matched and major_chunk .__has_hidden_minors then
4373+ local major_chunk_fragment_list = major_chunk .__fragment_list
4374+ local major_chunk_fragment_count = major_chunk .__fragment_count
4375+
4376+ for major_chunk_fragment_index = 1 , major_chunk_fragment_count - 1 do
4377+ local major_chunk_fragment = major_chunk_fragment_list [major_chunk_fragment_index ]
4378+
4379+ if not query_include_set [major_chunk_fragment ] and __evolved_has (major_chunk_fragment , __HIDDEN ) then
4380+ is_major_chunk_matched = false
4381+ break
4382+ end
4383+ end
4384+ end
4385+
43564386 if is_major_chunk_matched then
43574387 chunk_stack_size = chunk_stack_size + 1
43584388 chunk_stack [chunk_stack_size ] = major_chunk
43594389 end
43604390 end
43614391 elseif query_exclude_count > 0 then
43624392 for root_fragment , root_chunk in __lua_next , __root_chunks do
4363- if not query_exclude_set [root_fragment ] then
4393+ local is_root_chunk_matched =
4394+ not root_chunk .__has_hidden_major and
4395+ not query_exclude_set [root_fragment ]
4396+
4397+ if is_root_chunk_matched then
43644398 chunk_stack_size = chunk_stack_size + 1
43654399 chunk_stack [chunk_stack_size ] = root_chunk
43664400 end
43674401 end
43684402 else
43694403 for _ , root_chunk in __lua_next , __root_chunks do
4370- chunk_stack_size = chunk_stack_size + 1
4371- chunk_stack [chunk_stack_size ] = root_chunk
4404+ local is_root_chunk_matched =
4405+ not root_chunk .__has_hidden_major
4406+
4407+ if is_root_chunk_matched then
4408+ chunk_stack_size = chunk_stack_size + 1
4409+ chunk_stack [chunk_stack_size ] = root_chunk
4410+ end
43724411 end
43734412 end
43744413
@@ -5048,25 +5087,29 @@ end
50485087local function __update_chunk_caches_trace (chunk )
50495088 local chunk_parent , chunk_fragment = chunk .__parent , chunk .__fragment
50505089
5051- local has_setup_hooks = (chunk_parent and chunk_parent .__has_setup_hooks )
5090+ local has_setup_hooks = (chunk_parent ~= nil and chunk_parent .__has_setup_hooks )
50525091 or __evolved_has_any (chunk_fragment , __DEFAULT , __DUPLICATE )
50535092
5054- local has_assign_hooks = (chunk_parent and chunk_parent .__has_assign_hooks )
5093+ local has_assign_hooks = (chunk_parent ~= nil and chunk_parent .__has_assign_hooks )
50555094 or __evolved_has_any (chunk_fragment , __ON_SET , __ON_ASSIGN )
50565095
5057- local has_insert_hooks = (chunk_parent and chunk_parent .__has_insert_hooks )
5096+ local has_insert_hooks = (chunk_parent ~= nil and chunk_parent .__has_insert_hooks )
50585097 or __evolved_has_any (chunk_fragment , __ON_SET , __ON_INSERT )
50595098
5060- local has_remove_hooks = (chunk_parent and chunk_parent .__has_remove_hooks )
5099+ local has_remove_hooks = (chunk_parent ~= nil and chunk_parent .__has_remove_hooks )
50615100 or __evolved_has (chunk_fragment , __ON_REMOVE )
50625101
5063- local has_hidden_fragments = (chunk_parent and chunk_parent .__has_hidden_fragments )
5064- or __evolved_has (chunk_fragment , __HIDDEN )
5102+ local has_hidden_major = __evolved_has (chunk_fragment , __HIDDEN )
5103+ local has_hidden_minors = chunk_parent ~= nil and chunk_parent .__has_hidden_fragments
5104+ local has_hidden_fragments = has_hidden_major or has_hidden_minors
50655105
50665106 chunk .__has_setup_hooks = has_setup_hooks
50675107 chunk .__has_assign_hooks = has_assign_hooks
50685108 chunk .__has_insert_hooks = has_insert_hooks
50695109 chunk .__has_remove_hooks = has_remove_hooks
5110+
5111+ chunk .__has_hidden_major = has_hidden_major
5112+ chunk .__has_hidden_minors = has_hidden_minors
50705113 chunk .__has_hidden_fragments = has_hidden_fragments
50715114
50725115 return true
0 commit comments