mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2026-03-22 04:44:06 +07:00
Compare commits
4 Commits
e364aaab37
...
feature/ca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6cc943850 | ||
|
|
a9fecee874 | ||
|
|
39c0b988b5 | ||
|
|
766f7b92be |
115
README.md
115
README.md
@@ -45,7 +45,8 @@
|
||||
- [Batch Operations](#batch-operations)
|
||||
- [Systems](#systems)
|
||||
- [Processing Payloads](#processing-payloads)
|
||||
- [Predefined Traits](#predefined-traits)
|
||||
- [Predefined Fragments](#predefined-fragments)
|
||||
- [Entity Names](#entity-names)
|
||||
- [Fragment Tags](#fragment-tags)
|
||||
- [Fragment Hooks](#fragment-hooks)
|
||||
- [Unique Fragments](#unique-fragments)
|
||||
@@ -53,7 +54,6 @@
|
||||
- [Internal Fragments](#internal-fragments)
|
||||
- [Shared Components](#shared-components)
|
||||
- [Fragment Requirements](#fragment-requirements)
|
||||
- [Id Names](#id-names)
|
||||
- [Destruction Policies](#destruction-policies)
|
||||
- [Custom Component Storages](#custom-component-storages)
|
||||
- [Garbage Collection](#garbage-collection)
|
||||
@@ -66,6 +66,7 @@
|
||||
- [Builder](#builder)
|
||||
- [Changelog](#changelog)
|
||||
- [vX.Y.Z](#vxyz)
|
||||
- [v1.10.0](#v1100)
|
||||
- [v1.9.0](#v190)
|
||||
- [v1.8.0](#v180)
|
||||
- [v1.7.0](#v170)
|
||||
@@ -491,6 +492,7 @@ When you need to spawn multiple entities with identical fragments, use `multi_sp
|
||||
---@param component_mapper? evolved.component_mapper
|
||||
---@return evolved.entity[] entity_list
|
||||
---@return integer entity_count
|
||||
---@nodiscard
|
||||
function evolved.multi_spawn(entity_count, component_table, component_mapper) end
|
||||
|
||||
---@param entity_count integer
|
||||
@@ -499,6 +501,7 @@ function evolved.multi_spawn(entity_count, component_table, component_mapper) en
|
||||
---@param component_mapper? evolved.component_mapper
|
||||
---@return evolved.entity[] entity_list
|
||||
---@return integer entity_count
|
||||
---@nodiscard
|
||||
function evolved.multi_clone(entity_count, prefab, component_table, component_mapper) end
|
||||
```
|
||||
|
||||
@@ -529,6 +532,36 @@ end)
|
||||
|
||||
Of course, you can use `evolved.multi_clone` in the same way. Builders can also be used for multi-entity spawning and cloning by calling the corresponding methods on the builder object.
|
||||
|
||||
Also, for all `multi_` functions, the library provides [`_nr`](#evolvedmulti_spawn_nr) and [`_to`](#evolvedmulti_spawn_to) suffix variants that allow you to perform these operations without returning the list of spawned entities or by copying the spawned entities to your own table, which can be more efficient because it avoids the overhead of allocating and returning a new table.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local position_x, position_y = evolved.id(2)
|
||||
|
||||
do
|
||||
-- we don't interest in the list of spawned entities,
|
||||
-- so we use the _nr variant of the multi_spawn function
|
||||
|
||||
evolved.multi_spawn_nr(100, {
|
||||
[position_x] = 0,
|
||||
[position_y] = 0,
|
||||
})
|
||||
end
|
||||
|
||||
do
|
||||
-- store spawned entities in our own table starting at index 1,
|
||||
-- so we use the _to variant of the multi_spawn function
|
||||
|
||||
local entity_list = {}
|
||||
|
||||
evolved.multi_spawn_to(entity_list, 1, 100, {
|
||||
[position_x] = 0,
|
||||
[position_y] = 0,
|
||||
})
|
||||
end
|
||||
```
|
||||
|
||||
### Access Operations
|
||||
|
||||
The library provides all the necessary functions to access entities and their components. I'm not going to cover all the accessor functions here, because they are pretty straightforward and self-explanatory. You can check the [API Reference](#api-reference) for all of them. Here are some of the most important ones:
|
||||
@@ -983,7 +1016,42 @@ evolved.process_with(physics_system, delta_time)
|
||||
|
||||
`delta_time` in this example is passed as a processing payload to the system's execution callback. Payloads can be of any type and can be multiple values. Also, payloads are passed to prologue and epilogue callbacks if they are defined. Every subsystem in a group will receive the same payload when the group is processed with [`evolved.process_with`](#evolvedprocess_with).
|
||||
|
||||
### Predefined Traits
|
||||
### Predefined Fragments
|
||||
|
||||
#### Entity Names
|
||||
|
||||
The library provides a way to assign names to any id using the [`evolved.NAME`](#evolvedname) fragment. This is useful for debugging and development purposes, as it allows you to identify entities or fragments by their names instead of their identifiers. The name of an entity can be retrieved using the [`evolved.name`](#evolvedname-1) function.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local player = evolved.builder()
|
||||
:name('Player')
|
||||
:build()
|
||||
|
||||
assert(evolved.name(player) == 'Player')
|
||||
```
|
||||
|
||||
Names are not unique, so multiple entities can have the same name. Also, the name of an entity can be changed at any time by setting a new name using the [`evolved.NAME`](#evolvedname) fragment as a usual component.
|
||||
|
||||
You can find entities by their names using the [`evolved.lookup`](#evolvedlookup) and [`evolved.multi_lookup`](#evolvedmulti_lookup) functions. The [`evolved.lookup`](#evolvedlookup) function returns the first entity with the specified name, while the [`evolved.multi_lookup`](#evolvedmulti_lookup) function returns a list of all entities with the specified name.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local player1 = evolved.builder()
|
||||
:name('Player')
|
||||
:build()
|
||||
|
||||
local player2 = evolved.builder()
|
||||
:name('Player')
|
||||
:build()
|
||||
|
||||
assert(evolved.lookup('Player') == player1)
|
||||
|
||||
local player_list, player_count = evolved.multi_lookup('Player')
|
||||
assert(player_count == 2 and player_list[1] == player1 and player_list[2] == player2)
|
||||
```
|
||||
|
||||
#### Fragment Tags
|
||||
|
||||
@@ -1163,41 +1231,6 @@ local enemy = evolved.builder()
|
||||
assert(evolved.has_all(enemy, position, velocity))
|
||||
```
|
||||
|
||||
#### Id Names
|
||||
|
||||
The library provides a way to assign names to any id using the [`evolved.NAME`](#evolvedname) fragment. This is useful for debugging and development purposes, as it allows you to identify entities or fragments by their names instead of their identifiers. The name of an entity can be retrieved using the [`evolved.name`](#evolvedname-1) function.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local player = evolved.builder()
|
||||
:name('Player')
|
||||
:build()
|
||||
|
||||
assert(evolved.name(player) == 'Player')
|
||||
```
|
||||
|
||||
Names are not unique, so multiple entities can have the same name. Also, the name of an entity can be changed at any time by setting a new name using the [`evolved.NAME`](#evolvedname) fragment as a usual component.
|
||||
|
||||
You can find entities by their names using the [`evolved.lookup`](#evolvedlookup) and [`evolved.multi_lookup`](#evolvedmulti_lookup) functions. The [`evolved.lookup`](#evolvedlookup) function returns the first entity with the specified name, while the [`evolved.multi_lookup`](#evolvedmulti_lookup) function returns a list of all entities with the specified name.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local player1 = evolved.builder()
|
||||
:name('Player')
|
||||
:build()
|
||||
|
||||
local player2 = evolved.builder()
|
||||
:name('Player')
|
||||
:build()
|
||||
|
||||
assert(evolved.lookup('Player') == player1)
|
||||
|
||||
local player_list, player_count = evolved.multi_lookup('Player')
|
||||
assert(player_count == 2 and player_list[1] == player1 and player_list[2] == player2)
|
||||
```
|
||||
|
||||
#### Destruction Policies
|
||||
|
||||
Typically, fragments remain alive for the entire lifetime of the program. However, in some cases, you might want to destroy fragments when they are no longer needed. For example, you can use some runtime entities as fragments for other entities. In this case, you might want to destroy such fragments even while they are still attached to other entities. Since entities cannot have destroyed fragments, a destruction policy must be applied to resolve this. By default, the library will remove the destroyed fragment from all entities that have it.
|
||||
@@ -1638,8 +1671,14 @@ builder_mt:destruction_policy :: id -> builder
|
||||
|
||||
### vX.Y.Z
|
||||
|
||||
- Slightly improved performance of modifying operations for fragments with [`ON_INSERT`](#evolvedon_insert) and [`ON_REMOVE`](#evolvedon_remove) hooks
|
||||
- Slightly improved performance of queries with [`EXPLICIT`](#evolvedexplicit) fragments
|
||||
|
||||
### v1.10.0
|
||||
|
||||
- Added the new [`evolved.lookup`](#evolvedlookup) and [`evolved.multi_lookup`](#evolvedmulti_lookup) functions that allow finding ids by their names
|
||||
- Added a non-shrinking version of the [`evolved.collect_garbage`](#evolvedcollect_garbage) function that only collects garbage without shrinking storages
|
||||
- Added [`_nr`](#evolvedmulti_spawn_nr) and [`_to`](#evolvedmulti_spawn_to) variants of the [`evolved.multi_spawn`](#evolvedmulti_spawn) and [`evolved.multi_clone`](#evolvedmulti_clone) functions that provide more efficient ways to spawn or clone entities in some cases
|
||||
|
||||
### v1.9.0
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'develop.testing.build_tests'
|
||||
require 'develop.testing.cached_hooks_tests'
|
||||
require 'develop.testing.cancel_tests'
|
||||
require 'develop.testing.clone_tests'
|
||||
require 'develop.testing.depth_tests'
|
||||
|
||||
203
develop/testing/cached_hooks_tests.lua
Normal file
203
develop/testing/cached_hooks_tests.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
evo.debug_mode(true)
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local insert_hook_calls = 0
|
||||
|
||||
if f1 < f2 then
|
||||
evo.set(f1, evo.ON_INSERT, function()
|
||||
insert_hook_calls = insert_hook_calls + 1
|
||||
end)
|
||||
else
|
||||
evo.set(f2, evo.ON_INSERT, function()
|
||||
insert_hook_calls = insert_hook_calls + 1
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
insert_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
assert(insert_hook_calls == 1)
|
||||
evo.destroy(e)
|
||||
end
|
||||
|
||||
evo.remove(f1, evo.ON_INSERT)
|
||||
evo.remove(f2, evo.ON_INSERT)
|
||||
|
||||
do
|
||||
insert_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
assert(insert_hook_calls == 0)
|
||||
evo.destroy(e)
|
||||
end
|
||||
|
||||
if f1 < f2 then
|
||||
evo.set(f1, evo.ON_INSERT, function()
|
||||
insert_hook_calls = insert_hook_calls + 2
|
||||
end)
|
||||
else
|
||||
evo.set(f2, evo.ON_INSERT, function()
|
||||
insert_hook_calls = insert_hook_calls + 2
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
insert_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
assert(insert_hook_calls == 2)
|
||||
evo.destroy(e)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local insert_hook_calls = 0
|
||||
|
||||
if f1 > f2 then
|
||||
evo.set(f1, evo.ON_INSERT, function()
|
||||
insert_hook_calls = insert_hook_calls + 1
|
||||
end)
|
||||
else
|
||||
evo.set(f2, evo.ON_INSERT, function()
|
||||
insert_hook_calls = insert_hook_calls + 1
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
insert_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
assert(insert_hook_calls == 1)
|
||||
evo.destroy(e)
|
||||
end
|
||||
|
||||
evo.remove(f1, evo.ON_INSERT)
|
||||
evo.remove(f2, evo.ON_INSERT)
|
||||
|
||||
do
|
||||
insert_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
assert(insert_hook_calls == 0)
|
||||
evo.destroy(e)
|
||||
end
|
||||
|
||||
if f1 > f2 then
|
||||
evo.set(f1, evo.ON_INSERT, function()
|
||||
insert_hook_calls = insert_hook_calls + 2
|
||||
end)
|
||||
else
|
||||
evo.set(f2, evo.ON_INSERT, function()
|
||||
insert_hook_calls = insert_hook_calls + 2
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
insert_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
assert(insert_hook_calls == 2)
|
||||
evo.destroy(e)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local remove_hook_calls = 0
|
||||
|
||||
if f1 < f2 then
|
||||
evo.set(f1, evo.ON_REMOVE, function()
|
||||
remove_hook_calls = remove_hook_calls + 1
|
||||
end)
|
||||
else
|
||||
evo.set(f2, evo.ON_REMOVE, function()
|
||||
remove_hook_calls = remove_hook_calls + 1
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
remove_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
evo.destroy(e)
|
||||
assert(remove_hook_calls == 1)
|
||||
end
|
||||
|
||||
evo.remove(f1, evo.ON_REMOVE)
|
||||
evo.remove(f2, evo.ON_REMOVE)
|
||||
|
||||
do
|
||||
remove_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
evo.destroy(e)
|
||||
assert(remove_hook_calls == 0)
|
||||
end
|
||||
|
||||
if f1 < f2 then
|
||||
evo.set(f1, evo.ON_REMOVE, function()
|
||||
remove_hook_calls = remove_hook_calls + 2
|
||||
end)
|
||||
else
|
||||
evo.set(f2, evo.ON_REMOVE, function()
|
||||
remove_hook_calls = remove_hook_calls + 2
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
remove_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
evo.destroy(e)
|
||||
assert(remove_hook_calls == 2)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local remove_hook_calls = 0
|
||||
|
||||
if f1 > f2 then
|
||||
evo.set(f1, evo.ON_REMOVE, function()
|
||||
remove_hook_calls = remove_hook_calls + 1
|
||||
end)
|
||||
else
|
||||
evo.set(f2, evo.ON_REMOVE, function()
|
||||
remove_hook_calls = remove_hook_calls + 1
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
remove_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
evo.destroy(e)
|
||||
assert(remove_hook_calls == 1)
|
||||
end
|
||||
|
||||
evo.remove(f1, evo.ON_REMOVE)
|
||||
evo.remove(f2, evo.ON_REMOVE)
|
||||
|
||||
do
|
||||
remove_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
evo.destroy(e)
|
||||
assert(remove_hook_calls == 0)
|
||||
end
|
||||
|
||||
if f1 > f2 then
|
||||
evo.set(f1, evo.ON_REMOVE, function()
|
||||
remove_hook_calls = remove_hook_calls + 2
|
||||
end)
|
||||
else
|
||||
evo.set(f2, evo.ON_REMOVE, function()
|
||||
remove_hook_calls = remove_hook_calls + 2
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
remove_hook_calls = 0
|
||||
local e = evo.spawn { [f1] = 42, [f2] = 'hello' }
|
||||
evo.destroy(e)
|
||||
assert(remove_hook_calls == 2)
|
||||
end
|
||||
end
|
||||
@@ -2928,8 +2928,8 @@ do
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local e = evo.spawn({ [f2] = 21, [f1] = true })
|
||||
assert(set_count == 2 and insert_count == 2)
|
||||
assert(last_set_entity == e and last_set_component == 21)
|
||||
assert(last_insert_entity == e and last_insert_component == 21)
|
||||
assert(last_set_entity == e and (last_set_component == 21 or last_set_component == true))
|
||||
assert(last_insert_entity == e and (last_insert_component == 21 or last_insert_component == true))
|
||||
end
|
||||
|
||||
do
|
||||
@@ -2948,8 +2948,8 @@ do
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local e = evo.spawn({ [f3] = 33, [f2] = 22 })
|
||||
assert(set_count == 2 and insert_count == 2)
|
||||
assert(last_set_entity == e and last_set_component == nil)
|
||||
assert(last_insert_entity == e and last_insert_component == nil)
|
||||
assert(last_set_entity == e and (last_set_component == nil or last_set_component == 22))
|
||||
assert(last_insert_entity == e and (last_insert_component == nil or last_insert_component == 22))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
261
evolved.lua
261
evolved.lua
@@ -1,7 +1,7 @@
|
||||
local evolved = {
|
||||
__HOMEPAGE = 'https://github.com/BlackMATov/evolved.lua',
|
||||
__DESCRIPTION = 'Evolved ECS (Entity-Component-System) for Lua',
|
||||
__VERSION = '1.9.0',
|
||||
__VERSION = '1.10.0',
|
||||
__LICENSE = [[
|
||||
MIT License
|
||||
|
||||
@@ -202,6 +202,12 @@ local __structural_changes = 0 ---@type integer
|
||||
---@field package __has_internal_minors boolean
|
||||
---@field package __has_internal_fragments boolean
|
||||
---@field package __has_required_fragments boolean
|
||||
---@field package __insert_fragment_list? evolved.fragment[]
|
||||
---@field package __insert_fragment_count integer
|
||||
---@field package __remove_fragment_list? evolved.fragment[]
|
||||
---@field package __remove_fragment_count integer
|
||||
---@field package __explicit_fragment_list? evolved.fragment[]
|
||||
---@field package __explicit_fragment_count integer
|
||||
local __chunk_mt = {}
|
||||
__chunk_mt.__index = __chunk_mt
|
||||
|
||||
@@ -819,12 +825,13 @@ end
|
||||
---@param list V[]
|
||||
---@param size? integer
|
||||
---@return V[]
|
||||
---@return integer dup_list_size
|
||||
---@nodiscard
|
||||
function __list_fns.dup(list, size)
|
||||
local list_size = size or #list
|
||||
|
||||
if list_size == 0 then
|
||||
return {}
|
||||
return {}, 0
|
||||
end
|
||||
|
||||
local dup_list = __list_fns.new(list_size)
|
||||
@@ -833,7 +840,7 @@ function __list_fns.dup(list, size)
|
||||
list, 1, list_size,
|
||||
1, dup_list)
|
||||
|
||||
return dup_list
|
||||
return dup_list, list_size
|
||||
end
|
||||
|
||||
---@generic V
|
||||
@@ -1408,6 +1415,12 @@ function __new_chunk(chunk_parent, chunk_fragment)
|
||||
__has_internal_minors = false,
|
||||
__has_internal_fragments = false,
|
||||
__has_required_fragments = false,
|
||||
__insert_fragment_list = nil,
|
||||
__insert_fragment_count = 0,
|
||||
__remove_fragment_list = nil,
|
||||
__remove_fragment_count = 0,
|
||||
__explicit_fragment_list = nil,
|
||||
__explicit_fragment_count = 0,
|
||||
}, __chunk_mt)
|
||||
|
||||
if not chunk_parent then
|
||||
@@ -1590,17 +1603,22 @@ function __update_chunk_caches(chunk)
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
|
||||
local has_setup_hooks = chunk_parent ~= nil and chunk_parent.__has_setup_hooks
|
||||
or __evolved_has_any(chunk_fragment, __DEFAULT, __DUPLICATE)
|
||||
local has_setup_major = __evolved_has_any(chunk_fragment, __DEFAULT, __DUPLICATE)
|
||||
local has_setup_minors = chunk_parent ~= nil and chunk_parent.__has_setup_hooks
|
||||
|
||||
local has_assign_hooks = chunk_parent ~= nil and chunk_parent.__has_assign_hooks
|
||||
or __evolved_has_any(chunk_fragment, __ON_SET, __ON_ASSIGN)
|
||||
local has_assign_major = __evolved_has_any(chunk_fragment, __ON_SET, __ON_ASSIGN)
|
||||
local has_assign_minors = chunk_parent ~= nil and chunk_parent.__has_assign_hooks
|
||||
|
||||
local has_insert_hooks = chunk_parent ~= nil and chunk_parent.__has_insert_hooks
|
||||
or __evolved_has_any(chunk_fragment, __ON_SET, __ON_INSERT)
|
||||
local has_insert_major = __evolved_has_any(chunk_fragment, __ON_SET, __ON_INSERT)
|
||||
local has_insert_minors = chunk_parent ~= nil and chunk_parent.__has_insert_hooks
|
||||
|
||||
local has_remove_hooks = chunk_parent ~= nil and chunk_parent.__has_remove_hooks
|
||||
or __evolved_has(chunk_fragment, __ON_REMOVE)
|
||||
local has_remove_major = __evolved_has(chunk_fragment, __ON_REMOVE)
|
||||
local has_remove_minors = chunk_parent ~= nil and chunk_parent.__has_remove_hooks
|
||||
|
||||
local has_setup_hooks = has_setup_major or has_setup_minors
|
||||
local has_assign_hooks = has_assign_major or has_assign_minors
|
||||
local has_insert_hooks = has_insert_major or has_insert_minors
|
||||
local has_remove_hooks = has_remove_major or has_remove_minors
|
||||
|
||||
local has_unique_major = __evolved_has(chunk_fragment, __UNIQUE)
|
||||
local has_unique_minors = chunk_parent ~= nil and chunk_parent.__has_unique_fragments
|
||||
@@ -1667,6 +1685,75 @@ function __update_chunk_caches(chunk)
|
||||
else
|
||||
chunk.__without_unique_fragments = chunk
|
||||
end
|
||||
|
||||
if has_insert_hooks then
|
||||
local parent_insert_fragment_list = chunk_parent and chunk_parent.__insert_fragment_list
|
||||
local parent_insert_fragment_count = chunk_parent and chunk_parent.__insert_fragment_count or 0
|
||||
|
||||
if has_insert_major then
|
||||
local insert_fragment_list, insert_fragment_count = parent_insert_fragment_list
|
||||
and __list_fns.dup(parent_insert_fragment_list, parent_insert_fragment_count)
|
||||
or __list_fns.new(1), 0
|
||||
|
||||
insert_fragment_count = parent_insert_fragment_count + 1
|
||||
insert_fragment_list[insert_fragment_count] = chunk_fragment
|
||||
|
||||
chunk.__insert_fragment_list = insert_fragment_list
|
||||
chunk.__insert_fragment_count = insert_fragment_count
|
||||
else
|
||||
chunk.__insert_fragment_list = parent_insert_fragment_list
|
||||
chunk.__insert_fragment_count = parent_insert_fragment_count
|
||||
end
|
||||
else
|
||||
chunk.__insert_fragment_list = nil
|
||||
chunk.__insert_fragment_count = 0
|
||||
end
|
||||
|
||||
if has_remove_hooks then
|
||||
local parent_remove_fragment_list = chunk_parent and chunk_parent.__remove_fragment_list
|
||||
local parent_remove_fragment_count = chunk_parent and chunk_parent.__remove_fragment_count or 0
|
||||
|
||||
if has_remove_major then
|
||||
local remove_fragment_list, remove_fragment_count = parent_remove_fragment_list
|
||||
and __list_fns.dup(parent_remove_fragment_list, parent_remove_fragment_count)
|
||||
or __list_fns.new(1), 0
|
||||
|
||||
remove_fragment_count = parent_remove_fragment_count + 1
|
||||
remove_fragment_list[remove_fragment_count] = chunk_fragment
|
||||
|
||||
chunk.__remove_fragment_list = remove_fragment_list
|
||||
chunk.__remove_fragment_count = remove_fragment_count
|
||||
else
|
||||
chunk.__remove_fragment_list = parent_remove_fragment_list
|
||||
chunk.__remove_fragment_count = parent_remove_fragment_count
|
||||
end
|
||||
else
|
||||
chunk.__remove_fragment_list = nil
|
||||
chunk.__remove_fragment_count = 0
|
||||
end
|
||||
|
||||
if has_explicit_fragments then
|
||||
local parent_explicit_fragment_list = chunk_parent and chunk_parent.__explicit_fragment_list
|
||||
local parent_explicit_fragment_count = chunk_parent and chunk_parent.__explicit_fragment_count or 0
|
||||
|
||||
if has_explicit_major then
|
||||
local explicit_fragment_list, explicit_fragment_count = parent_explicit_fragment_list
|
||||
and __list_fns.dup(parent_explicit_fragment_list, parent_explicit_fragment_count)
|
||||
or __list_fns.new(1), 0
|
||||
|
||||
explicit_fragment_count = parent_explicit_fragment_count + 1
|
||||
explicit_fragment_list[explicit_fragment_count] = chunk_fragment
|
||||
|
||||
chunk.__explicit_fragment_list = explicit_fragment_list
|
||||
chunk.__explicit_fragment_count = explicit_fragment_count
|
||||
else
|
||||
chunk.__explicit_fragment_list = parent_explicit_fragment_list
|
||||
chunk.__explicit_fragment_count = parent_explicit_fragment_count
|
||||
end
|
||||
else
|
||||
chunk.__explicit_fragment_list = nil
|
||||
chunk.__explicit_fragment_count = 0
|
||||
end
|
||||
end
|
||||
|
||||
---@param chunk evolved.chunk
|
||||
@@ -2063,17 +2150,15 @@ function __query_minor_matches(chunk, query)
|
||||
end
|
||||
end
|
||||
|
||||
if chunk.__has_explicit_fragments then
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local chunk_explicit_fragment_list = chunk.__explicit_fragment_list
|
||||
|
||||
for chunk_fragment_index = 1, chunk_fragment_count do
|
||||
local chunk_fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
if chunk_explicit_fragment_list then
|
||||
for chunk_explicit_fragment_index = 1, chunk.__explicit_fragment_count do
|
||||
local fragment = chunk_explicit_fragment_list[chunk_explicit_fragment_index]
|
||||
|
||||
local is_chunk_fragment_matched =
|
||||
(not __evolved_has(chunk_fragment, __EXPLICIT)) or
|
||||
(query_variant_count > 0 and query_variant_set[chunk_fragment]) or
|
||||
(query_include_count > 0 and query_include_set[chunk_fragment])
|
||||
(query_variant_count > 0 and query_variant_set[fragment]) or
|
||||
(query_include_count > 0 and query_include_set[fragment])
|
||||
|
||||
if not is_chunk_fragment_matched then
|
||||
return false
|
||||
@@ -2639,12 +2724,11 @@ function __spawn_entity(chunk, entity, component_table, component_mapper)
|
||||
component_mapper(chunk, place, place)
|
||||
end
|
||||
|
||||
if chunk.__has_insert_hooks then
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local chunk_insert_fragment_list = chunk.__insert_fragment_list
|
||||
|
||||
for chunk_fragment_index = 1, chunk_fragment_count do
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
if chunk_insert_fragment_list then
|
||||
for chunk_insert_fragment_index = 1, chunk.__insert_fragment_count do
|
||||
local fragment = chunk_insert_fragment_list[chunk_insert_fragment_index]
|
||||
|
||||
---@type evolved.set_hook?, evolved.insert_hook?
|
||||
local fragment_on_set, fragment_on_insert =
|
||||
@@ -2778,12 +2862,11 @@ function __multi_spawn_entity(chunk, entity_list, entity_first, entity_count, co
|
||||
component_mapper(chunk, b_place, e_place)
|
||||
end
|
||||
|
||||
if chunk.__has_insert_hooks then
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local chunk_insert_fragment_list = chunk.__insert_fragment_list
|
||||
|
||||
for chunk_fragment_index = 1, chunk_fragment_count do
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
if chunk_insert_fragment_list then
|
||||
for chunk_insert_fragment_index = 1, chunk.__insert_fragment_count do
|
||||
local fragment = chunk_insert_fragment_list[chunk_insert_fragment_index]
|
||||
|
||||
---@type evolved.set_hook?, evolved.insert_hook?
|
||||
local fragment_on_set, fragment_on_insert =
|
||||
@@ -2939,12 +3022,11 @@ function __clone_entity(prefab, entity, component_table, component_mapper)
|
||||
component_mapper(chunk, place, place)
|
||||
end
|
||||
|
||||
if chunk.__has_insert_hooks then
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local chunk_insert_fragment_list = chunk.__insert_fragment_list
|
||||
|
||||
for chunk_fragment_index = 1, chunk_fragment_count do
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
if chunk_insert_fragment_list then
|
||||
for chunk_insert_fragment_index = 1, chunk.__insert_fragment_count do
|
||||
local fragment = chunk_insert_fragment_list[chunk_insert_fragment_index]
|
||||
|
||||
---@type evolved.set_hook?, evolved.insert_hook?
|
||||
local fragment_on_set, fragment_on_insert =
|
||||
@@ -3107,12 +3189,11 @@ function __multi_clone_entity(prefab, entity_list, entity_first, entity_count, c
|
||||
component_mapper(chunk, b_place, e_place)
|
||||
end
|
||||
|
||||
if chunk.__has_insert_hooks then
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local chunk_insert_fragment_list = chunk.__insert_fragment_list
|
||||
|
||||
for chunk_fragment_index = 1, chunk_fragment_count do
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
if chunk_insert_fragment_list then
|
||||
for chunk_insert_fragment_index = 1, chunk.__insert_fragment_count do
|
||||
local fragment = chunk_insert_fragment_list[chunk_insert_fragment_index]
|
||||
|
||||
---@type evolved.set_hook?, evolved.insert_hook?
|
||||
local fragment_on_set, fragment_on_insert =
|
||||
@@ -3377,27 +3458,29 @@ function __clear_entity_one(entity)
|
||||
local chunk = entity_chunks[entity_primary]
|
||||
local place = entity_places[entity_primary]
|
||||
|
||||
if chunk and chunk.__has_remove_hooks then
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
if chunk then
|
||||
local chunk_remove_fragment_list = chunk.__remove_fragment_list
|
||||
|
||||
for chunk_fragment_index = 1, chunk_fragment_count do
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
if chunk_remove_fragment_list then
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
|
||||
---@type evolved.remove_hook?
|
||||
local fragment_on_remove = __evolved_get(fragment, __ON_REMOVE)
|
||||
for chunk_remove_fragment_index = 1, chunk.__remove_fragment_count do
|
||||
local fragment = chunk_remove_fragment_list[chunk_remove_fragment_index]
|
||||
|
||||
if fragment_on_remove then
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
---@type evolved.remove_hook?
|
||||
local fragment_on_remove = __evolved_get(fragment, __ON_REMOVE)
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local old_component = component_storage[place]
|
||||
fragment_on_remove(entity, fragment, old_component)
|
||||
else
|
||||
fragment_on_remove(entity, fragment)
|
||||
if fragment_on_remove then
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local old_component = component_storage[place]
|
||||
fragment_on_remove(entity, fragment, old_component)
|
||||
else
|
||||
fragment_on_remove(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3444,27 +3527,29 @@ function __destroy_entity_one(entity)
|
||||
local chunk = entity_chunks[entity_primary]
|
||||
local place = entity_places[entity_primary]
|
||||
|
||||
if chunk and chunk.__has_remove_hooks then
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
if chunk then
|
||||
local chunk_remove_fragment_list = chunk.__remove_fragment_list
|
||||
|
||||
for chunk_fragment_index = 1, chunk_fragment_count do
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
if chunk_remove_fragment_list then
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
|
||||
---@type evolved.remove_hook?
|
||||
local fragment_on_remove = __evolved_get(fragment, __ON_REMOVE)
|
||||
for chunk_remove_fragment_index = 1, chunk.__remove_fragment_count do
|
||||
local fragment = chunk_remove_fragment_list[chunk_remove_fragment_index]
|
||||
|
||||
if fragment_on_remove then
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
---@type evolved.remove_hook?
|
||||
local fragment_on_remove = __evolved_get(fragment, __ON_REMOVE)
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local old_component = component_storage[place]
|
||||
fragment_on_remove(entity, fragment, old_component)
|
||||
else
|
||||
fragment_on_remove(entity, fragment)
|
||||
if fragment_on_remove then
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local old_component = component_storage[place]
|
||||
fragment_on_remove(entity, fragment, old_component)
|
||||
else
|
||||
fragment_on_remove(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4060,8 +4145,6 @@ function __chunk_remove(old_chunk, ...)
|
||||
local old_entity_list = old_chunk.__entity_list
|
||||
local old_entity_count = old_chunk.__entity_count
|
||||
|
||||
local old_fragment_list = old_chunk.__fragment_list
|
||||
local old_fragment_count = old_chunk.__fragment_count
|
||||
local old_component_indices = old_chunk.__component_indices
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
|
||||
@@ -4075,12 +4158,14 @@ function __chunk_remove(old_chunk, ...)
|
||||
return
|
||||
end
|
||||
|
||||
if old_chunk.__has_remove_hooks then
|
||||
local old_remove_fragment_list = old_chunk.__remove_fragment_list
|
||||
|
||||
if old_remove_fragment_list then
|
||||
local new_fragment_set = new_chunk and new_chunk.__fragment_set
|
||||
or __safe_tbls.__EMPTY_FRAGMENT_SET
|
||||
|
||||
for old_fragment_index = 1, old_fragment_count do
|
||||
local fragment = old_fragment_list[old_fragment_index]
|
||||
for old_remove_fragment_index = 1, old_chunk.__remove_fragment_count do
|
||||
local fragment = old_remove_fragment_list[old_remove_fragment_index]
|
||||
|
||||
if not new_fragment_set[fragment] then
|
||||
---@type evolved.remove_hook?
|
||||
@@ -4209,14 +4294,14 @@ function __chunk_clear(chunk)
|
||||
return
|
||||
end
|
||||
|
||||
if chunk.__has_remove_hooks then
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_fragment_count = chunk.__fragment_count
|
||||
local chunk_remove_fragment_list = chunk.__remove_fragment_list
|
||||
|
||||
if chunk_remove_fragment_list then
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
|
||||
for chunk_fragment_index = 1, chunk_fragment_count do
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
for chunk_remove_fragment_index = 1, chunk.__remove_fragment_count do
|
||||
local fragment = chunk_remove_fragment_list[chunk_remove_fragment_index]
|
||||
|
||||
---@type evolved.remove_hook?
|
||||
local fragment_on_remove = __evolved_get(fragment, __ON_REMOVE)
|
||||
@@ -5610,17 +5695,17 @@ function __evolved_remove(entity, ...)
|
||||
__evolved_defer()
|
||||
|
||||
if old_chunk and old_chunk ~= new_chunk then
|
||||
local old_fragment_list = old_chunk.__fragment_list
|
||||
local old_fragment_count = old_chunk.__fragment_count
|
||||
local old_component_indices = old_chunk.__component_indices
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
|
||||
if old_chunk.__has_remove_hooks then
|
||||
local old_remove_fragment_list = old_chunk.__remove_fragment_list
|
||||
|
||||
if old_remove_fragment_list then
|
||||
local new_fragment_set = new_chunk and new_chunk.__fragment_set
|
||||
or __safe_tbls.__EMPTY_FRAGMENT_SET
|
||||
|
||||
for old_fragment_index = 1, old_fragment_count do
|
||||
local fragment = old_fragment_list[old_fragment_index]
|
||||
for old_remove_fragment_index = 1, old_chunk.__remove_fragment_count do
|
||||
local fragment = old_remove_fragment_list[old_remove_fragment_index]
|
||||
|
||||
if not new_fragment_set[fragment] then
|
||||
---@type evolved.remove_hook?
|
||||
|
||||
34
rockspecs/evolved.lua-1.10.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.10.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "evolved.lua"
|
||||
version = "1.10.0-0"
|
||||
source = {
|
||||
url = "git://github.com/BlackMATov/evolved.lua",
|
||||
tag = "v1.10.0",
|
||||
}
|
||||
description = {
|
||||
homepage = "https://github.com/BlackMATov/evolved.lua",
|
||||
summary = "Evolved ECS (Entity-Component-System) for Lua",
|
||||
detailed = [[
|
||||
`evolved.lua` is a fast and flexible ECS (Entity-Component-System) library for Lua.
|
||||
It is designed to be simple and easy to use, while providing all the features needed to create complex systems with blazing performance.
|
||||
]],
|
||||
license = "MIT",
|
||||
labels = {
|
||||
"ecs",
|
||||
"entity",
|
||||
"entities",
|
||||
"component",
|
||||
"components",
|
||||
"entity-component",
|
||||
"entity-component-system",
|
||||
},
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
evolved = "evolved.lua",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user