mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2026-03-22 12:55:31 +07:00
Compare commits
19 Commits
v1.5.0
...
d9c9b4cf85
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9c9b4cf85 | ||
|
|
20c94a0b72 | ||
|
|
e396c320ee | ||
|
|
52c898f912 | ||
|
|
a5319351c1 | ||
|
|
c9f4a74518 | ||
|
|
c29092c3e1 | ||
|
|
a0a4a20c35 | ||
|
|
2f8b0b0ef3 | ||
|
|
5e0170b4e8 | ||
|
|
d42c0cf3db | ||
|
|
723a65ca7f | ||
|
|
72fc524fe0 | ||
|
|
a8d1d84bed | ||
|
|
568cec4012 | ||
|
|
f175a25f1a | ||
|
|
856b9c665d | ||
|
|
8e2a34f2f6 | ||
|
|
47dd1bb30a |
2
.github/workflows/lua5.1.yml
vendored
2
.github/workflows/lua5.1.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- uses: leafo/gh-actions-lua@v11
|
||||
- uses: leafo/gh-actions-lua@v12
|
||||
with:
|
||||
luaVersion: ${{matrix.lua_version}}
|
||||
- run: |
|
||||
|
||||
21
.github/workflows/lua5.2.yml
vendored
Normal file
21
.github/workflows/lua5.2.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: lua5.2
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{matrix.operating_system}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
lua_version: ["5.2"]
|
||||
operating_system: ["ubuntu-latest", "macos-latest", "windows-latest"]
|
||||
name: ${{matrix.operating_system}}-${{matrix.lua_version}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- uses: leafo/gh-actions-lua@v12
|
||||
with:
|
||||
luaVersion: ${{matrix.lua_version}}
|
||||
- run: |
|
||||
lua ./develop/all.lua
|
||||
21
.github/workflows/lua5.3.yml
vendored
Normal file
21
.github/workflows/lua5.3.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: lua5.3
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{matrix.operating_system}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
lua_version: ["5.3"]
|
||||
operating_system: ["ubuntu-latest", "macos-latest", "windows-latest"]
|
||||
name: ${{matrix.operating_system}}-${{matrix.lua_version}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- uses: leafo/gh-actions-lua@v12
|
||||
with:
|
||||
luaVersion: ${{matrix.lua_version}}
|
||||
- run: |
|
||||
lua ./develop/all.lua
|
||||
2
.github/workflows/lua5.4.yml
vendored
2
.github/workflows/lua5.4.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- uses: leafo/gh-actions-lua@v11
|
||||
- uses: leafo/gh-actions-lua@v12
|
||||
with:
|
||||
luaVersion: ${{matrix.lua_version}}
|
||||
- run: |
|
||||
|
||||
2
.github/workflows/luajit.yml
vendored
2
.github/workflows/luajit.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- uses: leafo/gh-actions-lua@v11
|
||||
- uses: leafo/gh-actions-lua@v12
|
||||
with:
|
||||
luaVersion: ${{matrix.lua_version}}
|
||||
- run: |
|
||||
|
||||
27
.vscode/launch.json
vendored
27
.vscode/launch.json
vendored
@@ -10,6 +10,24 @@
|
||||
"file": "${workspaceFolder}/develop/all.lua"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Launch Evolved All (lua5.2)",
|
||||
"type": "lua-local",
|
||||
"request": "launch",
|
||||
"program": {
|
||||
"lua": "lua5.2",
|
||||
"file": "${workspaceFolder}/develop/all.lua"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Launch Evolved All (lua5.3)",
|
||||
"type": "lua-local",
|
||||
"request": "launch",
|
||||
"program": {
|
||||
"lua": "lua5.3",
|
||||
"file": "${workspaceFolder}/develop/all.lua"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Launch Evolved All (lua5.4)",
|
||||
"type": "lua-local",
|
||||
@@ -19,6 +37,15 @@
|
||||
"file": "${workspaceFolder}/develop/all.lua"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Launch Evolved All (lua5.5)",
|
||||
"type": "lua-local",
|
||||
"request": "launch",
|
||||
"program": {
|
||||
"lua": "lua5.5",
|
||||
"file": "${workspaceFolder}/develop/all.lua"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Launch Evolved All (luajit)",
|
||||
"type": "lua-local",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2024-2025, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
Copyright (C) 2024-2026, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
117
README.md
117
README.md
@@ -43,6 +43,7 @@
|
||||
- [Deferred Operations](#deferred-operations)
|
||||
- [Batch Operations](#batch-operations)
|
||||
- [Systems](#systems)
|
||||
- [Processing Payloads](#processing-payloads)
|
||||
- [Predefined Traits](#predefined-traits)
|
||||
- [Fragment Tags](#fragment-tags)
|
||||
- [Fragment Hooks](#fragment-hooks)
|
||||
@@ -60,6 +61,8 @@
|
||||
- [Chunk](#chunk)
|
||||
- [Builder](#builder)
|
||||
- [Changelog](#changelog)
|
||||
- [v1.7.0](#v170)
|
||||
- [v1.6.0](#v160)
|
||||
- [v1.5.0](#v150)
|
||||
- [v1.4.0](#v140)
|
||||
- [v1.3.0](#v130)
|
||||
@@ -585,16 +588,22 @@ evolved.set(entity, fragment, 42)
|
||||
|
||||
One of the most important features of any ECS library is the ability to process entities by filters or queries. `evolved.lua` provides a simple and efficient way to do this.
|
||||
|
||||
First, you need to create a query that describes which entities you want to process. You can specify fragments you want to include, and fragments you want to exclude. Queries are just identifiers with a special predefined fragments: [`evolved.INCLUDES`](#evolvedincludes) and [`evolved.EXCLUDES`](#evolvedexcludes). These fragments expect a list of fragments as their components.
|
||||
First, you need to create a query that describes which entities you want to process. You can specify fragments you want to include, and fragments you want to exclude. Queries are just identifiers with a special predefined fragments: [`evolved.INCLUDES`](#evolvedincludes), [`evolved.EXCLUDES`](#evolvedexcludes), and [`evolved.VARIANTS`](#evolvedvariants). These fragments expect a list of fragments as their components.
|
||||
|
||||
- [`evolved.INCLUDES`](#evolvedincludes) is used to specify fragments that must be present in the entity;
|
||||
- [`evolved.EXCLUDES`](#evolvedexcludes) is used to specify fragments that must not be present in the entity;
|
||||
- [`evolved.VARIANTS`](#evolvedvariants) is used to specify fragments where at least one must be present in the entity.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local health, poisoned, resistant = evolved.id(3)
|
||||
local alive, undead = evolved.id(2)
|
||||
|
||||
local query = evolved.id()
|
||||
evolved.set(query, evolved.INCLUDES, { health, poisoned })
|
||||
evolved.set(query, evolved.EXCLUDES, { resistant })
|
||||
evolved.set(query, evolved.VARIANTS, { alive, undead })
|
||||
```
|
||||
|
||||
The builder interface can be used to create queries too. It is more convenient to use, because the builder has special methods for including and excluding fragments. Here is a simple example of this:
|
||||
@@ -603,10 +612,11 @@ The builder interface can be used to create queries too. It is more convenient t
|
||||
local query = evolved.builder()
|
||||
:include(health, poisoned)
|
||||
:exclude(resistant)
|
||||
:variant(alive, undead)
|
||||
:build()
|
||||
```
|
||||
|
||||
We don't have to set both [`evolved.INCLUDES`](#evolvedincludes) and [`evolved.EXCLUDES`](#evolvedexcludes) fragments, we can even do it without filters at all, then the query will match all chunks in the world.
|
||||
We don't have to set all of [`evolved.INCLUDES`](#evolvedincludes), [`evolved.EXCLUDES`](#evolvedexcludes), and [`evolved.VARIANTS`](#evolvedvariants) fragments, we can even do it without filters at all, then the query will match all chunks in the world.
|
||||
|
||||
After the query is created, we are ready to process our filtered by this query entities. You can do this by using the [`evolved.execute`](#evolvedexecute) function. This function takes a query as an argument and returns an iterator that can be used to iterate over all matching with the query chunks.
|
||||
|
||||
@@ -643,6 +653,10 @@ Now we know that structural changes are not allowed during iteration, but what i
|
||||
---@return boolean started
|
||||
function evolved.defer() end
|
||||
|
||||
---@return integer depth
|
||||
---@nodiscard
|
||||
function evolved.depth() end
|
||||
|
||||
---@return boolean committed
|
||||
function evolved.commit() end
|
||||
|
||||
@@ -650,7 +664,7 @@ function evolved.commit() end
|
||||
function evolved.cancel() end
|
||||
```
|
||||
|
||||
The [`evolved.defer`](#evolveddefer) function starts a deferred scope. This means that all changes made inside the scope will be queued and applied after leaving the scope. The [`evolved.commit`](#evolvedcommit) function closes the last deferred scope and applies all queued changes. These functions can be nested, so you can start a new deferred scope inside an existing one. The [`evolved.commit`](#evolvedcommit) function will apply all queued changes only when the last deferred scope is closed.
|
||||
The [`evolved.defer`](#evolveddefer) function starts a deferred scope. This means that all changes made inside the scope will be queued and applied after leaving the scope. The [`evolved.commit`](#evolvedcommit) function closes the last deferred scope and applies all queued changes. These functions can be nested, so you can start a new deferred scope inside an existing one. The [`evolved.commit`](#evolvedcommit) function will apply all queued changes only when the last deferred scope is closed. The [`evolved.depth`](#evolveddepth) function returns the current depth of deferred scopes. If there are no deferred scopes, it returns `0`.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
@@ -781,7 +795,7 @@ The [`evolved.process`](#evolvedprocess) function is used to process systems. It
|
||||
function evolved.process(...) end
|
||||
```
|
||||
|
||||
If you don't specify a query for the system, the system itself will be treated as a query. This means the system can contain `evolved.INCLUDES` and `evolved.EXCLUDES` fragments, and it will be processed according to them. This is useful for creating systems with unique queries that don't need to be reused in other systems.
|
||||
If you don't specify a query for the system, the system itself will be treated as a query. This means the system can contain `evolved.INCLUDES`, `evolved.EXCLUDES`, and `evolved.VARIANTS` fragments, and it will be processed according to them. This is useful for creating systems with unique queries that don't need to be reused in other systems.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
@@ -875,6 +889,43 @@ The prologue and epilogue fragments do not require an explicit query. They will
|
||||
> [!NOTE]
|
||||
> And one more thing about systems. Execution callbacks are called in the [deferred scope](#deferred-operations), which means that all modifying operations inside the callback will be queued and applied after the system has processed all chunks. But prologue and epilogue callbacks are not called in the deferred scope, so all modifying operations inside them will be applied immediately. This is done to avoid confusion and to make it clear that prologue and epilogue callbacks are not part of the chunk processing.
|
||||
|
||||
#### Processing Payloads
|
||||
|
||||
Additionally, systems can have a payload that will be passed to the execution, prologue, and epilogue callbacks. This is useful for passing additional data to the system without using global variables or closures.
|
||||
|
||||
```lua
|
||||
---@param system evolved.system
|
||||
---@param ... any processing payload
|
||||
function evolved.process_with(system, ...) end
|
||||
```
|
||||
|
||||
The [`evolved.process_with`](#evolvedprocess_with) function is similar to the [`evolved.process`](#evolvedprocess) function, but it takes a processing payload as additional arguments. These arguments will be passed to the system's callbacks.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local position_x, position_y = evolved.id(2)
|
||||
local velocity_x, velocity_y = evolved.id(2)
|
||||
|
||||
local physics_system = evolved.builder()
|
||||
:include(position_x, position_y)
|
||||
:include(velocity_x, velocity_y)
|
||||
:execute(function(chunk, entity_list, entity_count, delta_time)
|
||||
local px, py = chunk:components(position_x, position_y)
|
||||
local vx, vy = chunk:components(velocity_x, velocity_y)
|
||||
|
||||
for i = 1, entity_count do
|
||||
px[i] = px[i] + vx[i] * delta_time
|
||||
py[i] = py[i] + vy[i] * delta_time
|
||||
end
|
||||
end):build()
|
||||
|
||||
local delta_time = 0.016
|
||||
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
|
||||
|
||||
#### Fragment Tags
|
||||
@@ -1120,9 +1171,9 @@ storage :: component[]
|
||||
default :: component
|
||||
duplicate :: {component -> component}
|
||||
|
||||
execute :: {chunk, entity[], integer}
|
||||
prologue :: {}
|
||||
epilogue :: {}
|
||||
execute :: {chunk, entity[], integer, any...}
|
||||
prologue :: {any...}
|
||||
epilogue :: {any...}
|
||||
|
||||
set_hook :: {entity, fragment, component, component}
|
||||
assign_hook :: {entity, fragment, component, component}
|
||||
@@ -1154,6 +1205,7 @@ DISABLED :: fragment
|
||||
|
||||
INCLUDES :: fragment
|
||||
EXCLUDES :: fragment
|
||||
VARIANTS :: fragment
|
||||
REQUIRES :: fragment
|
||||
|
||||
ON_SET :: fragment
|
||||
@@ -1184,6 +1236,7 @@ pack :: integer, integer -> id
|
||||
unpack :: id -> integer, integer
|
||||
|
||||
defer :: boolean
|
||||
depth :: integer
|
||||
commit :: boolean
|
||||
cancel :: boolean
|
||||
|
||||
@@ -1223,6 +1276,7 @@ execute :: query -> {execute_state? -> chunk?, entity[]?, integer?}, execute_sta
|
||||
locate :: entity -> chunk?, integer
|
||||
|
||||
process :: system... -> ()
|
||||
process_with :: system, ... -> ()
|
||||
|
||||
debug_mode :: boolean -> ()
|
||||
collect_garbage :: ()
|
||||
@@ -1286,6 +1340,7 @@ builder_mt:disabled :: builder
|
||||
|
||||
builder_mt:include :: fragment... -> builder
|
||||
builder_mt:exclude :: fragment... -> builder
|
||||
builder_mt:variant :: fragment... -> builder
|
||||
builder_mt:require :: fragment... -> builder
|
||||
|
||||
builder_mt:on_set :: {entity, fragment, component, component} -> builder
|
||||
@@ -1296,21 +1351,31 @@ builder_mt:on_remove :: {entity, fragment} -> builder
|
||||
builder_mt:group :: system -> builder
|
||||
|
||||
builder_mt:query :: query -> builder
|
||||
builder_mt:execute :: {chunk, entity[], integer} -> builder
|
||||
builder_mt:execute :: {chunk, entity[], integer, any...} -> builder
|
||||
|
||||
builder_mt:prologue :: {} -> builder
|
||||
builder_mt:epilogue :: {} -> builder
|
||||
builder_mt:prologue :: {any...} -> builder
|
||||
builder_mt:epilogue :: {any...} -> builder
|
||||
|
||||
builder_mt:destruction_policy :: id -> builder
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
### v1.7.0
|
||||
|
||||
- Added the new [`evolved.VARIANTS`](#evolvedvariants) query fragment that allows specifying any of multiple fragments in queries
|
||||
- Added the new [`evolved.process_with`](#evolvedprocess_with) function that allows passing payloads to processing systems
|
||||
|
||||
### v1.6.0
|
||||
|
||||
- Significant performance improvements of the [`evolved.REQUIRES`](#evolvedrequires) fragment trait
|
||||
- Added the new [`evolved.depth`](#evolveddepth) function that returns the current depth of deferred scopes
|
||||
|
||||
### v1.5.0
|
||||
|
||||
- Added a little [LÖVE](https://love2d.org) example;
|
||||
- The spawn and clone operations with defaults have been significantly optimized;
|
||||
- Added basic [Teal](https://github.com/teal-language) type definitions, thanks to [@p0sel0k](https://github.com/p0sel0k).
|
||||
- Added a little [LÖVE](https://love2d.org) example
|
||||
- The spawn and clone operations with defaults have been significantly optimized
|
||||
- Added basic [Teal](https://github.com/teal-language) type definitions, thanks to [@p0sel0k](https://github.com/p0sel0k)
|
||||
|
||||
### v1.4.0
|
||||
|
||||
@@ -1373,6 +1438,8 @@ builder_mt:destruction_policy :: id -> builder
|
||||
|
||||
### `evolved.EXCLUDES`
|
||||
|
||||
### `evolved.VARIANTS`
|
||||
|
||||
### `evolved.REQUIRES`
|
||||
|
||||
### `evolved.ON_SET`
|
||||
@@ -1446,6 +1513,14 @@ function evolved.unpack(id) end
|
||||
function evolved.defer() end
|
||||
```
|
||||
|
||||
### `evolved.depth`
|
||||
|
||||
```lua
|
||||
---@return integer depth
|
||||
---@nodiscard
|
||||
function evolved.depth() end
|
||||
```
|
||||
|
||||
### `evolved.commit`
|
||||
|
||||
```lua
|
||||
@@ -1691,6 +1766,14 @@ function evolved.locate(entity) end
|
||||
function evolved.process(...) end
|
||||
```
|
||||
|
||||
### `evolved.process_with`
|
||||
|
||||
```lua
|
||||
---@param system evolved.system
|
||||
---@param ... any processing payload
|
||||
function evolved.process_with(system, ...) end
|
||||
```
|
||||
|
||||
### `evolved.debug_mode`
|
||||
|
||||
```lua
|
||||
@@ -1994,6 +2077,14 @@ function evolved.builder_mt:include(...) end
|
||||
function evolved.builder_mt:exclude(...) end
|
||||
```
|
||||
|
||||
#### `evolved.builder_mt:variant`
|
||||
|
||||
```lua
|
||||
---@param ... evolved.fragment fragments
|
||||
---@return evolved.builder builder
|
||||
function evolved.builder_mt:variant(...) end
|
||||
```
|
||||
|
||||
### `evolved.builder_mt:require`
|
||||
|
||||
```lua
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
1. Insert the new function into the `evolved` table in `evolved.lua`.
|
||||
2. Create tests for the function in `develop/testing/function_name_tests.lua`.
|
||||
3. Add the new test to `develop/all.lua`.
|
||||
4. Document the function in the **Cheat Sheet** and **API Reference** sections of `README.md`.
|
||||
5. Provide a description in the **Overview** section of `README.md`.
|
||||
6. Describe the update in the **Changelog** section of `README.md`.
|
||||
4. Update the Teal type definitions in `evolved.d.tl`.
|
||||
5. Document the function in the **Cheat Sheet** and **API Reference** sections of `README.md`.
|
||||
6. Provide a description in the **Overview** section of `README.md`.
|
||||
7. Describe the update in the **Changelog** section of `README.md`.
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
|
||||
## Thoughts
|
||||
|
||||
- We can return deferred status from modifying operations and spawn/clone methods.
|
||||
- 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
|
||||
|
||||
## Known Issues
|
||||
|
||||
- Required fragments are slower than they should be
|
||||
- Errors in hooks are cannot be handled properly right now
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
require 'develop.testing.build_tests'
|
||||
require 'develop.testing.cancel_tests'
|
||||
require 'develop.testing.clone_tests'
|
||||
require 'develop.testing.depth_tests'
|
||||
require 'develop.testing.destroy_tests'
|
||||
require 'develop.testing.locate_tests'
|
||||
require 'develop.testing.main_tests'
|
||||
require 'develop.testing.multi_spawn_tests'
|
||||
require 'develop.testing.name_tests'
|
||||
require 'develop.testing.process_with_tests'
|
||||
require 'develop.testing.requires_fragment_tests'
|
||||
require 'develop.testing.spawn_tests'
|
||||
require 'develop.testing.system_as_query_tests'
|
||||
|
||||
@@ -173,6 +173,7 @@ basics.describe_bench(
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF1] = true }
|
||||
evo.remove(prefab, F1)
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
@@ -217,6 +218,7 @@ basics.describe_bench(
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF123] = true }
|
||||
evo.remove(prefab, F1, F2, F3)
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
@@ -261,6 +263,7 @@ basics.describe_bench(
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF12345] = true }
|
||||
evo.remove(prefab, F1, F2, F3, F4, F5)
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
|
||||
@@ -56,6 +56,20 @@ local function generate_query(query)
|
||||
end
|
||||
end
|
||||
|
||||
local variant_set = {}
|
||||
local variant_list = {}
|
||||
local variant_count = 0
|
||||
|
||||
for _ = 1, math.random(0, #all_fragment_list) do
|
||||
local variant = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
|
||||
if not variant_set[variant] then
|
||||
variant_count = variant_count + 1
|
||||
variant_set[variant] = variant_count
|
||||
variant_list[variant_count] = variant
|
||||
end
|
||||
end
|
||||
|
||||
if include_count > 0 then
|
||||
evo.set(query, evo.INCLUDES, include_list)
|
||||
end
|
||||
@@ -63,6 +77,10 @@ local function generate_query(query)
|
||||
if exclude_count > 0 then
|
||||
evo.set(query, evo.EXCLUDES, exclude_list)
|
||||
end
|
||||
|
||||
if variant_count > 0 then
|
||||
evo.set(query, evo.VARIANTS, variant_list)
|
||||
end
|
||||
end
|
||||
|
||||
---@param query_count integer
|
||||
@@ -173,12 +191,22 @@ local function execute_query(query)
|
||||
|
||||
local query_include_list = evo.get(query, evo.INCLUDES) or {}
|
||||
local query_exclude_list = evo.get(query, evo.EXCLUDES) or {}
|
||||
local query_variant_list = evo.get(query, evo.VARIANTS) or {}
|
||||
|
||||
local query_include_count = #query_include_list
|
||||
local query_exclude_count = #query_exclude_list
|
||||
local query_variant_count = #query_variant_list
|
||||
|
||||
local query_include_set = {}
|
||||
for _, include in ipairs(query_include_list) do
|
||||
query_include_set[include] = true
|
||||
end
|
||||
|
||||
local query_variant_set = {}
|
||||
for _, variant in ipairs(query_variant_list) do
|
||||
query_variant_set[variant] = true
|
||||
end
|
||||
|
||||
for chunk, entity_list, entity_count in evo.execute(query) do
|
||||
assert(not query_chunk_set[chunk])
|
||||
query_chunk_set[chunk] = true
|
||||
@@ -189,19 +217,29 @@ local function execute_query(query)
|
||||
query_entity_set[entity] = true
|
||||
end
|
||||
|
||||
assert(chunk:has_all(__table_unpack(query_include_list)))
|
||||
assert(not chunk:has_any(__table_unpack(query_exclude_list)))
|
||||
if query_include_count > 0 then
|
||||
assert(chunk:has_all(__table_unpack(query_include_list)))
|
||||
end
|
||||
|
||||
if query_exclude_count > 0 then
|
||||
assert(not chunk:has_any(__table_unpack(query_exclude_list)))
|
||||
end
|
||||
|
||||
if query_variant_count > 0 then
|
||||
assert(chunk:has_any(__table_unpack(query_variant_list)))
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, all_entity_count do
|
||||
local entity = all_entity_list[i]
|
||||
|
||||
local is_entity_matched =
|
||||
evo.has_all(entity, __table_unpack(query_include_list))
|
||||
and not evo.has_any(entity, __table_unpack(query_exclude_list))
|
||||
(query_variant_count == 0 or evo.has_any(entity, __table_unpack(query_variant_list))) and
|
||||
(query_include_count == 0 or evo.has_all(entity, __table_unpack(query_include_list))) and
|
||||
(query_exclude_count == 0 or not evo.has_any(entity, __table_unpack(query_exclude_list)))
|
||||
|
||||
for fragment in evo.each(entity) do
|
||||
if evo.has(fragment, evo.EXPLICIT) and not query_include_set[fragment] then
|
||||
if evo.has(fragment, evo.EXPLICIT) and not query_variant_set[fragment] and not query_include_set[fragment] then
|
||||
is_entity_matched = false
|
||||
end
|
||||
end
|
||||
@@ -236,10 +274,13 @@ for _ = 1, math.random(1, 5) do
|
||||
if math.random(1, 2) == 1 then
|
||||
generate_query(query)
|
||||
else
|
||||
if math.random(1, 2) == 1 then
|
||||
local r = math.random(1, 3)
|
||||
if r == 1 then
|
||||
evo.remove(query, evo.INCLUDES)
|
||||
else
|
||||
elseif r == 2 then
|
||||
evo.remove(query, evo.EXCLUDES)
|
||||
else
|
||||
evo.remove(query, evo.VARIANTS)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
65
develop/testing/depth_tests.lua
Normal file
65
develop/testing/depth_tests.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
assert(evo.depth() == 0)
|
||||
|
||||
assert(evo.defer())
|
||||
assert(evo.depth() == 1)
|
||||
|
||||
assert(not evo.defer())
|
||||
assert(evo.depth() == 2)
|
||||
|
||||
assert(not evo.cancel())
|
||||
assert(evo.depth() == 1)
|
||||
|
||||
assert(evo.cancel())
|
||||
assert(evo.depth() == 0)
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.depth() == 0)
|
||||
|
||||
assert(evo.defer())
|
||||
assert(evo.depth() == 1)
|
||||
|
||||
assert(not evo.defer())
|
||||
assert(evo.depth() == 2)
|
||||
|
||||
assert(not evo.commit())
|
||||
assert(evo.depth() == 1)
|
||||
|
||||
assert(evo.commit())
|
||||
assert(evo.depth() == 0)
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.depth() == 0)
|
||||
|
||||
assert(evo.defer())
|
||||
assert(evo.depth() == 1)
|
||||
|
||||
assert(not evo.defer())
|
||||
assert(evo.depth() == 2)
|
||||
|
||||
assert(not evo.cancel())
|
||||
assert(evo.depth() == 1)
|
||||
|
||||
assert(evo.commit())
|
||||
assert(evo.depth() == 0)
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.depth() == 0)
|
||||
|
||||
assert(evo.defer())
|
||||
assert(evo.depth() == 1)
|
||||
|
||||
assert(not evo.defer())
|
||||
assert(evo.depth() == 2)
|
||||
|
||||
assert(not evo.commit())
|
||||
assert(evo.depth() == 1)
|
||||
|
||||
assert(evo.cancel())
|
||||
assert(evo.depth() == 0)
|
||||
end
|
||||
104
develop/testing/destroy_tests.lua
Normal file
104
develop/testing/destroy_tests.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(evo.alive(e))
|
||||
|
||||
evo.destroy(e)
|
||||
assert(not evo.alive(e))
|
||||
|
||||
evo.destroy(e)
|
||||
assert(not evo.alive(e))
|
||||
end
|
||||
|
||||
do
|
||||
local e1, e2 = evo.id(2)
|
||||
assert(evo.alive_all(e1, e2))
|
||||
|
||||
evo.destroy(e1, e2)
|
||||
assert(not evo.alive_any(e1, e2))
|
||||
|
||||
evo.destroy(e1, e2)
|
||||
assert(not evo.alive_any(e1, e2))
|
||||
end
|
||||
|
||||
do
|
||||
do
|
||||
local e, f1, f2, f3 = evo.id(4)
|
||||
|
||||
evo.set(e, f1, 42)
|
||||
evo.set(e, f2, 21)
|
||||
evo.set(e, f3, 84)
|
||||
|
||||
evo.destroy(f1, f2)
|
||||
assert(evo.alive(e) and not evo.has_any(e, f1, f2) and evo.has(e, f3))
|
||||
end
|
||||
do
|
||||
local e, f1, f2, f3 = evo.id(4)
|
||||
evo.set(f1, evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_REMOVE_FRAGMENT)
|
||||
|
||||
evo.set(e, f1, 42)
|
||||
evo.set(e, f2, 21)
|
||||
evo.set(e, f3, 84)
|
||||
|
||||
evo.destroy(f1, f2)
|
||||
assert(evo.alive(e) and not evo.has_any(e, f1, f2) and evo.has(e, f3))
|
||||
end
|
||||
do
|
||||
local e, f1, f2, f3 = evo.id(4)
|
||||
evo.set(f2, evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_REMOVE_FRAGMENT)
|
||||
|
||||
evo.set(e, f1, 42)
|
||||
evo.set(e, f2, 21)
|
||||
evo.set(e, f3, 84)
|
||||
|
||||
evo.destroy(f1, f2)
|
||||
assert(evo.alive(e) and not evo.has_any(e, f1, f2) and evo.has(e, f3))
|
||||
end
|
||||
do
|
||||
local e, f1, f2, f3 = evo.id(4)
|
||||
evo.set(f1, evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_REMOVE_FRAGMENT)
|
||||
evo.set(f2, evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_REMOVE_FRAGMENT)
|
||||
|
||||
evo.set(e, f1, 42)
|
||||
evo.set(e, f2, 21)
|
||||
evo.set(e, f3, 84)
|
||||
|
||||
evo.destroy(f1, f2)
|
||||
assert(evo.alive(e) and not evo.has_any(e, f1, f2) and evo.has(e, f3))
|
||||
end
|
||||
do
|
||||
local e, f1, f2, f3 = evo.id(4)
|
||||
evo.set(f1, evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
|
||||
evo.set(e, f1, 42)
|
||||
evo.set(e, f2, 21)
|
||||
evo.set(e, f3, 84)
|
||||
|
||||
evo.destroy(f1, f2)
|
||||
assert(not evo.alive(e))
|
||||
end
|
||||
do
|
||||
local e, f1, f2, f3 = evo.id(4)
|
||||
evo.set(f2, evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
|
||||
evo.set(e, f1, 42)
|
||||
evo.set(e, f2, 21)
|
||||
evo.set(e, f3, 84)
|
||||
|
||||
evo.destroy(f1, f2)
|
||||
assert(not evo.alive(e))
|
||||
end
|
||||
do
|
||||
local e, f1, f2, f3 = evo.id(4)
|
||||
evo.set(f1, evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
evo.set(f2, evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
|
||||
evo.set(e, f1, 42)
|
||||
evo.set(e, f2, 21)
|
||||
evo.set(e, f3, 84)
|
||||
|
||||
evo.destroy(f1, f2)
|
||||
assert(not evo.alive(e))
|
||||
end
|
||||
end
|
||||
107
develop/testing/process_with_tests.lua
Normal file
107
develop/testing/process_with_tests.lua
Normal file
@@ -0,0 +1,107 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
local f = evo.id()
|
||||
local e = evo.builder():set(f, 42):spawn()
|
||||
|
||||
local s = evo.builder()
|
||||
:include(f)
|
||||
:prologue(function(payload1, payload2, payload3)
|
||||
assert(payload1 == 11 and payload2 == 22 and payload3 == 33)
|
||||
end)
|
||||
:execute(function(chunk, entity_list, entity_count, payload1, payload2, payload3)
|
||||
assert(payload1 == 11 and payload2 == 22 and payload3 == 33)
|
||||
assert(chunk == evo.chunk(f) and entity_count == 1 and entity_list[1] == e)
|
||||
end)
|
||||
:epilogue(function(payload1, payload2, payload3)
|
||||
assert(payload1 == 11 and payload2 == 22 and payload3 == 33)
|
||||
end)
|
||||
:spawn()
|
||||
|
||||
evo.process_with(s, 11, 22, 33)
|
||||
end
|
||||
|
||||
do
|
||||
local f = evo.id()
|
||||
local e = evo.builder():set(f, 42):spawn()
|
||||
|
||||
local s = evo.builder()
|
||||
:include(f)
|
||||
:prologue(function(payload1, payload2, payload3)
|
||||
assert(payload1 == nil and payload2 == 42 and payload3 == nil)
|
||||
end)
|
||||
:execute(function(chunk, entity_list, entity_count, payload1, payload2, payload3)
|
||||
assert(payload1 == nil and payload2 == 42 and payload3 == nil)
|
||||
assert(chunk == evo.chunk(f) and entity_count == 1 and entity_list[1] == e)
|
||||
end)
|
||||
:epilogue(function(payload1, payload2, payload3)
|
||||
assert(payload1 == nil and payload2 == 42 and payload3 == nil)
|
||||
end)
|
||||
:spawn()
|
||||
|
||||
evo.process_with(s, nil, 42)
|
||||
end
|
||||
|
||||
do
|
||||
local f = evo.id()
|
||||
local e = evo.builder():set(f, 42):spawn()
|
||||
|
||||
local s = evo.builder()
|
||||
:include(f)
|
||||
:prologue(function(payload1, payload2, payload3)
|
||||
assert(payload1 == nil and payload2 == nil and payload3 == nil)
|
||||
end)
|
||||
:execute(function(chunk, entity_list, entity_count, payload1, payload2, payload3)
|
||||
assert(payload1 == nil and payload2 == nil and payload3 == nil)
|
||||
assert(chunk == evo.chunk(f) and entity_count == 1 and entity_list[1] == e)
|
||||
end)
|
||||
:epilogue(function(payload1, payload2, payload3)
|
||||
assert(payload1 == nil and payload2 == nil and payload3 == nil)
|
||||
end)
|
||||
:spawn()
|
||||
|
||||
evo.process_with(s)
|
||||
end
|
||||
|
||||
do
|
||||
local f = evo.id()
|
||||
local e = evo.builder():set(f, 42):spawn()
|
||||
|
||||
local prologue_sum, execute_sum, epilogue_sum = 0, 0, 0
|
||||
|
||||
local function sum(...)
|
||||
local s = 0
|
||||
for i = 1, select('#', ...) do
|
||||
s = s + select(i, ...)
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function iota(n)
|
||||
if n == 0 then return end
|
||||
return n, iota(n - 1)
|
||||
end
|
||||
|
||||
local s = evo.builder()
|
||||
:include(f)
|
||||
:prologue(function(...)
|
||||
prologue_sum = prologue_sum + sum(...)
|
||||
end)
|
||||
:execute(function(chunk, entity_list, entity_count, ...)
|
||||
execute_sum = execute_sum + sum(...)
|
||||
assert(chunk == evo.chunk(f) and entity_count == 1 and entity_list[1] == e)
|
||||
end)
|
||||
:epilogue(function(...)
|
||||
epilogue_sum = epilogue_sum + sum(...)
|
||||
end)
|
||||
:spawn()
|
||||
|
||||
for n = 0, 50 do
|
||||
prologue_sum, execute_sum, epilogue_sum = 0, 0, 0
|
||||
evo.process_with(s, iota(n))
|
||||
local expect_sum = (n * (n + 1)) / 2
|
||||
assert(prologue_sum == expect_sum)
|
||||
assert(execute_sum == expect_sum)
|
||||
assert(epilogue_sum == expect_sum)
|
||||
end
|
||||
end
|
||||
@@ -243,3 +243,143 @@ do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
evo.set(f2, evo.REQUIRES, { f3 })
|
||||
evo.set(f3, evo.REQUIRES, { f4 })
|
||||
|
||||
do
|
||||
local e1 = evo.builder():set(f1):spawn()
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
assert(evo.has(e1, f3) and evo.get(e1, f3) == true)
|
||||
assert(evo.has(e1, f4) and evo.get(e1, f4) == true)
|
||||
|
||||
local e2 = evo.builder():set(f2):spawn()
|
||||
assert(not evo.has(e2, f1) and evo.get(e2, f1) == nil)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(evo.has(e2, f3) and evo.get(e2, f3) == true)
|
||||
assert(evo.has(e2, f4) and evo.get(e2, f4) == true)
|
||||
|
||||
local e3 = evo.builder():set(f3):spawn()
|
||||
assert(not evo.has(e3, f1) and evo.get(e3, f1) == nil)
|
||||
assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == true)
|
||||
assert(evo.has(e3, f4) and evo.get(e3, f4) == true)
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.id()
|
||||
evo.set(e1, f1)
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
assert(evo.has(e1, f3) and evo.get(e1, f3) == true)
|
||||
assert(evo.has(e1, f4) and evo.get(e1, f4) == true)
|
||||
|
||||
local e2 = evo.id()
|
||||
evo.set(e2, f2)
|
||||
assert(not evo.has(e2, f1) and evo.get(e2, f1) == nil)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(evo.has(e2, f3) and evo.get(e2, f3) == true)
|
||||
assert(evo.has(e2, f4) and evo.get(e2, f4) == true)
|
||||
|
||||
local e3 = evo.id()
|
||||
evo.set(e3, f3)
|
||||
assert(not evo.has(e3, f1) and evo.get(e3, f1) == nil)
|
||||
assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == true)
|
||||
assert(evo.has(e3, f4) and evo.get(e3, f4) == true)
|
||||
end
|
||||
|
||||
evo.remove(f2, evo.REQUIRES)
|
||||
|
||||
do
|
||||
local e1 = evo.builder():set(f1):spawn()
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
assert(not evo.has(e1, f3) and evo.get(e1, f3) == nil)
|
||||
assert(not evo.has(e1, f4) and evo.get(e1, f4) == nil)
|
||||
|
||||
local e2 = evo.builder():set(f2):spawn()
|
||||
assert(not evo.has(e2, f1) and evo.get(e2, f1) == nil)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(not evo.has(e2, f3) and evo.get(e2, f3) == nil)
|
||||
assert(not evo.has(e2, f4) and evo.get(e2, f4) == nil)
|
||||
|
||||
local e3 = evo.builder():set(f3):spawn()
|
||||
assert(not evo.has(e3, f1) and evo.get(e3, f1) == nil)
|
||||
assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == true)
|
||||
assert(evo.has(e3, f4) and evo.get(e3, f4) == true)
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.id()
|
||||
evo.set(e1, f1)
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
assert(not evo.has(e1, f3) and evo.get(e1, f3) == nil)
|
||||
assert(not evo.has(e1, f4) and evo.get(e1, f4) == nil)
|
||||
|
||||
local e2 = evo.id()
|
||||
evo.set(e2, f2)
|
||||
assert(not evo.has(e2, f1) and evo.get(e2, f1) == nil)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(not evo.has(e2, f3) and evo.get(e2, f3) == nil)
|
||||
assert(not evo.has(e2, f4) and evo.get(e2, f4) == nil)
|
||||
|
||||
local e3 = evo.id()
|
||||
evo.set(e3, f3)
|
||||
assert(not evo.has(e3, f1) and evo.get(e3, f1) == nil)
|
||||
assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == true)
|
||||
assert(evo.has(e3, f4) and evo.get(e3, f4) == true)
|
||||
end
|
||||
|
||||
evo.set(f2, evo.REQUIRES, { f4 })
|
||||
|
||||
do
|
||||
local e1 = evo.builder():set(f1):spawn()
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
assert(not evo.has(e1, f3) and evo.get(e1, f3) == nil)
|
||||
assert(evo.has(e1, f4) and evo.get(e1, f4) == true)
|
||||
|
||||
local e2 = evo.builder():set(f2):spawn()
|
||||
assert(not evo.has(e2, f1) and evo.get(e2, f1) == nil)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(not evo.has(e2, f3) and evo.get(e2, f3) == nil)
|
||||
assert(evo.has(e2, f4) and evo.get(e2, f4) == true)
|
||||
|
||||
local e3 = evo.builder():set(f3):spawn()
|
||||
assert(not evo.has(e3, f1) and evo.get(e3, f1) == nil)
|
||||
assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == true)
|
||||
assert(evo.has(e3, f4) and evo.get(e3, f4) == true)
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.id()
|
||||
evo.set(e1, f1)
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
assert(not evo.has(e1, f3) and evo.get(e1, f3) == nil)
|
||||
assert(evo.has(e1, f4) and evo.get(e1, f4) == true)
|
||||
|
||||
local e2 = evo.id()
|
||||
evo.set(e2, f2)
|
||||
assert(not evo.has(e2, f1) and evo.get(e2, f1) == nil)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(not evo.has(e2, f3) and evo.get(e2, f3) == nil)
|
||||
assert(evo.has(e2, f4) and evo.get(e2, f4) == true)
|
||||
|
||||
local e3 = evo.id()
|
||||
evo.set(e3, f3)
|
||||
assert(not evo.has(e3, f1) and evo.get(e3, f1) == nil)
|
||||
assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == true)
|
||||
assert(evo.has(e3, f4) and evo.get(e3, f4) == true)
|
||||
end
|
||||
end
|
||||
|
||||
10
evolved.d.tl
10
evolved.d.tl
@@ -69,6 +69,7 @@
|
||||
|
||||
include: function(self: Builder, ...: Fragment): Builder
|
||||
exclude: function(self: Builder, ...: Fragment): Builder
|
||||
variant: function(self: Builder, ...: Fragment): Builder
|
||||
require: function(self: Builder, ...: Fragment): Builder
|
||||
|
||||
on_set: function<Component>(self: Builder, on_set: function(Entity, Fragment, ? Component, ? Component)): Builder
|
||||
@@ -79,10 +80,10 @@
|
||||
group: function(self: Builder, group: System): Builder
|
||||
|
||||
query: function(self: Builder, query: Query): Builder
|
||||
execute: function(self: Builder, execute: function(Chunk, {Entity}, integer)): Builder
|
||||
execute: function(self: Builder, execute: function(Chunk, {Entity}, integer, ...: any)): Builder
|
||||
|
||||
prologue: function(self: Builder, prologue: function()): Builder
|
||||
epilogue: function(self: Builder, epilogue: function()): Builder
|
||||
prologue: function(self: Builder, prologue: function(...: any)): Builder
|
||||
epilogue: function(self: Builder, epilogue: function(...: any)): Builder
|
||||
|
||||
destruction_policy: function(self: Builder, destruction_policy: Id): Builder
|
||||
end
|
||||
@@ -102,6 +103,7 @@
|
||||
|
||||
INCLUDES: Fragment
|
||||
EXCLUDES: Fragment
|
||||
VARIANTS: Fragment
|
||||
REQUIRES: Fragment
|
||||
|
||||
ON_SET: Fragment
|
||||
@@ -127,6 +129,7 @@
|
||||
unpack: function(id: Id): integer, integer
|
||||
|
||||
defer: function(): boolean
|
||||
depth: function(): integer
|
||||
commit: function(): boolean
|
||||
cancel: function(): boolean
|
||||
|
||||
@@ -170,6 +173,7 @@
|
||||
locate: function(entity: Entity): Chunk | nil, integer
|
||||
|
||||
process: function(...: System)
|
||||
process_with: function(system: System, ...: any)
|
||||
|
||||
debug_mode: function(yesno: boolean)
|
||||
collect_garbage: function()
|
||||
|
||||
1474
evolved.lua
1474
evolved.lua
File diff suppressed because it is too large
Load Diff
@@ -12,10 +12,6 @@ local STAGES = {
|
||||
:build(),
|
||||
}
|
||||
|
||||
local UNIFORMS = {
|
||||
DELTA_TIME = 1.0 / 60.0,
|
||||
}
|
||||
|
||||
local FRAGMENTS = {
|
||||
POSITION_X = evolved.builder()
|
||||
:name('FRAGMENTS.POSITION_X')
|
||||
@@ -82,8 +78,7 @@ evolved.builder()
|
||||
:group(STAGES.ON_UPDATE)
|
||||
:include(FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y)
|
||||
:include(FRAGMENTS.VELOCITY_X, FRAGMENTS.VELOCITY_Y)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local delta_time = UNIFORMS.DELTA_TIME
|
||||
:execute(function(chunk, _, entity_count, delta_time)
|
||||
local screen_width, screen_height = love.graphics.getDimensions()
|
||||
|
||||
---@type number[], number[]
|
||||
@@ -156,8 +151,7 @@ end
|
||||
|
||||
---@type love.update
|
||||
function love.update(dt)
|
||||
UNIFORMS.DELTA_TIME = dt
|
||||
evolved.process(STAGES.ON_UPDATE)
|
||||
evolved.process_with(STAGES.ON_UPDATE, dt)
|
||||
end
|
||||
|
||||
---@type love.draw
|
||||
|
||||
34
rockspecs/evolved.lua-1.6.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.6.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "evolved.lua"
|
||||
version = "1.6.0-0"
|
||||
source = {
|
||||
url = "git://github.com/BlackMATov/evolved.lua",
|
||||
tag = "v1.6.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",
|
||||
}
|
||||
}
|
||||
34
rockspecs/evolved.lua-1.7.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.7.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "evolved.lua"
|
||||
version = "1.7.0-0"
|
||||
source = {
|
||||
url = "git://github.com/BlackMATov/evolved.lua",
|
||||
tag = "v1.7.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