mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2026-03-22 04:44:06 +07:00
non-shrinking version of garbage collection
This commit is contained in:
24
README.md
24
README.md
@@ -55,6 +55,7 @@
|
|||||||
- [Fragment Requirements](#fragment-requirements)
|
- [Fragment Requirements](#fragment-requirements)
|
||||||
- [Destruction Policies](#destruction-policies)
|
- [Destruction Policies](#destruction-policies)
|
||||||
- [Custom Component Storages](#custom-component-storages)
|
- [Custom Component Storages](#custom-component-storages)
|
||||||
|
- [Garbage Collection](#garbage-collection)
|
||||||
- [Cheat Sheet](#cheat-sheet)
|
- [Cheat Sheet](#cheat-sheet)
|
||||||
- [Aliases](#aliases)
|
- [Aliases](#aliases)
|
||||||
- [Predefs](#predefs)
|
- [Predefs](#predefs)
|
||||||
@@ -1346,6 +1347,24 @@ evolved.builder()
|
|||||||
evolved.process_with(MOVEMENT_SYSTEM, 0.016)
|
evolved.process_with(MOVEMENT_SYSTEM, 0.016)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Garbage Collection
|
||||||
|
|
||||||
|
While using the library, some internal data structures can become obsolete and should be cleaned up to free memory. For example, empty chunks that no longer contain entities can be removed. Component storages can also have unused capacity that can be shrunk to save memory. The library provides a function to control this garbage collection process.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
---@param no_shrink? boolean
|
||||||
|
function evolved.collect_garbage(no_shrink) end
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, [`evolved.collect_garbage`](#evolvedcollect_garbage) cleans up obsolete data structures and shrinks component storages to fit their current size. If you pass `true`, it only cleans up obsolete data structures and skips shrinking. This avoids the overhead of resizing storages, which can be expensive.
|
||||||
|
|
||||||
|
Call this function periodically to keep memory usage under control. It is best to call it between levels or during loading screens when performance is not critical. Also, call Lua's built-in garbage collector afterward to ensure all unused memory is freed.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
evolved.collect_garbage()
|
||||||
|
collectgarbage('collect')
|
||||||
|
```
|
||||||
|
|
||||||
## Cheat Sheet
|
## Cheat Sheet
|
||||||
|
|
||||||
### Aliases
|
### Aliases
|
||||||
@@ -1481,7 +1500,7 @@ process :: system... -> ()
|
|||||||
process_with :: system, ... -> ()
|
process_with :: system, ... -> ()
|
||||||
|
|
||||||
debug_mode :: boolean -> ()
|
debug_mode :: boolean -> ()
|
||||||
collect_garbage :: ()
|
collect_garbage :: boolean? -> ()
|
||||||
```
|
```
|
||||||
|
|
||||||
### Classes
|
### Classes
|
||||||
@@ -2007,7 +2026,8 @@ function evolved.debug_mode(yesno) end
|
|||||||
### `evolved.collect_garbage`
|
### `evolved.collect_garbage`
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
function evolved.collect_garbage() end
|
---@param no_shrink? boolean
|
||||||
|
function evolved.collect_garbage(no_shrink) end
|
||||||
```
|
```
|
||||||
|
|
||||||
## Classes
|
## Classes
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
## Thoughts
|
## Thoughts
|
||||||
|
|
||||||
- We should have a way to not copy components on deferred spawn/clone
|
- We should have a way to not copy components on deferred spawn/clone
|
||||||
- Having a light version of the gargabe collector can be useful for some use-cases
|
|
||||||
- Basic default component value as true looks awful, should we use something else?
|
- Basic default component value as true looks awful, should we use something else?
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|||||||
@@ -118,11 +118,11 @@ end
|
|||||||
---
|
---
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.destroy(__table_unpack(all_entity_list))
|
evo.destroy(__table_unpack(all_entity_list))
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -124,11 +124,11 @@ end
|
|||||||
---
|
---
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.destroy(__table_unpack(all_entity_list))
|
evo.destroy(__table_unpack(all_entity_list))
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ end
|
|||||||
---
|
---
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.destroy(__table_unpack(all_query_list))
|
evo.destroy(__table_unpack(all_query_list))
|
||||||
@@ -304,5 +304,5 @@ evo.destroy(__table_unpack(all_entity_list))
|
|||||||
evo.destroy(__table_unpack(all_fragment_list))
|
evo.destroy(__table_unpack(all_fragment_list))
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -78,11 +78,11 @@ end
|
|||||||
---
|
---
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.destroy(__table_unpack(all_entity_list))
|
evo.destroy(__table_unpack(all_entity_list))
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -115,17 +115,17 @@ end
|
|||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.destroy(__table_unpack(all_entity_list))
|
evo.destroy(__table_unpack(all_entity_list))
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
evo.destroy(__table_unpack(all_fragment_list))
|
evo.destroy(__table_unpack(all_fragment_list))
|
||||||
else
|
else
|
||||||
evo.destroy(__table_unpack(all_fragment_list))
|
evo.destroy(__table_unpack(all_fragment_list))
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
evo.destroy(__table_unpack(all_entity_list))
|
evo.destroy(__table_unpack(all_entity_list))
|
||||||
end
|
end
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -64,11 +64,11 @@ end
|
|||||||
---
|
---
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.destroy(__table_unpack(all_entity_list))
|
evo.destroy(__table_unpack(all_entity_list))
|
||||||
|
|
||||||
if math.random(1, 2) == 1 then
|
if math.random(1, 2) == 1 then
|
||||||
evo.collect_garbage()
|
evo.collect_garbage(math.random(1, 2) == 1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -212,7 +212,7 @@
|
|||||||
process_with: function(system: System, ...: any)
|
process_with: function(system: System, ...: any)
|
||||||
|
|
||||||
debug_mode: function(yesno: boolean)
|
debug_mode: function(yesno: boolean)
|
||||||
collect_garbage: function()
|
collect_garbage: function(no_shrink?: boolean)
|
||||||
|
|
||||||
chunk: function(fragment: Fragment, ...: Fragment): Chunk, { Entity }, integer
|
chunk: function(fragment: Fragment, ...: Fragment): Chunk, { Entity }, integer
|
||||||
builder: function(): Builder
|
builder: function(): Builder
|
||||||
|
|||||||
49
evolved.lua
49
evolved.lua
@@ -6145,7 +6145,8 @@ function __evolved_debug_mode(yesno)
|
|||||||
__debug_mode = yesno
|
__debug_mode = yesno
|
||||||
end
|
end
|
||||||
|
|
||||||
function __evolved_collect_garbage()
|
---@param no_shrink boolean?
|
||||||
|
function __evolved_collect_garbage(no_shrink)
|
||||||
if __defer_depth > 0 then
|
if __defer_depth > 0 then
|
||||||
__defer_call_hook(__evolved_collect_garbage)
|
__defer_call_hook(__evolved_collect_garbage)
|
||||||
return
|
return
|
||||||
@@ -6209,16 +6210,16 @@ function __evolved_collect_garbage()
|
|||||||
local postorder_chunk_entity_count = postorder_chunk.__entity_count
|
local postorder_chunk_entity_count = postorder_chunk.__entity_count
|
||||||
local postorder_chunk_entity_capacity = postorder_chunk.__entity_capacity
|
local postorder_chunk_entity_capacity = postorder_chunk.__entity_capacity
|
||||||
|
|
||||||
local should_be_purged =
|
local can_be_purged =
|
||||||
postorder_chunk_child_count == 0 and
|
postorder_chunk_child_count == 0 and
|
||||||
postorder_chunk_entity_count == 0
|
postorder_chunk_entity_count == 0
|
||||||
|
|
||||||
local should_be_shrunk =
|
local can_be_shrunk =
|
||||||
postorder_chunk_entity_count < postorder_chunk_entity_capacity
|
postorder_chunk_entity_count < postorder_chunk_entity_capacity
|
||||||
|
|
||||||
if should_be_purged then
|
if can_be_purged then
|
||||||
__purge_chunk(postorder_chunk)
|
__purge_chunk(postorder_chunk)
|
||||||
elseif should_be_shrunk then
|
elseif can_be_shrunk and not no_shrink then
|
||||||
__shrink_chunk(postorder_chunk, 0)
|
__shrink_chunk(postorder_chunk, 0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -6234,29 +6235,31 @@ function __evolved_collect_garbage()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for table_pool_tag = 1, __table_pool_tag.__count do
|
if not no_shrink then
|
||||||
local table_pool_reserve = __table_pool_reserve[table_pool_tag]
|
for table_pool_tag = 1, __table_pool_tag.__count do
|
||||||
|
local table_pool_reserve = __table_pool_reserve[table_pool_tag]
|
||||||
|
|
||||||
---@type evolved.table_pool
|
---@type evolved.table_pool
|
||||||
local new_table_pool = __lua_table_new(table_pool_reserve)
|
local new_table_pool = __lua_table_new(table_pool_reserve)
|
||||||
|
|
||||||
for table_pool_index = 1, table_pool_reserve do
|
for table_pool_index = 1, table_pool_reserve do
|
||||||
new_table_pool[table_pool_index] = {}
|
new_table_pool[table_pool_index] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
new_table_pool.__size = table_pool_reserve
|
||||||
|
|
||||||
|
__tagged_table_pools[table_pool_tag] = new_table_pool
|
||||||
end
|
end
|
||||||
|
|
||||||
new_table_pool.__size = table_pool_reserve
|
do
|
||||||
|
__entity_chunks = __table_dup(__entity_chunks)
|
||||||
|
__entity_places = __table_dup(__entity_places)
|
||||||
|
end
|
||||||
|
|
||||||
__tagged_table_pools[table_pool_tag] = new_table_pool
|
do
|
||||||
end
|
__defer_points = __list_dup(__defer_points, __defer_depth)
|
||||||
|
__defer_bytecode = __list_dup(__defer_bytecode, __defer_length)
|
||||||
do
|
end
|
||||||
__entity_chunks = __table_dup(__entity_chunks)
|
|
||||||
__entity_places = __table_dup(__entity_places)
|
|
||||||
end
|
|
||||||
|
|
||||||
do
|
|
||||||
__defer_points = __list_dup(__defer_points, __defer_depth)
|
|
||||||
__defer_bytecode = __list_dup(__defer_bytecode, __defer_length)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
__evolved_commit()
|
__evolved_commit()
|
||||||
|
|||||||
Reference in New Issue
Block a user