├── src
├── cs
│ ├── Directory.Build.targets
│ ├── production
│ │ ├── Directory.Build.props
│ │ ├── Directory.Build.targets
│ │ ├── Flecs.Core
│ │ │ ├── _README_PACKAGE.md
│ │ │ ├── IEcsComponent.cs
│ │ │ ├── CallbackIterator.cs
│ │ │ ├── Component
│ │ │ │ ├── CallbackComponentCopy.cs
│ │ │ │ ├── CallbackComponentMove.cs
│ │ │ │ ├── CallbackComponentConstructor.cs
│ │ │ │ ├── CallbackComponentDeconstructor.cs
│ │ │ │ ├── IComponent.cs
│ │ │ │ ├── ComponentDeconstructorContext.cs
│ │ │ │ ├── ComponentConstructorContext.cs
│ │ │ │ ├── ComponentCopyContext.cs
│ │ │ │ ├── ComponentMoveContext.cs
│ │ │ │ └── ComponentHooks.cs
│ │ │ ├── ITag.cs
│ │ │ ├── Flecs.Core.csproj.DotSettings
│ │ │ ├── Pair.cs
│ │ │ ├── FlecsException.cs
│ │ │ ├── IteratorEvent.cs
│ │ │ ├── Table.cs
│ │ │ ├── EntityType.cs
│ │ │ ├── IdentifiersEnumerable.cs
│ │ │ ├── Expressions
│ │ │ │ ├── Expression.cs
│ │ │ │ └── TermBuilder.cs
│ │ │ ├── Properties
│ │ │ │ └── AdditionalCodeAnalysisSuppressions.cs
│ │ │ ├── Flecs.Core.csproj
│ │ │ ├── IdentifiersEnumerator.cs
│ │ │ ├── Identifier.cs
│ │ │ ├── EntityIterator.cs
│ │ │ ├── Iterator.cs
│ │ │ ├── CallbacksHelper.cs
│ │ │ ├── World.cs
│ │ │ └── Entity.cs
│ │ ├── Interop.Flecs.Core
│ │ │ ├── _README_PACKAGE.md
│ │ │ ├── Generated
│ │ │ │ └── AssemblyAttributes.gen.cs
│ │ │ ├── Interop.Flecs.Core.csproj
│ │ │ └── PInvoke.Extensions.cs
│ │ ├── Interop.Flecs.runtime.osx
│ │ │ ├── _README_PACKAGE.md
│ │ │ └── Interop.Flecs.runtime.osx.csproj
│ │ ├── Interop.Flecs.runtime.win-x64
│ │ │ ├── _README_PACKAGE.md
│ │ │ └── Interop.Flecs.runtime.win-x64.csproj
│ │ ├── Interop.Flecs.runtime.linux-x64
│ │ │ ├── _README_PACKAGE.md
│ │ │ └── Interop.Flecs.runtime.linux-x64.csproj
│ │ ├── Interop.Flecs.Unity
│ │ │ ├── Generated
│ │ │ │ └── AssemblyAttributes.gen.cs
│ │ │ └── Interop.Flecs.Unity.csproj
│ │ └── Flecs.Unity
│ │ │ └── Flecs.Unity.csproj
│ ├── examples
│ │ ├── Directory.Build.targets
│ │ ├── queries
│ │ │ ├── Directory.Build.props
│ │ │ ├── Directory.Build.targets
│ │ │ └── Flecs.Examples.Queries.OptionalOr
│ │ │ │ ├── Flecs.Examples.Queries.OptionalOr.csproj
│ │ │ │ └── Program.cs
│ │ ├── systems
│ │ │ ├── Directory.Build.props
│ │ │ ├── Directory.Build.targets
│ │ │ └── Flecs.Examples.Systems.CustomPhase
│ │ │ │ ├── Flecs.Examples.Systems.CustomPhase.csproj
│ │ │ │ └── Program.cs
│ │ ├── entities
│ │ │ ├── Directory.Build.props
│ │ │ ├── Directory.Build.targets
│ │ │ ├── Flecs.Examples.Entities.RelationBasic
│ │ │ │ ├── Flecs.Examples.Entities.RelationBasic.csproj
│ │ │ │ └── Program.cs
│ │ │ ├── Flecs.Examples.Entities.RelationComponents
│ │ │ │ ├── Flecs.Examples.Entities.RelationComponents.csproj
│ │ │ │ └── Program.cs
│ │ │ ├── Flecs.Examples.Entities.Basics
│ │ │ │ ├── Flecs.Examples.Entities.Basics.csproj
│ │ │ │ └── Program.cs
│ │ │ ├── Flecs.Examples.Entities.Hooks
│ │ │ │ ├── Flecs.Examples.Entities.Hooks.csproj
│ │ │ │ └── Program.cs
│ │ │ ├── Flecs.Examples.Entities.Prefab
│ │ │ │ ├── Flecs.Examples.Entities.Prefab.csproj
│ │ │ │ └── Program.cs
│ │ │ ├── Flecs.Examples.Entities.Hierarchy
│ │ │ │ ├── Flecs.Examples.Entities.Hierarchy.csproj
│ │ │ │ └── Program.cs
│ │ │ ├── Flecs.Examples.Entities.PrefabSlot
│ │ │ │ ├── Flecs.Examples.Entities.PrefabSlot.csproj
│ │ │ │ └── Program.cs
│ │ │ └── Flecs.Examples.Entities.IterateComponents
│ │ │ │ ├── Flecs.Examples.Entities.IterateComponents.csproj
│ │ │ │ └── Program.cs
│ │ ├── Flecs.Examples.HelloWorld
│ │ │ ├── Flecs.Examples.HelloWorld.csproj
│ │ │ └── Program.cs
│ │ └── Directory.Build.props
│ ├── Flecs.sln.DotSettings
│ ├── Flecs.sln.DotSettings.user
│ ├── .globalconfig
│ ├── Directory.Build.props
│ ├── StyleCop.json
│ └── Flecs.sln
└── c
│ └── production
│ └── flecs
│ ├── src
│ └── flecs_pinvoke.c
│ ├── CMakeLists.txt
│ └── include
│ ├── flecs_pinvoke.h
│ └── pinvoke.h
├── .gitmodules
├── bindgen
├── config-build-c-library.json
├── config-extract-macos.json
├── config-extract-windows.json
├── config-extract-linux.json
├── merge.sh
├── generate.sh
├── config-generate-cs-core.json
├── config-generate-cs-unity.json
├── appsettings.json
└── extract.sh
├── .github
├── dependabot.yml
└── workflows
│ ├── pull-release.yml
│ ├── commit.yml
│ ├── release.yml
│ ├── build.yml
│ └── bindgen.yml
├── .gitignore
├── library.sh
├── LICENSE
├── .editorconfig
└── README.md
/src/cs/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/c/production/flecs/src/flecs_pinvoke.c:
--------------------------------------------------------------------------------
1 | #include "flecs_pinvoke.h"
2 | #include "flecs.h"
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "ext/flecs"]
2 | path = ext/flecs
3 | url = https://github.com/SanderMertens/flecs
--------------------------------------------------------------------------------
/src/cs/production/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/examples/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/examples/queries/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/examples/systems/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/production/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/examples/queries/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/examples/systems/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/_README_PACKAGE.md:
--------------------------------------------------------------------------------
1 |
2 | # flecs_hub.Flecs
3 |
4 | Automatically updated C# bindings for https://github.com/SanderMertens/flecs.
--------------------------------------------------------------------------------
/bindgen/config-build-c-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "cMakeDirectoryPath": "../src/c/production/flecs",
3 | "outputDirectoryPath": "../lib",
4 | "deleteBuildFiles": true
5 | }
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.Core/_README_PACKAGE.md:
--------------------------------------------------------------------------------
1 |
2 | # flecs_hub.Interop.Flecs.Core
3 |
4 | Automatically updated C# bindings for https://github.com/SanderMertens/flecs.
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "gitsubmodule"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 | time: "00:15" # 8:15pm EDT
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.runtime.osx/_README_PACKAGE.md:
--------------------------------------------------------------------------------
1 |
2 | # flecs_hub.Interop.Flecs.runtime.osx
3 |
4 | Automatically updated C# bindings for https://github.com/flecs-hub/flecs-cs.
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.runtime.win-x64/_README_PACKAGE.md:
--------------------------------------------------------------------------------
1 |
2 | # flecs_hub.Interop.Flecs.runtime.win-x64
3 |
4 | Automatically updated C# bindings for https://github.com/flecs-hub/flecs-cs.
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.runtime.linux-x64/_README_PACKAGE.md:
--------------------------------------------------------------------------------
1 |
2 | # flecs_hub.Interop.Flecs.runtime.linux-x64
3 |
4 | Automatically updated C# bindings for https://github.com/flecs-hub/flecs-cs.
--------------------------------------------------------------------------------
/bindgen/config-extract-macos.json:
--------------------------------------------------------------------------------
1 | {
2 | "inputFilePath": "../src/c/production/flecs/include/flecs_pinvoke.h",
3 | "userIncludeDirectories": [
4 | "../ext/flecs/include"
5 | ],
6 | "platforms": {
7 | "aarch64-apple-darwin": {},
8 | "x86_64-apple-darwin": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/bindgen/config-extract-windows.json:
--------------------------------------------------------------------------------
1 | {
2 | "inputFilePath": "../src/c/production/flecs/include/flecs_pinvoke.h",
3 | "userIncludeDirectories": [
4 | "../ext/flecs/include"
5 | ],
6 | "platforms": {
7 | "x86_64-pc-windows-msvc": {},
8 | "aarch64-pc-windows-msvc": {}
9 | }
10 | }
--------------------------------------------------------------------------------
/bindgen/config-extract-linux.json:
--------------------------------------------------------------------------------
1 | {
2 | "inputFilePath": "../src/c/production/flecs/include/flecs_pinvoke.h",
3 | "userIncludeDirectories": [
4 | "../ext/flecs/include"
5 | ],
6 | "platforms": {
7 | "x86_64-unknown-linux-gnu": {},
8 | "aarch64-unknown-linux-gnu": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/IEcsComponent.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs;
5 |
6 | public interface IEcsComponent
7 | {
8 | }
9 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/CallbackIterator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs;
5 |
6 | public delegate void CallbackIterator(Iterator iterator);
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # JetBrains
2 | .idea/
3 |
4 | # VisualStudio
5 | .suo
6 | .vs/
7 |
8 | # C# build artifacts
9 | bin/
10 | obj/
11 | /artifacts/
12 |
13 | # C# packages
14 | /nupkg/
15 |
16 | # Native libraries
17 | /lib/
18 |
19 | # C2CS
20 | /bindgen/ast/
21 | /bindgen/x-ast/
22 |
23 | # macOS
24 | .DS_store
25 |
26 | # scripts
27 | /build
28 | /ext/scripts
29 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/CallbackComponentCopy.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs;
5 |
6 | public delegate void CallbackComponentCopy(ref ComponentCopyContext context);
7 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/CallbackComponentMove.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs;
5 |
6 | public delegate void CallbackComponentMove(ref ComponentMoveContext context);
7 |
--------------------------------------------------------------------------------
/src/cs/examples/queries/Flecs.Examples.Queries.OptionalOr/Flecs.Examples.Queries.OptionalOr.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net7.0
6 | true
7 | true
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/cs/examples/systems/Flecs.Examples.Systems.CustomPhase/Flecs.Examples.Systems.CustomPhase.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net7.0
6 | true
7 | true
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.RelationBasic/Flecs.Examples.Entities.RelationBasic.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net7.0
6 | true
7 | true
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/CallbackComponentConstructor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs;
5 |
6 | public delegate void CallbackComponentConstructor(ref ComponentConstructorContext context);
7 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/CallbackComponentDeconstructor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs;
5 |
6 | public delegate void CallbackComponentDeconstructor(ref ComponentDeconstructorContext context);
7 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.RelationComponents/Flecs.Examples.Entities.RelationComponents.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net7.0
6 | true
7 | true
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/ITag.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs;
5 |
6 | ///
7 | /// Marker interface for a Flecs tag.
8 | ///
9 | public interface ITag : IEcsComponent
10 | {
11 | }
12 |
--------------------------------------------------------------------------------
/src/cs/Flecs.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/src/cs/examples/Flecs.Examples.HelloWorld/Flecs.Examples.HelloWorld.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Exe
6 | net7.0
7 | true
8 | true
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/bindgen/merge.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
3 |
4 | if ! [[ -x "$(command -v castffi)" ]]; then
5 | echo "Error: 'castffi' is not installed. Please visit https://github.com/bottlenoselabs/CAstFfi for instructions to install the CAstFfi tool." >&2
6 | exit 1
7 | fi
8 |
9 | castffi merge --inputDirectoryPath "$DIRECTORY/ast" --outputFilePath "$DIRECTORY/x-ast/ast-cross-platform.json"
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.Basics/Flecs.Examples.Entities.Basics.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Exe
6 | net7.0
7 | true
8 | true
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.Hooks/Flecs.Examples.Entities.Hooks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Exe
6 | net7.0
7 | true
8 | true
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.Prefab/Flecs.Examples.Entities.Prefab.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Exe
6 | net7.0
7 | true
8 | true
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/cs/Flecs.sln.DotSettings.user:
--------------------------------------------------------------------------------
1 |
2 | VISIBLE_FILES
3 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.Hierarchy/Flecs.Examples.Entities.Hierarchy.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Exe
6 | net7.0
7 | true
8 | true
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.PrefabSlot/Flecs.Examples.Entities.PrefabSlot.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Exe
6 | net7.0
7 | true
8 | true
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/bindgen/generate.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
3 |
4 | if ! [[ -x "$(command -v c2cs)" ]]; then
5 | echo "Error: 'c2cs' is not installed. Please visit https://github.com/bottlenoselabs/C2CS for instructions to install the C2CS tool." >&2
6 | exit 1
7 | fi
8 |
9 | c2cs generate --config "$DIRECTORY/config-generate-cs-core.json"
10 | c2cs generate --config "$DIRECTORY/config-generate-cs-unity.json"
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.IterateComponents/Flecs.Examples.Entities.IterateComponents.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Exe
6 | net7.0
7 | true
8 | true
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/cs/.globalconfig:
--------------------------------------------------------------------------------
1 | # NOTE: Requires .NET 5 SDK (VS2019 16.8 or later)
2 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/configuration-files#global-analyzerconfig
3 | is_global = true
4 |
5 | dotnet_diagnostic.CA1815.severity = none
6 |
7 | # StyleCop Rules
8 | ## Description: StyleCop code analysis rules for C# projects.
9 | dotnet_diagnostic.SA1401.severity = none
10 | dotnet_diagnostic.SA1600.severity = none
11 | dotnet_diagnostic.SA1649.severity = none
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Flecs.Core.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/bindgen/config-generate-cs-core.json:
--------------------------------------------------------------------------------
1 | {
2 | "inputFilePath": "./x-ast/ast-cross-platform.json",
3 | "outputFileDirectory": "./../src/cs/production/Interop.Flecs.Core/Generated",
4 | "namespaceName": "flecs_hub.Interop.Flecs",
5 | "className": "PInvoke",
6 | "libraryName": "flecs",
7 | "isEnabledGeneratingRuntimeCode": false,
8 | "isEnabledLibraryImport": true,
9 | "isEnabledFunctionPointers": true,
10 | "isEnabledFileScopedNamespace": true
11 | }
12 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/IComponent.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Diagnostics.CodeAnalysis;
5 |
6 | namespace Flecs;
7 |
8 | ///
9 | /// Marker interface for a Flecs component.
10 | ///
11 | public interface IComponent : IEcsComponent
12 | {
13 | }
14 |
--------------------------------------------------------------------------------
/bindgen/config-generate-cs-unity.json:
--------------------------------------------------------------------------------
1 | {
2 | "inputFilePath": "./x-ast/ast-cross-platform.json",
3 | "outputFileDirectory": "./../src/cs/production/Interop.Flecs.Unity/Generated",
4 | "namespaceName": "flecs_hub.Interop.Flecs",
5 | "className": "PInvoke",
6 | "libraryName": "flecs",
7 | "isEnabledGeneratingRuntimeCode": false,
8 | "isEnabledLibraryImport": false,
9 | "isEnabledFunctionPointers": false,
10 | "isEnabledFileScopedNamespace": false
11 | }
12 |
--------------------------------------------------------------------------------
/bindgen/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "Console": {
4 | "LogLevel": {
5 | "Default": "Warning",
6 | "CAstFfi": "Debug",
7 | "C2CS": "Debug"
8 | },
9 | "FormatterOptions": {
10 | "ColorBehavior": "Enabled",
11 | "SingleLine": true,
12 | "IncludeScopes": true,
13 | "TimestampFormat": "yyyy-dd-MM HH:mm:ss ",
14 | "UseUtcTimestamp": true
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Pair.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs;
5 |
6 | public readonly struct Pair
7 | {
8 | public readonly Entity First;
9 | public readonly Entity Second;
10 |
11 | internal Pair(Entity first, Entity second)
12 | {
13 | First = first;
14 | Second = second;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/library.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
3 |
4 | if ! [[ -x "$(command -v c2cs)" ]]; then
5 | echo "Error: 'c2cs' is not installed. The C2CS tool is used to generate a C shared library for the purposes of P/Invoke with C#. Please visit https://github.com/bottlenoselabs/C2CS for instructions to install the C2CS tool." >&2
6 | exit 1
7 | fi
8 |
9 | c2cs library --config "$DIRECTORY/bindgen/config-build-c-library.json"
10 |
11 | if [[ -z "$1" ]]; then
12 | read
13 | fi
--------------------------------------------------------------------------------
/.github/workflows/pull-release.yml:
--------------------------------------------------------------------------------
1 | name: "Pull request"
2 |
3 | on:
4 | pull_request:
5 | types: [assigned, opened, synchronize, reopened]
6 | paths-ignore:
7 | - '**.md'
8 |
9 | jobs:
10 |
11 | bindgen-job:
12 | uses: "./.github/workflows/bindgen.yml"
13 |
14 | build-job:
15 | needs: [bindgen-job]
16 | if: always()
17 | uses: "./.github/workflows/build.yml"
18 |
19 | commit-job:
20 | needs: [bindgen-job, build-job]
21 | if: github.actor == 'dependabot[bot]'
22 | uses: "./.github/workflows/commit.yml"
23 |
--------------------------------------------------------------------------------
/src/c/production/flecs/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.16)
2 |
3 | project(flecs C)
4 | set(CMAKE_C_STANDARD 11)
5 |
6 | get_filename_component(FLECS_DIRECTORY_PATH "../../../../ext/flecs" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
7 | file(GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c;${FLECS_DIRECTORY_PATH}/src/*.c)
8 |
9 | include_directories(flecs PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${FLECS_DIRECTORY_PATH}/include)
10 |
11 | add_library(flecs SHARED ${SRC})
12 |
13 | if (WIN32)
14 | target_link_libraries(flecs wsock32 ws2_32)
15 | endif()
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/FlecsException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 |
6 | namespace Flecs;
7 |
8 | public class FlecsException : Exception
9 | {
10 | public FlecsException()
11 | {
12 | }
13 |
14 | public FlecsException(string message)
15 | : base(message)
16 | {
17 | }
18 |
19 | public FlecsException(string message, Exception innerException)
20 | : base(message, innerException)
21 | {
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/cs/examples/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
10 |
12 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/IteratorEvent.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using JetBrains.Annotations;
5 | using static flecs_hub.Interop.Flecs.PInvoke;
6 |
7 | namespace Flecs;
8 |
9 | [PublicAPI]
10 | public readonly unsafe struct IteratorEvent
11 | {
12 | internal readonly World World;
13 | internal readonly ecs_entity_t Handle;
14 |
15 | internal IteratorEvent(World world, ecs_entity_t handle)
16 | {
17 | World = world;
18 | Handle = handle;
19 | }
20 |
21 | public string Name()
22 | {
23 | var result = ecs_get_name(World.Handle, Handle);
24 | return result.ToString();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/ComponentDeconstructorContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | namespace Flecs;
7 |
8 | public readonly unsafe struct ComponentDeconstructorContext
9 | {
10 | private readonly void* _pointer;
11 | private readonly int _count;
12 |
13 | public ComponentDeconstructorContext(void* pointer, int count)
14 | {
15 | _pointer = pointer;
16 | _count = count;
17 | }
18 |
19 | public ref TComponent Get()
20 | where TComponent : unmanaged, IComponent
21 | {
22 | return ref Unsafe.AsRef(_pointer);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/ComponentConstructorContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Diagnostics.CodeAnalysis;
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace Flecs;
8 |
9 | public readonly unsafe struct ComponentConstructorContext
10 | {
11 | private readonly void* _pointer;
12 | private readonly int _count;
13 |
14 | public ComponentConstructorContext(void* pointer, int count)
15 | {
16 | _pointer = pointer;
17 | _count = count;
18 | }
19 |
20 | public ref TComponent Get()
21 | where TComponent : unmanaged, IComponent
22 | {
23 | return ref Unsafe.AsRef(_pointer);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Table.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 | using JetBrains.Annotations;
6 | using static flecs_hub.Interop.Flecs.PInvoke;
7 |
8 | namespace Flecs;
9 |
10 | [PublicAPI]
11 | public readonly unsafe struct Table
12 | {
13 | public readonly ecs_table_t* Handle;
14 | private readonly ecs_world_t* _worldHandle;
15 |
16 | internal Table(ecs_world_t* world, ecs_table_t* handle)
17 | {
18 | _worldHandle = world;
19 | Handle = handle;
20 | }
21 |
22 | public string String()
23 | {
24 | var cString = ecs_table_str(_worldHandle, Handle);
25 | var result = Marshal.PtrToStringAnsi(cString)!;
26 | Marshal.FreeHGlobal(cString);
27 | return result;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/cs/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), .gitignore))/artifacts
7 |
8 |
9 |
10 |
11 |
12 | all
13 |
14 |
15 | all
16 | runtime; build; native; contentfiles; analyzers; buildtransitive
17 |
18 |
19 |
20 |
21 |
22 | $(MSBuildThisFileDirectory)StyleCop.json
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.Core/Generated/AssemblyAttributes.gen.cs:
--------------------------------------------------------------------------------
1 | // To disable generating this file set `isEnabledGenerateAssemblyAttributes` to `false` in the config file for generating C# code.
2 | //
3 | // This code was generated by the following tool on 2023-09-05 00:24:37 GMT+00:00:
4 | // https://github.com/bottlenoselabs/c2cs (v6.1.3.0)
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
7 | //
8 | // ReSharper disable All
9 |
10 | #region Template
11 | #nullable enable
12 | #pragma warning disable CS1591
13 | #pragma warning disable CS8981
14 | using bottlenoselabs.C2CS.Runtime;
15 | using System;
16 | using System.Collections.Generic;
17 | using System.Globalization;
18 | using System.Runtime.InteropServices;
19 | using System.Runtime.CompilerServices;
20 | #endregion
21 |
22 | #if NET7_0_OR_GREATER
23 | [assembly: DisableRuntimeMarshalling]
24 | #endif
25 |
26 | [assembly: DefaultDllImportSearchPathsAttribute(DllImportSearchPath.SafeDirectories)]
27 |
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.Unity/Generated/AssemblyAttributes.gen.cs:
--------------------------------------------------------------------------------
1 | // To disable generating this file set `isEnabledGenerateAssemblyAttributes` to `false` in the config file for generating C# code.
2 | //
3 | // This code was generated by the following tool on 2023-09-05 00:24:52 GMT+00:00:
4 | // https://github.com/bottlenoselabs/c2cs (v6.1.3.0)
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
7 | //
8 | // ReSharper disable All
9 |
10 | #region Template
11 | #nullable enable
12 | #pragma warning disable CS1591
13 | #pragma warning disable CS8981
14 | using bottlenoselabs.C2CS.Runtime;
15 | using System;
16 | using System.Collections.Generic;
17 | using System.Globalization;
18 | using System.Runtime.InteropServices;
19 | using System.Runtime.CompilerServices;
20 | #endregion
21 |
22 | #if NET7_0_OR_GREATER
23 | [assembly: DisableRuntimeMarshalling]
24 | #endif
25 |
26 | [assembly: DefaultDllImportSearchPathsAttribute(DllImportSearchPath.SafeDirectories)]
27 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/EntityType.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 | using static flecs_hub.Interop.Flecs.PInvoke;
6 |
7 | namespace Flecs;
8 |
9 | public readonly unsafe struct EntityType
10 | {
11 | private readonly World _world;
12 | private readonly ecs_type_t* _handle;
13 |
14 | internal EntityType(World world, ecs_type_t* handle)
15 | {
16 | _handle = handle;
17 | _world = world;
18 | }
19 |
20 | public IdentifiersEnumerable Identifiers()
21 | {
22 | return new IdentifiersEnumerable(_world, _handle);
23 | }
24 |
25 | public string String()
26 | {
27 | var cString = ecs_type_str(_world.Handle, _handle);
28 | var result = Marshal.PtrToStringAnsi(cString.Pointer)!;
29 | Marshal.FreeHGlobal(cString.Pointer);
30 | return result;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/cs/StyleCop.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
3 | "settings": {
4 | "indentation": {
5 | "useTabs": false
6 | },
7 | "documentationRules": {
8 | "companyName": "Flecs Hub (https://github.com/flecs-hub)",
9 | "copyrightText": "Copyright (c) {companyName}. All rights reserved.\nLicensed under the {licenseName} license. See {licenseFile} file in the Git repository root directory for full license information.",
10 | "variables": {
11 | "licenseName": "MIT",
12 | "licenseFile": "LICENSE"
13 | },
14 | "xmlHeader": false,
15 | "documentInternalElements": false
16 | },
17 | "orderingRules": {
18 | "usingDirectivesPlacement": "outsideNamespace",
19 | "elementOrder": [
20 | "kind",
21 | "accessibility",
22 | "constant",
23 | "readonly"
24 | ]
25 | },
26 | "layoutRules": {
27 | "newlineAtEndOfFile": "require"
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Bottlenose Labs Inc. (https://github.com/bottlenoselabs)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/IdentifiersEnumerable.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Collections;
6 | using System.Collections.Generic;
7 | using JetBrains.Annotations;
8 | using static flecs_hub.Interop.Flecs.PInvoke;
9 |
10 | namespace Flecs;
11 |
12 | [PublicAPI]
13 | public readonly unsafe struct IdentifiersEnumerable : IEnumerable
14 | {
15 | private readonly IdentifiersEnumerator _enumerator;
16 |
17 | internal IdentifiersEnumerable(World world, ecs_type_t* type)
18 | {
19 | _enumerator = new IdentifiersEnumerator(world, type);
20 | }
21 |
22 | public IdentifiersEnumerator GetEnumerator()
23 | {
24 | // This method is duck-typed for usage in a `foreach`
25 | return _enumerator;
26 | }
27 |
28 | IEnumerator IEnumerable.GetEnumerator()
29 | {
30 | throw new InvalidOperationException();
31 | }
32 |
33 | IEnumerator IEnumerable.GetEnumerator()
34 | {
35 | throw new InvalidOperationException();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Expressions/Expression.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace Flecs;
11 |
12 | public class Expression
13 | {
14 | private World _world;
15 |
16 | public Expression(World world)
17 | {
18 | _world = world;
19 | }
20 |
21 | public TermBuilder Term()
22 | where T : unmanaged, IEcsComponent
23 | {
24 | var termBuilder = new TermBuilder(_world);
25 | termBuilder.First();
26 | return termBuilder;
27 | }
28 |
29 | public TermBuilder Term()
30 | where T1 : unmanaged, IEcsComponent
31 | where T2 : unmanaged, IEcsComponent
32 | {
33 | var termBuilder = new TermBuilder(_world);
34 | termBuilder.First();
35 | termBuilder.Second();
36 | return termBuilder;
37 | }
38 |
39 | public TermBuilder Term()
40 | {
41 | return new TermBuilder(_world);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/.github/workflows/commit.yml:
--------------------------------------------------------------------------------
1 | name: "Commit generated C# code"
2 |
3 | on:
4 | workflow_call:
5 |
6 | permissions: write-all
7 |
8 | jobs:
9 |
10 | commit-job:
11 | name: "Commit generated C# code"
12 | runs-on: ubuntu-latest
13 | if: github.actor == 'dependabot[bot]'
14 |
15 | steps:
16 | - name: "Clone Git repository"
17 | uses: actions/checkout@v2
18 | with:
19 | submodules: 'false'
20 |
21 | - name: "Download changes to commit: .NET 7+"
22 | uses: actions/download-artifact@v3
23 | with:
24 | name: "bindgen-cs-core"
25 | path: "./src/cs/production/Interop.Flecs.Core/Generated"
26 |
27 | - name: "Download changes to commit: Unity"
28 | uses: actions/download-artifact@v3
29 | with:
30 | name: "bindgen-cs-unity"
31 | path: "./src/cs/production/Interop.Flecs.Unity/Generated"
32 |
33 | - name: "Echo download path"
34 | run: echo ${{steps.download.outputs.download-path}}
35 |
36 | - name: "Add + commit + push (if necessary)"
37 | uses: EndBug/add-and-commit@v7
38 | with:
39 | author_name: 'lithiumtoast'
40 | author_email: '519592+lithiumtoast@users.noreply.github.com'
41 | message: "Update C# bindings"
42 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Properties/AdditionalCodeAnalysisSuppressions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Diagnostics.CodeAnalysis;
5 |
6 | [assembly: SuppressMessage(
7 | "Microsoft.Reliability",
8 | "CA2020:Prevent behavioral change",
9 | MessageId = "Prevent behavioral change caused by built-in operators of IntPtr/UIntPtr",
10 | Justification = "The new changes from .NET 6 to .NET 7 for IntPtr/UIntPtr are acceptable.")]
11 |
12 | [assembly: SuppressMessage(
13 | "Microsoft.Performance",
14 | "CA1815:Override equals and operator equals on value types",
15 | MessageId = "Override equals and operator equals on value types",
16 | Justification = "Any time we are using structs for Interop or are creating structs that wrap Interop structs we most definitely want them to be blittable to which rule this does not apply.")]
17 |
18 | [assembly: SuppressMessage(
19 | "Microsoft.Design",
20 | "CA1040:Avoid empty interfaces",
21 | MessageId = "Avoid empty interfaces",
22 | Justification = "We are using interfaces with generics for compile time markers; this is acceptable according to MSDN.")]
23 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Flecs.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net7.0
6 | true
7 | false
8 | enable
9 | flecs_hub.Flecs
10 |
11 |
12 |
13 |
14 | true
15 | flecs_hub.Flecs
16 | C# API for https://github.com/SanderMertens/flecs
17 | https://github.com/flecs_hub/flecs-cs
18 | MIT
19 |
20 |
21 |
22 | true
23 | /
24 | PreserveNewest
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Is this file the top-most EditorConfig file?
2 | root = true
3 |
4 | # Any and all files
5 | [*]
6 | charset = utf-8
7 | indent_style = space
8 | indent_size = 4
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | # C# files
13 | [*.cs]
14 | indent_style = space
15 |
16 | # Visual Studio Solution files
17 | [*.sln]
18 | indent_style = tab
19 |
20 | # Visual Studio XML project files
21 | [*.{csproj,vbproj,vcxproj.filters,proj,projitems,shproj}]
22 | indent_style = tab
23 | indent_size = 2
24 |
25 | # XML configuration files
26 | [*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}]
27 | indent_style = tab
28 | indent_size = 2
29 |
30 | # JSON files
31 | [*.{json,json5,webmanifest}]
32 | indent_style = space
33 | indent_size = 2
34 |
35 | # YAML files
36 | [*.{yml,yaml}]
37 | indent_style = space
38 | indent_size = 2
39 |
40 | # Markdown files
41 | [*.md]
42 | indent_style = space
43 | trim_trailing_whitespace = false
44 | indent_size = 4
45 |
46 | # Web files
47 | [*.{htm,html,js,jsm,ts,tsx,css,sass,scss,less,svg,vue}]
48 | indent_style = space
49 | indent_size = 2
50 |
51 | # Batch files
52 | [*.{cmd,bat}]
53 | indent_style = tab
54 | end_of_line = crlf
55 |
56 | # Bash files
57 | [*.sh]
58 | indent_style = tab
59 | end_of_line = lf
60 |
61 | # Makefiles
62 | [Makefile]
63 | indent_style = tab
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/ComponentCopyContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace Flecs;
8 |
9 | public readonly unsafe struct ComponentCopyContext
10 | {
11 | private readonly void* _destinationPointer;
12 | private readonly void* _sourcePointer;
13 | private readonly int _count;
14 |
15 | public IntPtr DestinationPointer => (IntPtr)_destinationPointer;
16 |
17 | public IntPtr SourcePointer => (IntPtr)_sourcePointer;
18 |
19 | public ComponentCopyContext(void* destinationPointer, void* sourcePointer, int count)
20 | {
21 | _destinationPointer = destinationPointer;
22 | _sourcePointer = sourcePointer;
23 | _count = count;
24 | }
25 |
26 | public ref TComponent GetDestination()
27 | where TComponent : unmanaged, IComponent
28 | {
29 | return ref Unsafe.AsRef(_destinationPointer);
30 | }
31 |
32 | public ref TComponent GetSource()
33 | where TComponent : unmanaged, IComponent
34 | {
35 | return ref Unsafe.AsRef(_sourcePointer);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/ComponentMoveContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace Flecs;
8 |
9 | public readonly unsafe struct ComponentMoveContext
10 | {
11 | private readonly void* _destinationPointer;
12 | private readonly void* _sourcePointer;
13 | private readonly int _count;
14 |
15 | public IntPtr DestinationPointer => (IntPtr)_destinationPointer;
16 |
17 | public IntPtr SourcePointer => (IntPtr)_sourcePointer;
18 |
19 | public ComponentMoveContext(void* destinationPointer, void* sourcePointer, int count)
20 | {
21 | _destinationPointer = destinationPointer;
22 | _sourcePointer = sourcePointer;
23 | _count = count;
24 | }
25 |
26 | public ref TComponent GetDestination()
27 | where TComponent : unmanaged, IComponent
28 | {
29 | return ref Unsafe.AsRef(_destinationPointer);
30 | }
31 |
32 | public ref TComponent GetSource()
33 | where TComponent : unmanaged, IComponent
34 | {
35 | return ref Unsafe.AsRef(_sourcePointer);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.Unity/Interop.Flecs.Unity.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | netstandard2.1
6 | disable
7 | true
8 | flecs_hub.Interop.Flecs
9 | false
10 | enable
11 | en
12 | false
13 | false
14 | $(NoWarn);CS8981;CA1016
15 |
16 |
17 |
18 |
19 | false
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | %(RecursiveDir)%(Filename)%(Extension)
30 | PreserveNewest
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.Core/Interop.Flecs.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net7.0
6 | enable
7 | true
8 | flecs_hub.Interop.Flecs
9 | false
10 | enable
11 | en
12 | $(NoWarn);CS8981
13 |
14 |
15 |
16 |
17 | true
18 | flecs_hub.Interop.Flecs
19 | C# interop bindings for https://github.com/SanderMertens/flecs
20 | https://github.com/flecs_hub/flecs-cs
21 | MIT
22 |
23 |
24 |
25 | true
26 | /
27 | PreserveNewest
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/IdentifiersEnumerator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Collections;
6 | using System.Collections.Generic;
7 | using static flecs_hub.Interop.Flecs.PInvoke;
8 |
9 | namespace Flecs;
10 |
11 | public unsafe struct IdentifiersEnumerator : IEnumerator
12 | {
13 | private readonly World _world;
14 | private int _index;
15 | private readonly ecs_type_t* _type;
16 |
17 | public Identifier Current { get; private set; }
18 |
19 | public IdentifiersEnumerator(World world, ecs_type_t* type)
20 | {
21 | _world = world;
22 | _type = type;
23 | _index = 0;
24 | Current = default;
25 | }
26 |
27 | public bool MoveNext()
28 | {
29 | if (_index >= _type->count)
30 | {
31 | return false;
32 | }
33 |
34 | var current = _type->array[_index++];
35 | Current = new Identifier(_world, current);
36 | return true;
37 | }
38 |
39 | public void Reset()
40 | {
41 | _index = 0;
42 | Current = default;
43 | }
44 |
45 | public void Dispose()
46 | {
47 | }
48 |
49 | object IEnumerator.Current => throw new InvalidOperationException();
50 | }
51 |
--------------------------------------------------------------------------------
/bindgen/extract.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
3 |
4 | function get_host_operating_system() {
5 | local UNAME_STRING="$(uname -a)"
6 | case "${UNAME_STRING}" in
7 | *Microsoft*) local HOST_OS="windows";;
8 | *microsoft*) local HOST_OS="windows";;
9 | Linux*) local HOST_OS="linux";;
10 | Darwin*) local HOST_OS="macos";;
11 | CYGWIN*) local HOST_OS="linux";;
12 | MINGW*) local HOST_OS="windows";;
13 | *Msys) local HOST_OS="windows";;
14 | *) local HOST_OS="UNKNOWN:${UNAME_STRING}"
15 | esac
16 | echo "$HOST_OS"
17 | return 0
18 | }
19 |
20 | OS="$(get_host_operating_system)"
21 |
22 | if [[ "$OS" == "windows" ]]; then
23 | CASTFFI_CONFIG_FILE_PATH="$DIRECTORY/config-extract-windows.json"
24 | elif [[ "$OS" == "macos" ]]; then
25 | CASTFFI_CONFIG_FILE_PATH="$DIRECTORY/config-extract-macos.json"
26 | elif [[ "$OS" == "linux" ]]; then
27 | CASTFFI_CONFIG_FILE_PATH="$DIRECTORY/config-extract-linux.json"
28 | else
29 | echo "Error: Unknown operating system '$OS'" >&2
30 | exit 1
31 | fi
32 |
33 | if ! [[ -x "$(command -v castffi)" ]]; then
34 | echo "Error: 'castffi' is not installed. Please visit https://github.com/bottlenoselabs/CAstFfi for instructions to install the CAstFfi tool." >&2
35 | exit 1
36 | fi
37 |
38 | castffi extract --config "$CASTFFI_CONFIG_FILE_PATH"
39 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Unity/Flecs.Unity.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | netstandard2.1
6 | disable
7 | enable
8 | $(DefineConstants);UNITY_5_3_OR_NEWER
9 | $(NoWarn);CA1016
10 | flecs_hub.Flecs
11 | false
12 | false
13 | $(NoWarn);CA1016
14 |
15 |
16 |
17 |
18 | false
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | %(RecursiveDir)%(Filename)%(Extension)
36 | PreserveNewest
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/cs/examples/systems/Flecs.Examples.Systems.CustomPhase/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using static flecs_hub.Interop.Flecs.PInvoke;
5 |
6 | namespace Flecs.Examples.Systems.CustomPhase;
7 |
8 | #pragma warning disable CS0649
9 |
10 | internal static class Program
11 | {
12 | internal struct Position : IComponent
13 | {
14 | public float X;
15 | public float Y;
16 | }
17 |
18 | private static int Main(string[] args)
19 | {
20 | var world = new World(args);
21 |
22 | var physics = world.CreateEntity("physics");
23 | physics.Add(world.EcsPhase);
24 | physics.DependsOn(world.EcsDependsOn);
25 |
26 | var collision = world.CreateEntity("collision");
27 | collision.Add(world.EcsPhase);
28 | collision.DependsOn(physics);
29 |
30 | world.RegisterSystem(System1, physics, string.Empty);
31 | world.RegisterSystem(System2, collision, string.Empty);
32 | world.RegisterSystem(System3, EcsOnUpdate, string.Empty);
33 |
34 | world.Progress(0);
35 |
36 | return world.Fini();
37 | }
38 |
39 | private static void System1(Iterator iterator)
40 | {
41 | Console.WriteLine("Sys1: Physics < OnUpdate");
42 | }
43 |
44 | private static void System2(Iterator iterator)
45 | {
46 | Console.WriteLine("Sys2: Collision < Physics < OnUpdate");
47 | }
48 |
49 | private static void System3(Iterator iterator)
50 | {
51 | Console.WriteLine("Sys3 OnUpdate");
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Identifier.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 | using static flecs_hub.Interop.Flecs.PInvoke;
6 |
7 | namespace Flecs;
8 |
9 | public readonly unsafe struct Identifier
10 | {
11 | internal readonly World World;
12 | internal readonly ecs_id_t Handle;
13 |
14 | internal Identifier(World world, ecs_id_t handle)
15 | {
16 | World = world;
17 | Handle = handle;
18 | }
19 |
20 | public bool IsPair => ecs_id_is_pair(Handle);
21 |
22 | public string String()
23 | {
24 | var cString = ecs_id_str(World.Handle, Handle);
25 | var result = Marshal.PtrToStringAnsi(cString.Pointer)!;
26 | Marshal.FreeHGlobal(cString.Pointer);
27 | return result;
28 | }
29 |
30 | public string RoleString()
31 | {
32 | var id = default(ecs_id_t);
33 | id.Data = Handle.Data & ECS_ID_FLAGS_MASK;
34 | var cString = ecs_id_flag_str(id);
35 | var result = Marshal.PtrToStringAnsi(cString.Pointer)!;
36 | return result;
37 | }
38 |
39 | public Pair AsPair()
40 | {
41 | var first = ecs_pair_first(World.Handle, Handle);
42 | var firstEntity = new Entity(World, first);
43 | var second = ecs_pair_second(World.Handle, Handle);
44 | var secondEntity = new Entity(World, second);
45 | return new Pair(firstEntity, secondEntity);
46 | }
47 |
48 | public Entity AsComponent()
49 | {
50 | var value = Handle.Data & ECS_COMPONENT_MASK;
51 | return new Entity(World, *(ecs_entity_t*)&value);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/EntityIterator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Runtime.CompilerServices;
6 | using JetBrains.Annotations;
7 | using static flecs_hub.Interop.Flecs.PInvoke;
8 |
9 | namespace Flecs;
10 |
11 | [PublicAPI]
12 | public readonly unsafe struct EntityIterator
13 | {
14 | internal readonly ecs_iter_t Handle;
15 | private readonly ecs_world_t* _world;
16 |
17 | public int Count => Handle.count;
18 |
19 | internal EntityIterator(World world, ecs_iter_t it)
20 | {
21 | _world = world.Handle;
22 | Handle = it;
23 | }
24 |
25 | public float DeltaTime() => Handle.delta_time;
26 |
27 | public float DeltaSystemTime() => Handle.delta_system_time;
28 |
29 | public bool HasNext()
30 | {
31 | fixed (EntityIterator* @this = &this)
32 | {
33 | var handlePointer = &@this->Handle;
34 | var result = ecs_term_next(handlePointer);
35 | return result;
36 | }
37 | }
38 |
39 | public Span Field(int index)
40 | {
41 | fixed (EntityIterator* @this = &this)
42 | {
43 | var handlePointer = &@this->Handle;
44 | var structSize = Unsafe.SizeOf();
45 | var pointer = ecs_field_w_size(handlePointer, (ulong)structSize, index);
46 | return new Span(pointer, Handle.count);
47 | }
48 | }
49 |
50 | public Entity Entity(int index)
51 | {
52 | var world = World.Pointers[(IntPtr)_world];
53 | var result = new Entity(world, Handle.entities[index]);
54 | return result;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/c/production/flecs/include/flecs_pinvoke.h:
--------------------------------------------------------------------------------
1 | #include "pinvoke.h"
2 | #include "flecs.h"
3 |
4 | // Roles
5 | PINVOKE_API ecs_id_t pinvoke_ECS_PAIR()
6 | {
7 | return ECS_PAIR;
8 | }
9 |
10 | PINVOKE_API ecs_id_t pinvoke_ECS_OVERRIDE()
11 | {
12 | return ECS_OVERRIDE;
13 | }
14 |
15 | // Relationships
16 | PINVOKE_API ecs_entity_t pinvoke_EcsIsA()
17 | {
18 | return EcsIsA;
19 | }
20 |
21 | PINVOKE_API ecs_entity_t pinvoke_EcsDependsOn()
22 | {
23 | return EcsDependsOn;
24 | }
25 |
26 | PINVOKE_API ecs_entity_t pinvoke_EcsChildOf()
27 | {
28 | return EcsChildOf;
29 | }
30 |
31 | PINVOKE_API ecs_entity_t pinvoke_EcsSlotOf()
32 | {
33 | return EcsSlotOf;
34 | }
35 |
36 | // Entity tags
37 | PINVOKE_API ecs_entity_t pinvoke_EcsPrefab()
38 | {
39 | return EcsPrefab;
40 | }
41 |
42 | // System tags
43 | PINVOKE_API ecs_entity_t pinvoke_EcsPreFrame()
44 | {
45 | return EcsPreFrame;
46 | }
47 |
48 | PINVOKE_API ecs_entity_t pinvoke_EcsOnLoad()
49 | {
50 | return EcsOnLoad;
51 | }
52 |
53 | PINVOKE_API ecs_entity_t pinvoke_EcsPostLoad()
54 | {
55 | return EcsPostLoad;
56 | }
57 |
58 | PINVOKE_API ecs_entity_t pinvoke_EcsPreUpdate()
59 | {
60 | return EcsPreUpdate;
61 | }
62 |
63 | PINVOKE_API ecs_entity_t pinvoke_EcsOnUpdate()
64 | {
65 | return EcsOnUpdate;
66 | }
67 |
68 | PINVOKE_API ecs_entity_t pinvoke_EcsOnValidate()
69 | {
70 | return EcsOnValidate;
71 | }
72 |
73 | PINVOKE_API ecs_entity_t pinvoke_EcsPostUpdate()
74 | {
75 | return EcsPostUpdate;
76 | }
77 |
78 | PINVOKE_API ecs_entity_t pinvoke_EcsPreStore()
79 | {
80 | return EcsPreStore;
81 | }
82 |
83 | PINVOKE_API ecs_entity_t pinvoke_EcsOnStore()
84 | {
85 | return EcsOnStore;
86 | }
87 |
88 | PINVOKE_API ecs_entity_t pinvoke_EcsPostFrame()
89 | {
90 | return EcsPostFrame;
91 | }
92 |
93 | PINVOKE_API ecs_entity_t pinvoke_EcsPhase()
94 | {
95 | return EcsPhase;
96 | }
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.runtime.osx/Interop.Flecs.runtime.osx.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | netstandard1.0
6 | false
7 | disable
8 | true
9 |
10 |
11 |
12 |
13 | true
14 | flecs_hub.Interop.Flecs.runtime.osx
15 |
16 | macOS x64/arm64 native libraries for the `flecs_hub.Interop.Flecs` package.
17 |
18 | https://github.com/flecs-hub/flecs-cs
19 | MIT
20 | _README_PACKAGE.md
21 | true
22 | true
23 | false
24 | false
25 |
26 |
27 |
28 | true
29 | /
30 | PreserveNewest
31 |
32 |
33 |
34 |
35 |
36 |
37 | %(Filename)%(Extension)
38 | runtimes/osx/native/%(Filename)%(Extension)
39 | true
40 | PreserveNewest
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.runtime.win-x64/Interop.Flecs.runtime.win-x64.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | netstandard1.0
6 | false
7 | disable
8 | true
9 |
10 |
11 |
12 |
13 | true
14 | flecs_hub.Interop.Flecs.runtime.win-x64
15 |
16 | Windows x64 native libraries for the `flecs_hub.Interop.Flecs` package.
17 |
18 | https://github.com/flecs-hub/flecs-cs
19 | MIT
20 | _README_PACKAGE.md
21 | true
22 | true
23 | false
24 | false
25 |
26 |
27 |
28 | true
29 | /
30 | PreserveNewest
31 |
32 |
33 |
34 |
35 |
36 |
37 | %(Filename)%(Extension)
38 | runtimes/win-x64/native/%(Filename)%(Extension)
39 | true
40 | PreserveNewest
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.runtime.linux-x64/Interop.Flecs.runtime.linux-x64.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | netstandard1.0
6 | false
7 | disable
8 | true
9 |
10 |
11 |
12 |
13 | true
14 | flecs_hub.Interop.Flecs.runtime.linux-x64
15 |
16 | Linux x64 native libraries for the `flecs_hub.Interop.Flecs` package.
17 |
18 | https://github.com/flecs-hub/flecs-cs
19 | MIT
20 | _README_PACKAGE.md
21 | true
22 | true
23 | false
24 | false
25 |
26 |
27 |
28 | true
29 | /
30 | PreserveNewest
31 |
32 |
33 |
34 |
35 |
36 |
37 | %(Filename)%(Extension)
38 | runtimes/linux-x64/native/%(Filename)%(Extension)
39 | true
40 | PreserveNewest
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.PrefabSlot/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs.Examples.Entities.PrefabSlot;
5 |
6 | internal static class Program
7 | {
8 | private static int Main(string[] args)
9 | {
10 | var world = new World(args);
11 | // ecs_world_t* ecs = ecs_init_w_args(argc, argv);
12 |
13 | // Create the same prefab hierarchy as from the hierarchy example, but now with the SlotOf relationship.
14 |
15 | var spaceShipPrefab = world.CreatePrefab("SpaceShip");
16 | var enginePrefab = world.CreatePrefab("Engine");
17 | enginePrefab.AddParent(spaceShipPrefab);
18 | enginePrefab.AddSlotOf(spaceShipPrefab);
19 |
20 | var cockpitPrefab = world.CreatePrefab("Cockpit");
21 | cockpitPrefab.AddParent(spaceShipPrefab);
22 | cockpitPrefab.AddSlotOf(spaceShipPrefab);
23 |
24 | // Add an additional child to the Cockpit prefab to demonstrate how
25 | // slots can be different from the parent. This slot could have been
26 | // added to the Cockpit prefab, but instead we register it on the top
27 | // level SpaceShip prefab.
28 | var pilotSeat = world.CreatePrefab("PilotSeat");
29 | pilotSeat.AddParent(cockpitPrefab);
30 | pilotSeat.AddSlotOf(spaceShipPrefab);
31 |
32 | // Create a prefab instance.
33 | var shipInstance = world.CreateEntity("SpaceShipInstance");
34 | shipInstance.IsA(spaceShipPrefab);
35 |
36 | // Get the instantiated entities for the prefab slots
37 | Entity engineInstance = shipInstance.GetTarget(enginePrefab);
38 | Entity cockpitInstance = shipInstance.GetTarget(cockpitPrefab);
39 | Entity pilotSeatInstance = shipInstance.GetTarget(pilotSeat);
40 |
41 | Console.WriteLine($"Instance engine: {engineInstance.FullPathString()}");
42 | Console.WriteLine($"Instance cockpit: {cockpitInstance.FullPathString()}");
43 | Console.WriteLine($"Instance pilot seat: {pilotSeatInstance.FullPathString()}");
44 |
45 | return world.Fini();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Iterator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Runtime.CompilerServices;
6 | using JetBrains.Annotations;
7 | using static flecs_hub.Interop.Flecs.PInvoke;
8 |
9 | namespace Flecs;
10 |
11 | [PublicAPI]
12 | public readonly unsafe struct Iterator
13 | {
14 | internal readonly ecs_iter_t* Handle;
15 | private readonly World _world;
16 |
17 | public int Count => Handle->count;
18 |
19 | internal Iterator(World world, ecs_iter_t* it)
20 | {
21 | _world = world;
22 | Handle = it;
23 | }
24 |
25 | public float DeltaTime() => Handle->delta_time;
26 |
27 | public float DeltaSystemTime() => Handle->delta_system_time;
28 |
29 | public Span Field(int index)
30 | {
31 | var structSize = Unsafe.SizeOf();
32 | var pointer = ecs_field_w_size(Handle, (ulong)structSize, index);
33 | return new Span(pointer, Handle->count);
34 | }
35 |
36 | public bool FieldIsSet(int index)
37 | {
38 | return ecs_field_is_set(Handle, index);
39 | }
40 |
41 | public bool FieldIs(int index)
42 | where T : unmanaged, IEcsComponent
43 | {
44 | var id = ecs_field_id(Handle, index);
45 | var compId = _world.GetIdentifier();
46 | return id == compId.Handle;
47 | }
48 |
49 | public Table Table()
50 | {
51 | return new Table(Handle->world, Handle->table);
52 | }
53 |
54 | public Entity Entity(int index)
55 | {
56 | var result = new Entity(_world, Handle->entities[index]);
57 | return result;
58 | }
59 |
60 | public bool HasQueryChanged()
61 | {
62 | return ecs_query_changed(null, Handle);
63 | }
64 |
65 | public void QuerySkip()
66 | {
67 | ecs_query_skip(Handle);
68 | }
69 |
70 | public bool IsSelf(int index)
71 | {
72 | return ecs_field_is_self(Handle, index);
73 | }
74 |
75 | public IteratorEvent Event()
76 | {
77 | var result = new IteratorEvent(_world, Handle->@event);
78 | return result;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.Basics/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Flecs.Examples.Entities.Basics;
7 |
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct Position : IComponent
10 | {
11 | public double X;
12 | public double Y;
13 | }
14 |
15 | public struct Walking : ITag
16 | {
17 | }
18 |
19 | internal static class Program
20 | {
21 | private static int Main(string[] args)
22 | {
23 | var world = new World(args);
24 |
25 | world.RegisterComponent();
26 | world.RegisterTag();
27 |
28 | var bob = world.CreateEntity("Bob");
29 | bob.Set(new Position { X = 10, Y = 20 });
30 | bob.Add();
31 |
32 | var position = bob.GetComponent();
33 | Console.WriteLine("Bob's initial position: {" + position.X + ", " + position.Y + "}");
34 |
35 | // Print all the components the entity has. This will output:
36 | // Position, Walking, (Identifier,Name)
37 | Console.WriteLine("Bob's type: " + bob.Type().String());
38 |
39 | bob.Set(new Position { X = 20, Y = 30 });
40 |
41 | var alice = world.CreateEntity("Alice");
42 | alice.Set(new Position { X = 10, Y = 20 });
43 | alice.Add();
44 |
45 | // Print all the components the entity has. This will output:
46 | // Position, Walking, (Identifier,Name)
47 | Console.WriteLine("Alice's type: " + alice.Type().String());
48 |
49 | // Remove tag
50 | alice.Remove();
51 |
52 | // Iterate all entities with Position
53 | var it = world.EntityIterator();
54 | while (it.HasNext())
55 | {
56 | var p = it.Field(1);
57 | for (var i = 0; i < it.Count; i++)
58 | {
59 | var entity = it.Entity(i);
60 | var entityName = entity.Name();
61 | var entityPosition = p[i];
62 | Console.WriteLine(entityName + ": {" + entityPosition.X + ", " + entityPosition.Y + "}");
63 | }
64 | }
65 |
66 | return world.Fini();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/cs/examples/Flecs.Examples.HelloWorld/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Flecs.Examples.HelloWorld;
7 |
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct Position : IComponent
10 | {
11 | public double X;
12 | public double Y;
13 | }
14 |
15 | [StructLayout(LayoutKind.Sequential)]
16 | public struct Velocity : IComponent
17 | {
18 | public double X;
19 | public double Y;
20 | }
21 |
22 | public struct Eats : ITag
23 | {
24 | }
25 |
26 | public struct Apples : ITag
27 | {
28 | }
29 |
30 | public struct Pears : ITag
31 | {
32 | }
33 |
34 | internal static class Program
35 | {
36 | // Move system implementation. System callbacks may be called multiple times, as entities are grouped by which
37 | // components they have, and each group has its own set of component arrays.
38 | private static void Move(Iterator iterator)
39 | {
40 | var p = iterator.Field(1);
41 | var v = iterator.Field(2);
42 |
43 | // Print the set of components for the iterated over entities
44 | var tableString = iterator.Table().String();
45 | Console.WriteLine("Move entities with table: " + tableString);
46 |
47 | // Iterate entities for the current group
48 | for (var i = 0; i < iterator.Count; i++)
49 | {
50 | ref var position = ref p[i];
51 | var velocity = v[i];
52 |
53 | position.X += velocity.X;
54 | position.Y += velocity.Y;
55 | }
56 | }
57 |
58 | private static int Main(string[] args)
59 | {
60 | // Create the world
61 | var world = new World(args);
62 |
63 | world.RegisterComponent();
64 | world.RegisterComponent();
65 | world.RegisterTag();
66 | world.RegisterTag();
67 | world.RegisterTag();
68 |
69 | // Register system
70 | world.RegisterSystem(Move);
71 |
72 | // Create an entity with name Bob, add Position and food preference
73 | var bob = world.CreateEntity("Bob");
74 | bob.Set(new Position { X = 0, Y = 0 });
75 | bob.Set(new Velocity { X = 2, Y = 2 });
76 | bob.Add();
77 |
78 | // Run systems twice. Usually this function is called once per frame
79 | world.Progress(0);
80 | world.Progress(0);
81 |
82 | // See if Bob has moved (he has)
83 | var p = bob.GetComponent();
84 | Console.WriteLine("Bob's position is {" + p.X + ", " + p.Y + "}");
85 |
86 | return world.Fini();
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flecs-cs
2 |
3 | Archived; see: https://github.com/BeanCheeseBurrito/Flecs.NET
4 |
5 | Automatically updated C# bindings for https://github.com/SanderMertens/flecs with native dynamic link libraries. Includes the lower-level unsafe C# "binding" which is 100% automatically generated. The higher level safe "wrapper" is still being worked on.
6 |
7 | ## How to use
8 |
9 | ### NuGet
10 |
11 | NuGet packages are experimental; please add the NuGet feed `https://www.myget.org/F/bottlenoselabs/api/v3/index.json` to access the NuGet packages.
12 |
13 | Either install `flecs_hub.Flecs` or `flecs_hub.Interop.Flecs` along with one the native library packages for your operating system / hardware.
14 |
15 | |Package name|Description|
16 | |-|-|
17 | |`flecs_hub.Flecs`|High-level, safe, idomatic C# API.|
18 | |`flecs_hub.Interop.Flecs`|Low-level, unsafe, 1-1 C# bindings.|
19 | |`flecs_hub.Interop.Flecs.runtime.win-x64`|Native libraries for Windows x64.|
20 | |`flecs_hub.Interop.Flecs.runtime.osx`|Native libraries for macOS universal (x64 and arm64).|
21 | |`flecs_hub.Interop.Flecs.runtime.linux-x64`|Native libraries for Linux x64.|
22 |
23 | ### From source
24 |
25 | 1. Download and install [.NET 7](https://dotnet.microsoft.com/download).
26 | 2. Fork the repository using GitHub or clone the repository manually with submodules: `git clone --recurse-submodules https://github.com/flecs-hub/flecs-cs`.
27 | 3. Build the native library by running `library.sh`. To execute `.sh` scripts on Windows, use Git Bash which can be installed with Git itself: https://git-scm.com/download/win. The `library.sh` script requires that CMake is installed and in your path and that [`C2CS`](https://github.com/bottlenoselabs/c2cs) is installed.
28 | 4.
29 | - .NET 7+: Add the `src/cs/production/Flecs.Core/Flecs.Core.csproj` C# project to your solution as an existing project and then reference it within your own solution.
30 | - Unity: Build the `src/cs/production/Flecs.Unity/Flecs.Unity.csproj` C# project and create the resulting `Flecs.Unity.dll` with it's dependencies; follow Unity's documentation for using the compiled C# code as a `.dll`: https://docs.unity3d.com/Manual/UsingDLL.
31 |
32 | ## Developers: Documentation
33 |
34 | ### C# Examples
35 |
36 | For examples in C# (.NET Core, not Unity), see [./src/cs/examples](https://github.com/flecs-hub/flecs-cs/tree/main/src/cs/examples), or open up the solution `.sln` file in VisualStudio / Rider.
37 |
38 | ### C Examples
39 |
40 | To learn how to use `flecs` directly, check out the https://github.com/SanderMertens/flecs#documentation.
41 |
42 | ### Binding / wrapper
43 |
44 | For more information on how C# binding / wrapper work, see [`C2CS`](https://github.com/lithiumtoast/c2cs), the tool that generates the binding / wrapper for `flecs` and other C libraries.
45 |
46 | ## License
47 |
48 | `flecs-cs` is licensed under the MIT License (`MIT`) - see the [LICENSE file](LICENSE) for details.
49 |
50 | `flecs` itself is licensed under MIT (`MIT`) - see https://github.com/SanderMertens/flecs/blob/master/LICENSE for more details.
51 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/CallbacksHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Diagnostics.CodeAnalysis;
6 | using System.Threading;
7 |
8 | namespace Flecs;
9 |
10 | internal static class CallbacksHelper
11 | {
12 | private static SystemCallbackContext[] _systemCallbackContexts = new SystemCallbackContext[64];
13 | private static int _systemCallbackContextsCount;
14 |
15 | private static ComponentHooksCallbackContext[] _componentHooksCallbackContexts = new ComponentHooksCallbackContext[64];
16 | private static int _componentHooksCallbackContextsCount;
17 |
18 | public static IntPtr CreateSystemCallbackContext(World world, CallbackIterator callback)
19 | {
20 | var data = new SystemCallbackContext(world, callback);
21 | var count = Interlocked.Increment(ref _systemCallbackContextsCount);
22 | if (count > _systemCallbackContexts.Length)
23 | {
24 | Array.Resize(ref _systemCallbackContexts, count * 2);
25 | }
26 |
27 | _systemCallbackContexts[count - 1] = data;
28 | var result = (IntPtr)count;
29 | return result;
30 | }
31 |
32 | public static void GetSystemCallbackContext(IntPtr pointer, out SystemCallbackContext data)
33 | {
34 | var index = (int)pointer;
35 | data = _systemCallbackContexts[index - 1];
36 | }
37 |
38 | public static IntPtr CreateComponentHooksCallbackContext(World world, ComponentHooks hooks)
39 | {
40 | var data = new ComponentHooksCallbackContext(world, hooks);
41 | var count = Interlocked.Increment(ref _componentHooksCallbackContextsCount);
42 | if (count > _componentHooksCallbackContexts.Length)
43 | {
44 | Array.Resize(ref _componentHooksCallbackContexts, count * 2);
45 | }
46 |
47 | _componentHooksCallbackContexts[count - 1] = data;
48 | var result = (IntPtr)count;
49 | return result;
50 | }
51 |
52 | public static unsafe ref ComponentHooksCallbackContext GetComponentHooksCallbackContext(void* pointer)
53 | {
54 | var index = (int)pointer;
55 | return ref _componentHooksCallbackContexts[index - 1];
56 | }
57 |
58 | public readonly struct SystemCallbackContext
59 | {
60 | public readonly World World;
61 | public readonly CallbackIterator Callback;
62 |
63 | public SystemCallbackContext(World world, CallbackIterator callback)
64 | {
65 | World = world;
66 | Callback = callback;
67 | }
68 | }
69 |
70 | public readonly struct ComponentHooksCallbackContext
71 | {
72 | public readonly World World;
73 | public readonly ComponentHooks Hooks;
74 |
75 | public ComponentHooksCallbackContext(World world, ComponentHooks hooks)
76 | {
77 | World = world;
78 | Hooks = hooks;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: "Release"
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | pre-release:
6 | description: 'Is this a release candidate (pre-release)? (NOTE: candidates get uploaded to MyGet.org instead of NuGet.org)'
7 | required: true
8 | default: 'true'
9 | schedule:
10 | - cron: "0 0 1 * *" # First day of every month
11 |
12 | jobs:
13 |
14 | build-job:
15 | name: "Build"
16 | uses: "./.github/workflows/build.yml"
17 |
18 | release-job:
19 | name: "Release"
20 | needs: [build-job]
21 | runs-on: ubuntu-latest
22 | permissions:
23 | contents: write
24 | steps:
25 |
26 | - name: "Clone Git repository"
27 | uses: actions/checkout@master
28 | with:
29 | submodules: "recursive"
30 |
31 | - name: "Set version"
32 | id: set-version
33 | shell: bash
34 | run: |
35 | IS_PRERELEASE="${{ github.event.inputs.pre-release }}"
36 | if [[ "$IS_PRERELEASE" = "true" ]]; then
37 | VERSION="$(date +'%Y.%m.%d')-rc"
38 | else
39 | VERSION="$(date +'%Y.%m.%d')"
40 | fi
41 | echo "VERSION=$VERSION"
42 | echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"
43 |
44 | - name: "Download native libraries (win-x64)"
45 | uses: actions/download-artifact@v1
46 | with:
47 | name: "native-libraries-win-x64"
48 | path: "./lib"
49 |
50 | - name: "Download native libraries (osx)"
51 | uses: actions/download-artifact@v1
52 | with:
53 | name: "native-libraries-osx"
54 | path: "./lib"
55 |
56 | - name: "Download native libraries (linux-x64)"
57 | uses: actions/download-artifact@v1
58 | with:
59 | name: "native-libraries-linux-x64"
60 | path: "./lib"
61 |
62 | - name: ".NET pack"
63 | run: dotnet pack "./src/cs" --nologo --verbosity minimal --configuration Release -p:Version="${{ steps.set-version.outputs.VERSION }}" -p:RepositoryBranch="${{ github.head_ref || github.ref_name }}" -p:RepositoryCommit="${{ github.sha }}"
64 |
65 | - name: "Upload packages to MyGet"
66 | if: github.event_name == 'workflow_dispatch' && github.event.inputs.pre-release == 'true'
67 | env:
68 | MYGET_ACCESS_TOKEN: ${{ secrets.MYGET_ACCESS_TOKEN }}
69 | run: dotnet nuget push "./nupkg/**/*.nupkg" --source https://www.myget.org/F/bottlenoselabs/api/v3/index.json --skip-duplicate --api-key $MYGET_ACCESS_TOKEN
70 |
71 | - name: "Upload packages to NuGet"
72 | if: github.event_name == 'schedule' || github.event.inputs.pre-release == 'false'
73 | env:
74 | NUGET_ACCESS_TOKEN: ${{ secrets.NUGET_ACCESS_TOKEN }}
75 | run: dotnet nuget push "./nupkg/**/*.nupkg" --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key $NUGET_ACCESS_TOKEN
76 |
77 | - name: "Create tag and GitHub release"
78 | uses: softprops/action-gh-release@v1
79 | if: github.event_name == 'schedule' || github.event.inputs.pre-release == 'false'
80 | with:
81 | generate_release_notes: true
82 | prerelease: "{{ github.event.inputs.pre-release == 'true' }}"
83 | tag_name: "v${{ steps.set-version.outputs.VERSION }}"
84 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.Hierarchy/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Flecs.Examples.Entities.Hierarchy;
7 |
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct Position : IComponent
10 | {
11 | public double X;
12 | public double Y;
13 | }
14 |
15 | public struct Star : ITag
16 | {
17 | }
18 |
19 | public struct Planet : ITag
20 | {
21 | }
22 |
23 | public struct Moon : ITag
24 | {
25 | }
26 |
27 | internal static class Program
28 | {
29 | private static int Main(string[] args)
30 | {
31 | var world = new World(args);
32 |
33 | world.RegisterComponent();
34 | world.RegisterTag();
35 | world.RegisterTag();
36 | world.RegisterTag();
37 |
38 | // Create a simple hierarchy.
39 | // Hierarchies use ECS relations and the builtin flecs::ChildOf relation to
40 | // create entities as children of other entities.
41 |
42 | var sun = world.CreateEntity("Sun");
43 | sun.Add();
44 | sun.Set(new Position { X = 1, Y = 1 });
45 |
46 | var mercury = world.CreateEntity("Mercury");
47 | mercury.AddParent(sun);
48 | mercury.Add();
49 | mercury.Set(new Position { X = 1, Y = 1 });
50 |
51 | var venus = world.CreateEntity("Venus");
52 | venus.AddParent(sun);
53 | venus.Add();
54 | venus.Set(new Position { X = 2, Y = 2 });
55 |
56 | var earth = world.CreateEntity("Earth");
57 | earth.AddParent(sun);
58 | earth.Add();
59 | earth.Set(new Position { X = 3, Y = 3 });
60 |
61 | var moon = world.CreateEntity("Moon");
62 | moon.AddParent(earth);
63 | moon.Add();
64 | moon.Set(new Position { X = 0.1f, Y = 0.1f });
65 |
66 | // Is the Moon a child of Earth?
67 | Console.WriteLine("Is Moon a child entity of Earth?: " + moon.IsChildOf(earth));
68 | Console.WriteLine("Is Earth a child entity of Moon?: " + earth.IsChildOf(moon));
69 |
70 | // Do a depth-first walk of the tree
71 | IterateTree(world, sun, default);
72 |
73 | return world.Fini();
74 | }
75 |
76 | private static void IterateTree(World world, Entity entity, Position parentPosition)
77 | {
78 | // Print hierarchical name of entity & the entity type
79 | var pathString = entity.FullPathString();
80 | var typeString = entity.Type().String();
81 | Console.WriteLine(pathString + " " + typeString);
82 |
83 | // Get entity position
84 | var position = entity.GetComponent();
85 |
86 | // Calculate actual position
87 | var actualPosition = new Position { X = position.X + parentPosition.X, Y = position.Y + parentPosition.Y };
88 | Console.WriteLine("{" + actualPosition.X + ", " + actualPosition.Y + "}");
89 |
90 | // Iterate children recursively
91 | var it = entity.Children();
92 | while (it.HasNext())
93 | {
94 | for (var i = 0; i < it.Count; i++)
95 | {
96 | IterateTree(world, it.Entity(i), actualPosition);
97 | }
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: "Build .NET solution"
2 |
3 | on:
4 | workflow_call:
5 | push:
6 | tags:
7 | - v*
8 | branches:
9 | - main
10 | paths-ignore:
11 | - "**.md"
12 |
13 | jobs:
14 |
15 | native-job:
16 | name: "Build native libraries: ${{ matrix.platform.rid }}"
17 | runs-on: ${{ matrix.platform.os }}
18 | strategy:
19 | fail-fast: false
20 | matrix:
21 | platform:
22 | - { name: Windows (x64), os: windows-latest, rid: win-x64 }
23 | - { name: macOS (x64 + arm64), os: macos-latest, rid: osx }
24 | - { name: Linux (x64), os: ubuntu-latest, rid: linux-x64 }
25 | steps:
26 |
27 | - name: "Clone Git repository"
28 | uses: actions/checkout@master
29 | with:
30 | submodules: "recursive"
31 |
32 | - name: "Cache native libraries"
33 | id: cache-libs
34 | uses: actions/cache@v3
35 | with:
36 | path: "./lib"
37 | key: "libs-${{ matrix.platform.rid }}-${{ hashFiles('ext/flecs/**/*') }}-${{ hashFiles('src/c/**/*') }}"
38 |
39 | - name: "Install C2CS"
40 | shell: bash
41 | run: dotnet tool install --global bottlenoselabs.C2CS.Tool
42 |
43 | - name: "Install Linux dependencies"
44 | if: runner.os == 'Linux' && steps.cache-libs.outputs.cache-hit != 'true'
45 | run: sudo apt-get update
46 |
47 | - name: "Build native libraries"
48 | if: steps.cache-libs.outputs.cache-hit != 'true'
49 | shell: bash
50 | run: ./library.sh "auto"
51 |
52 | - name: "Upload native libraries"
53 | uses: actions/upload-artifact@v2
54 | with:
55 | path: "./lib"
56 | name: "native-libraries-${{ matrix.platform.rid }}"
57 |
58 | dotnet-job:
59 | name: "Build .NET solution"
60 | needs: [native-job]
61 | runs-on: ubuntu-latest
62 | steps:
63 |
64 | - name: "Clone Git repository"
65 | uses: actions/checkout@master
66 |
67 | - name: "Download native libraries (win-x64)"
68 | uses: actions/download-artifact@v1
69 | continue-on-error: ${{ github.actor != 'dependabot[bot]' && github.actor != 'lithiumtoast' }}
70 | with:
71 | name: "native-libraries-win-x64"
72 | path: "./lib"
73 |
74 | - name: "Download native libraries (osx)"
75 | uses: actions/download-artifact@v1
76 | continue-on-error: ${{ github.actor != 'dependabot[bot]' && github.actor != 'lithiumtoast' }}
77 | with:
78 | name: "native-libraries-osx"
79 | path: "./lib"
80 |
81 | - name: "Download native libraries (linux-x64)"
82 | uses: actions/download-artifact@v1
83 | continue-on-error: ${{ github.actor != 'dependabot[bot]' && github.actor != 'lithiumtoast' }}
84 | with:
85 | name: "native-libraries-linux-x64"
86 | path: "./lib"
87 |
88 | - name: "Download generated C# code: .NET 7+"
89 | uses: actions/download-artifact@v1
90 | continue-on-error: true
91 | with:
92 | name: "bindgen-cs-core"
93 | path: "./src/cs/production/Interop.Flecs.Core/Generated"
94 |
95 | - name: "Download generated C# code: Unity"
96 | uses: actions/download-artifact@v1
97 | continue-on-error: true
98 | with:
99 | name: "bindgen-cs-unity"
100 | path: "./src/cs/production/Interop.Flecs.Unity/Generated"
101 |
102 | - name: ".NET Build"
103 | run: dotnet build "./src/cs" --nologo --verbosity minimal --configuration Release
104 |
105 |
--------------------------------------------------------------------------------
/src/cs/examples/queries/Flecs.Examples.Queries.OptionalOr/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 | using static flecs_hub.Interop.Flecs.PInvoke;
6 |
7 | namespace Flecs.Examples.Entities.OptionalOr;
8 |
9 | internal static class Program
10 | {
11 | [StructLayout(LayoutKind.Sequential)]
12 | public struct Position : IComponent
13 | {
14 | public float X;
15 | public float Y;
16 | }
17 |
18 | [StructLayout(LayoutKind.Sequential)]
19 | public struct Velocity : IComponent
20 | {
21 | public float Value;
22 | }
23 |
24 | [StructLayout(LayoutKind.Sequential)]
25 | public struct Speed : IComponent
26 | {
27 | public float Value;
28 | }
29 |
30 | private static int Main(string[] args)
31 | {
32 | var world = new World(args);
33 | world.RegisterComponent();
34 | world.RegisterComponent();
35 | world.RegisterComponent();
36 |
37 | var e1 = world.CreateEntity("e1");
38 | e1.Set(default(Position));
39 | e1.Set(default(Velocity));
40 | var e2 = world.CreateEntity("e2");
41 | e2.Set(default(Position));
42 | e2.Set(default(Speed));
43 | world.RegisterSystem(
44 | MoveOptionalVel,
45 | EcsOnUpdate,
46 | $"{world.GetFlecsTypeName(typeof(Position))}, ?{world.GetFlecsTypeName(typeof(Velocity))}");
47 | world.RegisterSystem(
48 | MoveOr,
49 | EcsOnUpdate,
50 | $"{world.GetFlecsTypeName(typeof(Position))}, " + $"{world.GetFlecsTypeName(typeof(Velocity))} || {world.GetFlecsTypeName(typeof(Speed))}");
51 |
52 | world.Progress(0);
53 |
54 | return world.Fini();
55 | }
56 |
57 | private static void MoveOptionalVel(Iterator iterator)
58 | {
59 | var p = iterator.Field(1);
60 |
61 | if (iterator.FieldIsSet(2))
62 | {
63 | var v = iterator.Field(2);
64 | for (var i = 0; i < iterator.Count; i++)
65 | {
66 | Console.WriteLine("entity has: pos, vel for");
67 | Console.WriteLine(iterator.Table().String());
68 | }
69 | }
70 | else
71 | {
72 | for (var i = 0; i < iterator.Count; i++)
73 | {
74 | Console.WriteLine("entity has: pos, no vel");
75 | Console.WriteLine(iterator.Table().String());
76 | }
77 | }
78 | }
79 |
80 | private static void MoveOr(Iterator iterator)
81 | {
82 | var p = iterator.Field(1);
83 |
84 | if (iterator.FieldIs(2))
85 | {
86 | var v = iterator.Field(2);
87 | for (var i = 0; i < iterator.Count; i++)
88 | {
89 | Console.WriteLine("entity has: pos, vel");
90 | Console.WriteLine(iterator.Table().String());
91 | }
92 | }
93 | else if (iterator.FieldIs(2))
94 | {
95 | for (var i = 0; i < iterator.Count; i++)
96 | {
97 | Console.WriteLine("entity has: pos, speed");
98 | Console.WriteLine(iterator.Table().String());
99 | }
100 | }
101 | else
102 | {
103 | // top could be written as else
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/cs/production/Interop.Flecs.Core/PInvoke.Extensions.cs:
--------------------------------------------------------------------------------
1 | //
2 | // ReSharper disable All
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | namespace flecs_hub.Interop.Flecs
7 | {
8 | public static unsafe partial class PInvoke
9 | {
10 | // Roles
11 | public static ecs_id_t ECS_PAIR => pinvoke_ECS_PAIR();
12 | public static ecs_id_t ECS_OVERRIDE => pinvoke_ECS_OVERRIDE();
13 |
14 | // Relationships
15 | public static ecs_entity_t EcsIsA => pinvoke_EcsIsA();
16 | public static ecs_entity_t EcsDependsOn => pinvoke_EcsDependsOn();
17 | public static ecs_entity_t EcsChildOf => pinvoke_EcsChildOf();
18 |
19 | public static ecs_entity_t EcsSlotOf => pinvoke_EcsSlotOf();
20 |
21 | // Entity tags
22 | public static ecs_entity_t EcsPrefab => pinvoke_EcsPrefab();
23 |
24 | // System tags
25 | public static ecs_entity_t EcsPreFrame => pinvoke_EcsPreFrame();
26 | public static ecs_entity_t EcsOnLoad => pinvoke_EcsOnLoad();
27 | public static ecs_entity_t EcsPostLoad => pinvoke_EcsPostLoad();
28 | public static ecs_entity_t EcsPreUpdate => pinvoke_EcsPreUpdate();
29 | public static ecs_entity_t EcsOnUpdate => pinvoke_EcsOnUpdate();
30 | public static ecs_entity_t EcsOnValidate => pinvoke_EcsOnValidate();
31 | public static ecs_entity_t EcsPostUpdate => pinvoke_EcsPostUpdate();
32 | public static ecs_entity_t EcsPreStore => pinvoke_EcsPreStore();
33 | public static ecs_entity_t EcsOnStore => pinvoke_EcsOnStore();
34 | public static ecs_entity_t EcsPostFrame => pinvoke_EcsPostFrame();
35 | public static ecs_entity_t EcsPhase => pinvoke_EcsPhase();
36 |
37 |
38 | public static ulong ecs_pair(ecs_entity_t pred, ecs_entity_t obj)
39 | {
40 | return ECS_PAIR.Data | ecs_entity_t_comb(obj.Data.Data, pred.Data.Data);
41 | }
42 |
43 | public static ulong ecs_childof(ecs_entity_t e)
44 | {
45 | return ecs_pair(EcsChildOf, e);
46 | }
47 |
48 | public static ulong ecs_entity_t_comb(ulong lo, ulong hi)
49 | {
50 | return (hi << 32) + (uint)lo;
51 | }
52 |
53 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
54 | public static ecs_entity_t ecs_pair_first(ecs_world_t* world, ecs_entity_t entity)
55 | {
56 | var value = ECS_PAIR_FIRST(entity.Data.Data);
57 | return ecs_get_alive(world, *(ecs_entity_t*)&value);
58 | }
59 |
60 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
61 | public static ecs_entity_t ecs_pair_second(ecs_world_t* world, ecs_entity_t entity)
62 | {
63 | var value = ECS_PAIR_SECOND(entity.Data.Data);
64 | return ecs_get_alive(world, *(ecs_entity_t*)&value);
65 | }
66 |
67 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
68 | public static ulong ECS_PAIR_FIRST(ulong entity)
69 | {
70 | var value = entity & ECS_COMPONENT_MASK;
71 | return ecs_entity_t_hi(value);
72 | }
73 |
74 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
75 | public static ulong ECS_PAIR_SECOND(ulong entity)
76 | {
77 | var value = entity;
78 | return ecs_entity_t_lo(value);
79 | }
80 |
81 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
82 | public static uint ecs_entity_t_hi(ulong value)
83 | {
84 | return (uint)(value >> 32);
85 | }
86 |
87 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
88 | public static uint ecs_entity_t_lo(ulong value)
89 | {
90 | return (uint)value;
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.RelationBasic/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | namespace Flecs.Examples.Entities.RelationBasic;
5 |
6 | public struct Eats : ITag
7 | {
8 | }
9 |
10 | public struct People : ITag
11 | {
12 | }
13 |
14 | internal static class Program
15 | {
16 | private static int Main(string[] args)
17 | {
18 | var world = new World(args);
19 | world.RegisterTag();
20 | world.RegisterTag();
21 | var grows = world.CreateEntity("Grows");
22 | var apples = world.CreateEntity("Apples");
23 | var pears = world.CreateEntity("Pears");
24 |
25 | var bob = world.CreateEntity("Bob");
26 | bob.AddSecond(apples);
27 | bob.AddSecond(pears);
28 | bob.Add();
29 |
30 | // Pairs can also be constructed from two entity ids
31 | bob.Add(grows, pears);
32 |
33 | Console.WriteLine("bob has (Grows, Pears) (dynamic): " + bob.Has(grows, pears));
34 | Console.WriteLine("bob has (Pears, Grows) (dynamic): " + bob.Has(pears, grows));
35 |
36 | Console.WriteLine("bob has (Eats, Apples) (dynamic): " + bob.Has(apples));
37 | Console.WriteLine("bob has (Apples, Eats) (dynamic): " + bob.HasSecond(apples));
38 |
39 | Console.WriteLine("bob has (Eats, People): " + bob.Has());
40 | Console.WriteLine("bob has (People, Eats): " + bob.Has());
41 |
42 | Console.WriteLine("\n");
43 | IterateComponents(bob);
44 |
45 | return world.Fini();
46 | }
47 |
48 | private static void IterateComponents(Entity entity)
49 | {
50 | // First get the entity's type, which is a vector of (component) ids.
51 | var type = entity.Type();
52 |
53 | // 1. The easiest way to print the components is the type's string
54 | var typeString = type.String();
55 | Console.WriteLine("Type: " + typeString);
56 |
57 | // 2. To print individual ids, iterate the type array with ecs_id_str
58 | var i = 0;
59 | foreach (var identifier in type.Identifiers())
60 | {
61 | var identifierString = identifier.String();
62 | Console.WriteLine(i + ": " + identifierString);
63 | i++;
64 | }
65 |
66 | Console.WriteLine();
67 |
68 | // 3. we can also inspect and print the ids in our own way. This is a
69 | // bit more complicated as we need to handle the edge cases of what can be
70 | // encoded in an id, but provides the most flexibility.
71 | i = 0;
72 | foreach (var identifier in type.Identifiers())
73 | {
74 | Console.Write(i + ": ");
75 |
76 | var roleString = identifier.RoleString();
77 | if (roleString != "UNKNOWN")
78 | {
79 | Console.Write("Role: " + roleString + ", ");
80 | }
81 |
82 | if (identifier.IsPair)
83 | {
84 | var pair = identifier.AsPair();
85 | var relationName = pair.First.Name();
86 | var objectName = pair.Second.Name();
87 | Console.Write("Relation: " + relationName + ", Object: " + objectName);
88 | }
89 | else
90 | {
91 | var component = identifier.AsComponent();
92 | var componentName = component.Name();
93 | Console.Write("Name: " + componentName);
94 | }
95 |
96 | Console.WriteLine();
97 | i++;
98 | }
99 |
100 | Console.WriteLine();
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/.github/workflows/bindgen.yml:
--------------------------------------------------------------------------------
1 | name: "Bindgen"
2 |
3 | on:
4 | workflow_call:
5 |
6 | jobs:
7 |
8 | bindgen-platform-ast-job:
9 | name: "Bindgen AST platform"
10 | runs-on: ${{ matrix.platform.os }}
11 | if: github.actor == 'dependabot[bot]' || github.actor == 'lithiumtoast' || github.actor == 'BlackPhoenix134'
12 | strategy:
13 | fail-fast: false
14 | matrix:
15 | platform:
16 | - { name: Windows, os: windows-latest, rid: win }
17 | - { name: macOS, os: macos-latest, rid: osx }
18 | - { name: Linux, os: ubuntu-latest, rid: linux }
19 |
20 | steps:
21 | - name: "Clone Git repository"
22 | uses: actions/checkout@v2
23 | with:
24 | submodules: 'true'
25 |
26 | - name: "Install CAstFfi"
27 | shell: bash
28 | run: dotnet tool install --global bottlenoselabs.CAstFfi.Tool
29 |
30 | - name: "Read C code: Linux dependencies"
31 | if: runner.os == 'Linux'
32 | run: sudo apt-get update && sudo apt-get install gcc-aarch64-linux-gnu
33 |
34 | - name: "Read C code: extract ${{ matrix.platform.rid }}"
35 | shell: bash
36 | run: cd ./bindgen && ./extract.sh
37 |
38 | - name: "Upload C code platform abstract syntax trees"
39 | uses: actions/upload-artifact@v2
40 | with:
41 | name: "ast-${{ matrix.platform.rid }}"
42 | path: "./bindgen/ast"
43 |
44 | bindgen-cross-platform-ast-job:
45 | name: "Bindgen AST cross-platform"
46 | needs: [bindgen-platform-ast-job]
47 | runs-on: ubuntu-latest
48 |
49 | steps:
50 | - name: "Clone Git repository"
51 | uses: actions/checkout@v2
52 | with:
53 | submodules: 'false'
54 |
55 | - name: "Download C code platform abstract syntax trees (win)"
56 | uses: actions/download-artifact@v1
57 | with:
58 | name: "ast-win"
59 | path: "./bindgen/ast"
60 |
61 | - name: "Download C code platform abstract syntax trees (osx)"
62 | uses: actions/download-artifact@v1
63 | with:
64 | name: "ast-osx"
65 | path: "./bindgen/ast"
66 |
67 | - name: "Download C code platform abstract syntax trees (linux)"
68 | uses: actions/download-artifact@v1
69 | with:
70 | name: "ast-linux"
71 | path: "./bindgen/ast"
72 |
73 | - name: "Install CAstFfi"
74 | shell: bash
75 | run: dotnet tool install --global bottlenoselabs.CAstFfi.Tool
76 |
77 | - name: "Generate cross-platform AST"
78 | shell: bash
79 | run: cd ./bindgen && ./merge.sh
80 |
81 | - name: "Upload cross-platform AST"
82 | uses: actions/upload-artifact@v2
83 | with:
84 | name: "ast-cross-platform"
85 | path: "./bindgen/x-ast/ast-cross-platform.json"
86 |
87 | bindgen-cs-job:
88 | name: "Bindgen C#"
89 | needs: [bindgen-cross-platform-ast-job]
90 | runs-on: ubuntu-latest
91 |
92 | steps:
93 | - name: "Clone Git repository"
94 | uses: actions/checkout@v2
95 | with:
96 | submodules: 'false'
97 |
98 | - name: "Download C code cross-platform abstract syntax tree"
99 | uses: actions/download-artifact@v1
100 | with:
101 | name: "ast-cross-platform"
102 | path: "./bindgen/x-ast"
103 |
104 | - name: "Install C2CS"
105 | shell: bash
106 | run: dotnet tool install --global bottlenoselabs.C2CS.Tool
107 |
108 | - name: "Generate C# code"
109 | shell: bash
110 | run: cd ./bindgen && ./generate.sh
111 |
112 | - name: "Upload generated C# code: .NET 7+"
113 | uses: actions/upload-artifact@v2
114 | with:
115 | name: "bindgen-cs-core"
116 | path: "./src/cs/production/Interop.Flecs.Core/Generated"
117 |
118 | - name: "Upload generated C# code: Unity"
119 | uses: actions/upload-artifact@v2
120 | with:
121 | name: "bindgen-cs-unity"
122 | path: "./src/cs/production/Interop.Flecs.Unity/Generated"
123 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.IterateComponents/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Flecs.Examples.Entities.IterateComponents;
7 |
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct Position : IComponent
10 | {
11 | public double X;
12 | public double Y;
13 | }
14 |
15 | [StructLayout(LayoutKind.Sequential)]
16 | public struct Velocity : IComponent
17 | {
18 | public double X;
19 | public double Y;
20 | }
21 |
22 | public struct Human : ITag
23 | {
24 | }
25 |
26 | public struct Eats : ITag
27 | {
28 | }
29 |
30 | public struct Apples : ITag
31 | {
32 | }
33 |
34 | internal static class Program
35 | {
36 | private static int Main(string[] args)
37 | {
38 | var world = new World(args);
39 |
40 | // Ordinary components
41 | world.RegisterComponent();
42 | world.RegisterComponent();
43 |
44 | // A tag
45 | world.RegisterTag();
46 |
47 | // Two tags used to create a pair
48 | world.RegisterTag();
49 | world.RegisterTag();
50 |
51 | // Create an entity which all of the above
52 | var bob = world.CreateEntity("bob");
53 |
54 | bob.Set(new Position { X = 10, Y = 20 });
55 | bob.Set(new Velocity { X = 1, Y = 1 });
56 | bob.Add();
57 | bob.Add();
58 |
59 | // Iterate & components of Bob
60 | Console.WriteLine("Bob's components:");
61 | IterateComponents(bob);
62 |
63 | // We can use the same function to iterate the components of a component
64 | Console.WriteLine("Position's components:");
65 | IterateComponents(Entity.FromIdentifier(world.GetIdentifier()));
66 |
67 | return world.Fini();
68 | }
69 |
70 | private static void IterateComponents(Entity entity)
71 | {
72 | // First get the entity's type, which is a vector of (component) ids.
73 | var type = entity.Type();
74 |
75 | // 1. The easiest way to print the components is the type's string
76 | var typeString = type.String();
77 | Console.WriteLine("Type: " + typeString);
78 |
79 | // 2. To print individual ids, iterate the type array with ecs_id_str
80 | var i = 0;
81 | foreach (var identifier in type.Identifiers())
82 | {
83 | var identifierString = identifier.String();
84 | Console.WriteLine(i + ": " + identifierString);
85 | i++;
86 | }
87 |
88 | Console.WriteLine();
89 |
90 | // 3. we can also inspect and print the ids in our own way. This is a
91 | // bit more complicated as we need to handle the edge cases of what can be
92 | // encoded in an id, but provides the most flexibility.
93 | i = 0;
94 | foreach (var identifier in type.Identifiers())
95 | {
96 | Console.Write(i + ": ");
97 |
98 | var idFlagsStr = identifier.RoleString();
99 | if (idFlagsStr != "UNKNOWN")
100 | {
101 | Console.Write("ID Flags: " + idFlagsStr + ", ");
102 | }
103 |
104 | if (identifier.IsPair)
105 | {
106 | var pair = identifier.AsPair();
107 | var relationName = pair.First.Name();
108 | var objectName = pair.Second.Name();
109 | Console.Write("First: " + relationName + ", Second: " + objectName);
110 | }
111 | else
112 | {
113 | var component = identifier.AsComponent();
114 | var componentName = component.Name();
115 | Console.Write("Name: " + componentName);
116 | }
117 |
118 | Console.WriteLine();
119 | i++;
120 | }
121 |
122 | Console.WriteLine();
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Expressions/TermBuilder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Text;
5 |
6 | namespace Flecs;
7 |
8 | public class TermBuilder
9 | {
10 | private string _entity1 = string.Empty;
11 | private string _entity2 = string.Empty;
12 | private string _source = "$This";
13 | private string _accessModifier = string.Empty; // empty == default == [InOut]
14 | private string _access = ",";
15 | private string _prefix = string.Empty;
16 |
17 | private readonly StringBuilder _stringBuilder;
18 | private readonly World _world;
19 |
20 | public TermBuilder(World world)
21 | {
22 | _world = world;
23 | _stringBuilder = new();
24 | }
25 |
26 | public TermBuilder First()
27 | where T : unmanaged, IEcsComponent
28 | => First(_world.GetFlecsTypeName());
29 |
30 | public TermBuilder First(string name)
31 | {
32 | _entity1 = name;
33 | return this;
34 | }
35 |
36 | public TermBuilder Second()
37 | where T : unmanaged, IEcsComponent
38 | => Second(_world.GetFlecsTypeName());
39 |
40 | public TermBuilder Second(string name)
41 | {
42 | _entity2 = name;
43 | return this;
44 | }
45 |
46 | public TermBuilder Source(string name)
47 | {
48 | _source = name;
49 | return this;
50 | }
51 |
52 | public TermBuilder Or()
53 | {
54 | _access = "||";
55 | return this;
56 | }
57 |
58 | public TermBuilder Not()
59 | {
60 | _prefix = "!";
61 | return this;
62 | }
63 |
64 | public TermBuilder Optional()
65 | {
66 | _prefix = "?";
67 | return this;
68 | }
69 |
70 | public TermBuilder Term()
71 | where T : unmanaged, IEcsComponent
72 | {
73 | FlushToBuilder();
74 | First();
75 | return this;
76 | }
77 |
78 | public TermBuilder Term()
79 | where T1 : unmanaged, IEcsComponent
80 | where T2 : unmanaged, IEcsComponent
81 | {
82 | var termBuilder = new TermBuilder(_world);
83 | termBuilder.First();
84 | termBuilder.Second();
85 | return termBuilder;
86 | }
87 |
88 | public TermBuilder Term()
89 | {
90 | FlushToBuilder();
91 | return this;
92 | }
93 |
94 | public TermBuilder In()
95 | {
96 | _accessModifier = "[in]";
97 | return this;
98 | }
99 |
100 | public TermBuilder Out()
101 | {
102 | _accessModifier = "[out]";
103 | return this;
104 | }
105 |
106 | public TermBuilder None()
107 | {
108 | _accessModifier = "[none]";
109 | return this;
110 | }
111 |
112 | public TermBuilder InOut() // default, empty == inout
113 | {
114 | _accessModifier = "[inout]";
115 | return this;
116 | }
117 |
118 | public string Build()
119 | {
120 | FlushToBuilder();
121 | return _stringBuilder.ToString();
122 | }
123 |
124 | private void Reset()
125 | {
126 | _entity1 = string.Empty;
127 | _entity2 = string.Empty;
128 | _source = "$This";
129 | _accessModifier = string.Empty;
130 | _access = ",";
131 | _prefix = string.Empty;
132 | }
133 |
134 | private void FlushToBuilder()
135 | {
136 | if (_stringBuilder.Length != 0)
137 | {
138 | _stringBuilder.Append(_access).Append(' ');
139 | }
140 |
141 | if (!string.IsNullOrEmpty(_access))
142 | {
143 | _stringBuilder.Append(_accessModifier).Append(' ');
144 | }
145 |
146 | _stringBuilder.Append(_prefix).Append(_entity1)
147 | .Append('(').Append(_source);
148 |
149 | if (!string.IsNullOrEmpty(_entity2))
150 | {
151 | _stringBuilder.Append(", ").Append(_entity2);
152 | }
153 |
154 | _stringBuilder.Append(')');
155 | Reset();
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.Hooks/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 | using bottlenoselabs.C2CS.Runtime;
6 |
7 | namespace Flecs.Examples.Entities.Hooks;
8 |
9 | // Component hooks are callbacks that can be registered for a type that are
10 | // invoked during different parts of the component lifecycle.
11 |
12 | [StructLayout(LayoutKind.Sequential)]
13 | public struct String : IComponent
14 | {
15 | public CString Value;
16 | }
17 |
18 | public struct Tag : ITag
19 | {
20 | }
21 |
22 | internal static class Program
23 | {
24 | private static int Main(string[] args)
25 | {
26 | var world = new World(args);
27 |
28 | var componentHooks = new ComponentHooks
29 | {
30 | // Resource management hooks. These hooks should primarily be used for managing memory used by the component.
31 | Constructor = ComponentHookConstructor,
32 | Deconstructor = ComponentHookDeconstructor,
33 | Copy = ComponentHookCopy,
34 | Move = ComponentHookMove,
35 | // Lifecycle hooks. These hooks should be used for application logic.
36 | OnAdd = HookCallback,
37 | OnSet = HookCallback,
38 | OnRemove = HookCallback
39 | };
40 | world.RegisterComponent(componentHooks);
41 | world.RegisterTag();
42 |
43 | var entity = world.CreateEntity("Entity");
44 |
45 | Console.WriteLine("entity.Add()");
46 | entity.Add();
47 |
48 | Console.WriteLine("entity.SetComponent()(\"Hello World\")");
49 | entity.Set(new String { Value = (CString)"Hello World" });
50 |
51 | Console.WriteLine("entity.AddTag()");
52 | // This operation changes the entity's archetype, which invokes a move
53 | entity.Add();
54 |
55 | Console.WriteLine("entity.Delete()");
56 | entity.Delete();
57 |
58 | return world.Fini();
59 | }
60 |
61 | // The constructor should initialize the component value.
62 | private static void ComponentHookConstructor(ref ComponentConstructorContext context)
63 | {
64 | Console.WriteLine("\tConstructor");
65 | ref var component = ref context.Get();
66 | component.Value = default;
67 | }
68 |
69 | // The destructor should free resources.
70 | private static void ComponentHookDeconstructor(ref ComponentDeconstructorContext context)
71 | {
72 | Console.WriteLine("\tDeconstructor");
73 | ref var component = ref context.Get();
74 | Marshal.FreeHGlobal(component.Value);
75 | }
76 |
77 | // The copy hook should copy resources from one location to another.
78 | private static void ComponentHookCopy(ref ComponentCopyContext context)
79 | {
80 | Console.WriteLine("\tCopy");
81 | ref var source = ref context.GetSource();
82 | ref var destination = ref context.GetDestination();
83 | var value = source.Value.ToString();
84 | source.Value = default;
85 | destination.Value = (CString)value;
86 | }
87 |
88 | // The move hook should move resources from one location to another.
89 | private static void ComponentHookMove(ref ComponentMoveContext context)
90 | {
91 | Console.WriteLine("\tMove");
92 | ref var source = ref context.GetSource();
93 | ref var destination = ref context.GetDestination();
94 | destination.Value = source.Value;
95 | source.Value = default;
96 | }
97 |
98 | // This callback is used for the add, remove and set hooks. Note that the
99 | // signature is the same as systems, triggers, observers.
100 | private static void HookCallback(Iterator iterator)
101 | {
102 | for (var i = 0; i < iterator.Count; i++)
103 | {
104 | var eventName = iterator.Event().Name();
105 | var entityName = iterator.Entity(i).Name();
106 | Console.WriteLine("\t" + eventName + ": " + entityName);
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.Prefab/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Flecs.Examples.Entities.Prefab;
7 |
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct Attack : IComponent
10 | {
11 | public double Value;
12 | }
13 |
14 | [StructLayout(LayoutKind.Sequential)]
15 | public struct Defense : IComponent
16 | {
17 | public double Value;
18 | }
19 |
20 | [StructLayout(LayoutKind.Sequential)]
21 | public struct FreightCapacity : IComponent
22 | {
23 | public double Value;
24 | }
25 |
26 | [StructLayout(LayoutKind.Sequential)]
27 | public struct ImpulseSpeed : IComponent
28 | {
29 | public double Value;
30 | }
31 |
32 | [StructLayout(LayoutKind.Sequential)]
33 | public struct Position : IComponent
34 | {
35 | public double X;
36 | public double Y;
37 | }
38 |
39 | public struct HasFtl : ITag
40 | {
41 | }
42 |
43 | public struct Amount : IComponent
44 | {
45 | public int Max;
46 | public int Current;
47 | }
48 |
49 | internal static class Program
50 | {
51 | private static int Main(string[] args)
52 | {
53 | var world = new World(args);
54 |
55 | world.RegisterComponent();
56 | world.RegisterComponent();
57 | world.RegisterComponent();
58 | world.RegisterComponent();
59 | world.RegisterComponent();
60 | world.RegisterComponent();
61 | world.RegisterTag();
62 |
63 | var hull = world.CreateEntity("Hull");
64 | var shield = world.CreateEntity("Shield");
65 |
66 | // Create a prefab hierarchy. Prefabs are entities that by default are
67 | // ignored by queries.
68 | var spaceShip = world.CreatePrefab("SpaceShip");
69 | spaceShip.Set(new ImpulseSpeed { Value = 50 });
70 | spaceShip.Set(new Defense { Value = 50 });
71 | // setting as overridable, every ship instance can be damaged individually
72 | spaceShip.SetOverride(hull, new Amount() { Max = 200, Current = 200});
73 | spaceShip.SetOverride(shield, new Amount() { Max = 200, Current = 200 });
74 |
75 | // By default components in an inheritance hierarchy are shared between
76 | // entities. The override function ensures that instances have a private
77 | // copy of the component.
78 | spaceShip.SetOverride(new Position { X = 0, Y = 0 });
79 |
80 | var freighter = world.CreatePrefab("Freighter");
81 | // This ensures the entity inherits all components from spaceship.
82 | freighter.IsA(spaceShip);
83 | freighter.Set(new FreightCapacity { Value = 100 });
84 | freighter.Set(new Defense { Value = 50 });
85 |
86 | var mammothFreighter = world.CreatePrefab("MammothFreighter");
87 | mammothFreighter.IsA(freighter);
88 | mammothFreighter.Set(new FreightCapacity { Value = 500 });
89 | mammothFreighter.Set(new Defense { Value = 300 });
90 |
91 | var frigate = world.CreatePrefab("Frigate");
92 | // This ensures the entity inherits all components from spaceship.
93 | frigate.IsA(spaceShip);
94 | frigate.Set(new Attack { Value = 100 });
95 | frigate.Set(new Defense { Value = 75 });
96 | frigate.Set(new ImpulseSpeed { Value = 125 });
97 |
98 | // Create an entity from a prefab.
99 | // The instance will have a private copy of the Position component, because
100 | // of the override in the spaceship entity. All other components are shared.
101 | var freighter1 = world.CreateEntity("my_mammoth_freighter1");
102 | freighter1.IsA(mammothFreighter);
103 |
104 | var freighter2 = world.CreateEntity("my_mammoth_freighter2");
105 | freighter2.IsA(mammothFreighter);
106 |
107 | // Inspect the type of the entity. This outputs:
108 | // Position,(Identifier,Name),(IsA,MammothFreighter)
109 | var instanceTypeString = freighter1.Type().String();
110 | Console.WriteLine("Instance type: " + instanceTypeString);
111 |
112 | // Even though the instance doesn't have a private copy of ImpulseSpeed, we
113 | // can still get it using the regular API (outputs 50)
114 | var impulseSpeed = freighter1.GetComponent();
115 | Console.WriteLine("Impulse speed: " + impulseSpeed.Value);
116 |
117 | ref var freighter1Hull = ref freighter1.GetSecond(hull);
118 | freighter1Hull.Current -= 100;
119 |
120 | Console.WriteLine($"Freigher 1 hull: {freighter1.GetSecond(hull).Current}");
121 | Console.WriteLine($"Freigher 2 hull: {freighter2.GetSecond(hull).Current}");
122 |
123 | return world.Fini();
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Component/ComponentHooks.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 | using flecs_hub.Interop.Flecs;
6 | using JetBrains.Annotations;
7 | using static flecs_hub.Interop.Flecs.PInvoke;
8 |
9 | namespace Flecs;
10 |
11 | [PublicAPI]
12 | public unsafe struct ComponentHooks
13 | {
14 | public CallbackComponentConstructor? Constructor;
15 | public CallbackComponentDeconstructor? Deconstructor;
16 | public CallbackComponentCopy? Copy;
17 | public CallbackComponentMove? Move;
18 | public CallbackIterator? OnAdd;
19 | public CallbackIterator? OnSet;
20 | public CallbackIterator? OnRemove;
21 |
22 | internal static void Fill(World world, ref ComponentHooks hooks, ecs_type_hooks_t* desc)
23 | {
24 | #if UNITY_5_3_OR_NEWER
25 | desc->ctor.Data.Pointer = Marshal.GetFunctionPointerForDelegate(CallbackConstructor);
26 | desc->dtor.Data.Pointer = Marshal.GetFunctionPointerForDelegate(CallbackDeconstructor);
27 | desc->copy.Data.Pointer = Marshal.GetFunctionPointerForDelegate(CallbackCopy);
28 | desc->move.Data.Pointer = Marshal.GetFunctionPointerForDelegate(CallbackMove);
29 | desc->on_add.Data.Pointer = Marshal.GetFunctionPointerForDelegate(CallbackOnAdd);
30 | desc->on_set.Data.Pointer = Marshal.GetFunctionPointerForDelegate(CallbackOnSet);
31 | desc->on_remove.Data.Pointer = Marshal.GetFunctionPointerForDelegate(CallbackOnRemove);
32 | #else
33 | desc->ctor.Data.Pointer = &CallbackConstructor;
34 | desc->dtor.Data.Pointer = &CallbackDeconstructor;
35 | desc->copy.Data.Pointer = &CallbackCopy;
36 | desc->move.Data.Pointer = &CallbackMove;
37 | desc->on_add.Data.Pointer = &CallbackOnAdd;
38 | desc->on_set.Data.Pointer = &CallbackOnSet;
39 | desc->on_remove.Data.Pointer = &CallbackOnRemove;
40 | #endif
41 | desc->binding_ctx = (void*)CallbacksHelper.CreateComponentHooksCallbackContext(world, hooks);
42 | }
43 |
44 | #if !UNITY_5_3_OR_NEWER
45 | [UnmanagedCallersOnly]
46 | #endif
47 | private static void CallbackConstructor(void* pointer, int count, ecs_type_info_t* typeInfo)
48 | {
49 | ref var data = ref CallbacksHelper.GetComponentHooksCallbackContext(typeInfo->hooks.binding_ctx);
50 | var context = new ComponentConstructorContext(pointer, count);
51 | data.Hooks.Constructor?.Invoke(ref context);
52 | }
53 |
54 | #if !UNITY_5_3_OR_NEWER
55 | [UnmanagedCallersOnly]
56 | #endif
57 | private static void CallbackDeconstructor(void* pointer, int count, ecs_type_info_t* typeInfo)
58 | {
59 | ref var data = ref CallbacksHelper.GetComponentHooksCallbackContext(typeInfo->hooks.binding_ctx);
60 | var context = new ComponentDeconstructorContext(pointer, count);
61 | data.Hooks.Deconstructor?.Invoke(ref context);
62 | }
63 |
64 | #if !UNITY_5_3_OR_NEWER
65 | [UnmanagedCallersOnly]
66 | #endif
67 | private static void CallbackCopy(void* destinationPointer, void* sourcePointer, int count, ecs_type_info_t* typeInfo)
68 | {
69 | ref var data = ref CallbacksHelper.GetComponentHooksCallbackContext(typeInfo->hooks.binding_ctx);
70 | var context = new ComponentCopyContext(destinationPointer, sourcePointer, count);
71 | data.Hooks.Copy?.Invoke(ref context);
72 | }
73 |
74 | #if !UNITY_5_3_OR_NEWER
75 | [UnmanagedCallersOnly]
76 | #endif
77 | private static void CallbackMove(void* destinationPointer, void* sourcePointer, int count, PInvoke.ecs_type_info_t* typeInfo)
78 | {
79 | ref var data = ref CallbacksHelper.GetComponentHooksCallbackContext(typeInfo->hooks.binding_ctx);
80 | var context = new ComponentMoveContext(destinationPointer, sourcePointer, count);
81 | data.Hooks.Move?.Invoke(ref context);
82 | }
83 |
84 | #if !UNITY_5_3_OR_NEWER
85 | [UnmanagedCallersOnly]
86 | #endif
87 | private static void CallbackOnAdd(ecs_iter_t* it)
88 | {
89 | ref var data = ref CallbacksHelper.GetComponentHooksCallbackContext(it->binding_ctx);
90 | var iterator = new Iterator(data.World, it);
91 | data.Hooks.OnAdd?.Invoke(iterator);
92 | }
93 |
94 | #if !UNITY_5_3_OR_NEWER
95 | [UnmanagedCallersOnly]
96 | #endif
97 | private static void CallbackOnSet(ecs_iter_t* it)
98 | {
99 | ref var data = ref CallbacksHelper.GetComponentHooksCallbackContext(it->binding_ctx);
100 | var iterator = new Iterator(data.World, it);
101 | data.Hooks.OnSet?.Invoke(iterator);
102 | }
103 |
104 | #if !UNITY_5_3_OR_NEWER
105 | [UnmanagedCallersOnly]
106 | #endif
107 | private static void CallbackOnRemove(ecs_iter_t* it)
108 | {
109 | ref var data = ref CallbacksHelper.GetComponentHooksCallbackContext(it->binding_ctx);
110 | var iterator = new Iterator(data.World, it);
111 | data.Hooks.OnRemove?.Invoke(iterator);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/c/production/flecs/include/pinvoke.h:
--------------------------------------------------------------------------------
1 | // Provides macros, types, and functions that make P/Invoke with C# easier.
2 | #pragma once
3 |
4 | #if defined(__APPLE__) && __has_include("TargetConditionals.h")
5 | #include
6 |
7 | // CPUs
8 | #define PINVOKE_TARGET_CPU_X64 TARGET_CPU_X86_64
9 | #define PINVOKE_TARGET_CPU_X86 TARGET_CPU_X86
10 | #define PINVOKE_TARGET_CPU_ARM64 TARGET_CPU_ARM64
11 |
12 | // Desktops
13 | #define PINVOKE_TARGET_OS_WINDOWS 0
14 | #define PINVOKE_TARGET_OS_LINUX 0
15 | #define PINVOKE_TARGET_OS_FREEBSD 0
16 | #define PINVOKE_TARGET_OS_MACOS TARGET_OS_OSX
17 |
18 | // Mobiles
19 | #define PINVOKE_TARGET_OS_IOS TARGET_OS_IOS
20 | #define PINVOKE_TARGET_OS_ANDROID 0
21 |
22 | // Browsers
23 | #if defined(__EMSCRIPTEN__)
24 | #define PINVOKE_TARGET_OS_BROWSER 1
25 | #else
26 | #define PINVOKE_TARGET_OS_BROWSER 0
27 | #endif
28 |
29 | // Compiler environments
30 | #define PINVOKE_TARGET_ENV_MSVC 0
31 | #define PINVOKE_TARGET_ENV_GNU 0
32 | #else
33 |
34 | // CPUs
35 | #if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
36 | #define PINVOKE_TARGET_CPU_X64 1
37 | #else
38 | #define PINVOKE_TARGET_CPU_X64 0
39 | #endif
40 |
41 | #if defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
42 | #define PINVOKE_TARGET_CPU_X86 1
43 | #else
44 | #define PINVOKE_TARGET_CPU_X86 0
45 | #endif
46 |
47 | #if defined(__aarch64__) || defined(_M_ARM64)
48 | #define PINVOKE_TARGET_CPU_ARM64 1
49 | #else
50 | #define PINVOKE_TARGET_CPU_ARM64 0
51 | #endif
52 |
53 | // Desktops
54 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
55 | #define PINVOKE_TARGET_OS_WINDOWS 1
56 | #else
57 | #define PINVOKE_TARGET_OS_WINDOWS 0
58 | #endif
59 |
60 | #if defined(__FreeBSD__)
61 | #define PINVOKE_TARGET_OS_FREEBSD 1
62 | #else
63 | #define PINVOKE_TARGET_OS_FREEBSD 0
64 | #endif
65 |
66 | #if defined(__linux__) && !defined(__ANDROID__)
67 | #define PINVOKE_TARGET_OS_LINUX 1
68 | #else
69 | #define PINVOKE_TARGET_OS_LINUX 0
70 | #endif
71 |
72 | #define PINVOKE_TARGET_OS_MACOS 0
73 |
74 | // Mobiles
75 | #define PINVOKE_TARGET_OS_IOS 0
76 |
77 | #if defined(__ANDROID__)
78 | #define PINVOKE_TARGET_OS_ANDROID 1
79 | #else
80 | #define PINVOKE_TARGET_OS_ANDROID 0
81 | #endif
82 |
83 | // Browsers
84 | #if defined(__EMSCRIPTEN__)
85 | #define PINVOKE_TARGET_OS_BROWSER 1
86 | #else
87 | #define PINVOKE_TARGET_OS_BROWSER 0
88 | #endif
89 |
90 | // Compiler environments
91 | #if defined(_MSC_VER)
92 | #define PINVOKE_TARGET_ENV_MSVC 1
93 | #else
94 | #define PINVOKE_TARGET_ENV_MSVC 0
95 | #endif
96 |
97 | #if defined(__GNUC__)
98 | #define PINVOKE_TARGET_ENV_GNU 1
99 | #else
100 | #define PINVOKE_TARGET_ENV_GNU 0
101 | #endif
102 | #endif
103 |
104 | #if PINVOKE_TARGET_OS_WINDOWS && PINVOKE_TARGET_ENV_GNU
105 | #if PINVOKE_TARGET_CPU_X64
106 | #define PINVOKE_TARGET_NAME "x86_64-pc-windows-gnu"
107 | #elif PINVOKE_TARGET_CPU_X86
108 | #define PINVOKE_TARGET_NAME "i686-pc-windows-gnu"
109 | #elif PINVOKE_TARGET_CPU_ARM64
110 | #define PINVOKE_TARGET_NAME "aarch64-pc-windows-gnu"
111 | #else
112 | #error "Unknown computer architecture for Windows (GNU)."
113 | #endif
114 | #elif PINVOKE_TARGET_OS_WINDOWS && PINVOKE_TARGET_ENV_MSVC
115 | #if PINVOKE_TARGET_CPU_X64
116 | #define PINVOKE_TARGET_NAME "x86_64-pc-windows-msvc"
117 | #elif PINVOKE_TARGET_CPU_X86
118 | #define PINVOKE_TARGET_NAME "i686-pc-windows-msvc"
119 | #elif PINVOKE_TARGET_CPU_ARM64
120 | #define PINVOKE_TARGET_NAME "aarch64-pc-windows-msvc"
121 | #else
122 | #error "Unknown computer architecture for Windows (Microsoft Visual C++)."
123 | #endif
124 | #elif PINVOKE_TARGET_OS_LINUX
125 | #if PINVOKE_TARGET_CPU_X64
126 | #define PINVOKE_TARGET_NAME "x86_64-unknown-linux-gnu"
127 | #elif PINVOKE_TARGET_CPU_X86
128 | #define PINVOKE_TARGET_NAME "i686-unknown-linux-gnu"
129 | #elif PINVOKE_TARGET_CPU_ARM64
130 | #define PINVOKE_TARGET_NAME "aarch64-unknown-linux-gnu"
131 | #else
132 | #error "Unknown computer architecture for Linux."
133 | #endif
134 | #elif PINVOKE_TARGET_OS_FREEBSD
135 | #if PINVOKE_TARGET_CPU_X64
136 | #define PINVOKE_TARGET_NAME "x86_64-unknown-freebsd"
137 | #elif PINVOKE_TARGET_CPU_X86
138 | #define PINVOKE_TARGET_NAME "i686-unknown-freebsd"
139 | #elif PINVOKE_TARGET_CPU_ARM64
140 | #define PINVOKE_TARGET_NAME "aarch64-unknown-freebsd"
141 | #else
142 | #error "Unknown computer architecture for FreeBSD."
143 | #endif
144 | #elif PINVOKE_TARGET_OS_MACOS
145 | #if PINVOKE_TARGET_CPU_X64
146 | #define PINVOKE_TARGET_NAME "x86_64-apple-darwin"
147 | #elif PINVOKE_TARGET_CPU_X86
148 | #define PINVOKE_TARGET_NAME "i686-apple-darwin"
149 | #elif PINVOKE_TARGET_CPU_ARM64
150 | #define PINVOKE_TARGET_NAME "aarch64-apple-darwin"
151 | #else
152 | #error "Unknown computer architecture for macOS."
153 | #endif
154 | #elif PINVOKE_TARGET_OS_IOS
155 | #if PINVOKE_TARGET_CPU_X64
156 | #define PINVOKE_TARGET_NAME "x86_64-apple-ios"
157 | #elif PINVOKE_TARGET_CPU_X86
158 | #define PINVOKE_TARGET_NAME "i686-apple-ios"
159 | #elif PINVOKE_TARGET_CPU_ARM64
160 | #define PINVOKE_TARGET_NAME "aarch64-apple-ios"
161 | #else
162 | #error "Unknown computer architecture for iOS."
163 | #endif
164 | #elif PINVOKE_TARGET_OS_ANDROID
165 | #if PINVOKE_TARGET_CPU_X64
166 | #define PINVOKE_TARGET_NAME "x86_64-linux-android"
167 | #elif PINVOKE_TARGET_CPU_X86
168 | #define PINVOKE_TARGET_NAME "i686-linux-android"
169 | #elif PINVOKE_TARGET_CPU_ARM64
170 | #define PINVOKE_TARGET_NAME "aarch64-linux-android"
171 | #else
172 | #error "Unknown computer architecture for Android."
173 | #endif
174 | #elif PINVOKE_TARGET_OS_BROWSER
175 | #error "WebAssembly is currently not supported!"
176 | #else
177 | #define PINVOKE_TARGET_NAME 0
178 | #endif
179 |
180 | #if PINVOKE_TARGET_OS_WINDOWS
181 | #define PINVOKE_API __declspec(dllexport)
182 | #else
183 | #define PINVOKE_API extern
184 | #endif
185 |
186 | #undef PINVOKE_TARGET_NAME
187 | #undef PINVOKE_TARGET_CPU_X64
188 | #undef PINVOKE_TARGET_CPU_X86
189 | #undef PINVOKE_TARGET_CPU_ARM64
190 | #undef PINVOKE_TARGET_OS_WINDOWS
191 | #undef PINVOKE_TARGET_OS_LINUX
192 | #undef PINVOKE_TARGET_OS_FREEBSD
193 | #undef PINVOKE_TARGET_OS_MACOS
194 | #undef PINVOKE_TARGET_OS_IOS
195 | #undef PINVOKE_TARGET_OS_ANDROID
196 | #undef PINVOKE_TARGET_OS_BROWSER
197 | #undef PINVOKE_TARGET_ENV_MSVC
198 | #undef PINVOKE_TARGET_ENV_GNU
199 |
--------------------------------------------------------------------------------
/src/cs/examples/entities/Flecs.Examples.Entities.RelationComponents/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Flecs.Examples.Entities.RelationComponents;
7 |
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct Requires : IComponent
10 | {
11 | public float Amount;
12 | }
13 |
14 | [StructLayout(LayoutKind.Sequential)]
15 | public struct Expires : IComponent
16 | {
17 | public float Timeout;
18 | }
19 |
20 | [StructLayout(LayoutKind.Sequential)]
21 | public struct Position : IComponent
22 | {
23 | public float X;
24 | public float Y;
25 | }
26 |
27 | public struct Gigawatts : ITag
28 | {
29 | }
30 |
31 | public struct MustHave : ITag
32 | {
33 | }
34 |
35 | internal static class Program
36 | {
37 | private static int Main(string[] args)
38 | {
39 | var world = new World(args);
40 |
41 | world.RegisterComponent();
42 | world.RegisterComponent();
43 | world.RegisterComponent();
44 | world.RegisterTag();
45 | world.RegisterTag();
46 |
47 | // When one element of a pair is a component and the other element is a tag,
48 | // the pair assumes the type of the component.
49 | var e1 = world.CreateEntity("e1");
50 | e1.Set(new Requires() { Amount = 1.21f });
51 | ref var requires1 = ref e1.Get();
52 | Console.WriteLine($"<{nameof(Requires)}, {nameof(Gigawatts)}> (first is value) {nameof(Requires)}: {requires1.Amount}");
53 |
54 | // The component can be either the first or second part of a pair:
55 | var e2 = world.CreateEntity("e2");
56 | e2.Set(new Requires() { Amount = 2.5f });
57 | ref var requires2 = ref e2.GetSecond();
58 | Console.WriteLine($"<{nameof(Gigawatts)}, {nameof(Requires)}> (second is value) {nameof(Requires)}: {requires2.Amount}");
59 |
60 | // Note that and are two
61 | // different pairs, and can be added to an entity at the same time.
62 |
63 | // If both parts of a pair are components, the pair assumes the type of
64 | // the first element:#
65 | // cs binding: GetPairFirstComp <- component value of first
66 | var e3 = world.CreateEntity("e3");
67 | e3.Set(new Expires() { Timeout = 2.5f });
68 | ref var expires = ref e3.Get();
69 | Console.WriteLine($"<{nameof(Expires)}, {nameof(Position)}> (2 comps, first is value) {nameof(Expires)}: {expires.Timeout}");
70 |
71 | // cs binding: GetPairSecondComp <- component value of second
72 | var e4 = world.CreateEntity("e4");
73 | e4.Set(new Position() { X = 0.5f, Y = 1f });
74 | ref var pos = ref e4.GetSecond();
75 | Console.WriteLine($"<{nameof(Expires)}, {nameof(Position)}> (2 comps, second is value) {nameof(Position)}: {pos.X}/{pos.Y}");
76 | Console.WriteLine($"has <{nameof(Expires)}, {nameof(Position)}>: {e4.Has()}");
77 | Console.WriteLine($"has <{nameof(Position)}, {nameof(Expires)}>: {e4.Has()}");
78 | Console.WriteLine();
79 |
80 | var eRuntimeTag = world.CreateEntity("RuntimeTag");
81 | var e5 = world.CreateEntity("e5");
82 | e5.Set(new Position() { X = 0.5f, Y = 1f }, eRuntimeTag);
83 | e5.Set(eRuntimeTag, new Expires() { Timeout = 0.5f });
84 | Console.WriteLine($"has ({nameof(Position)}, {nameof(eRuntimeTag)}): {e5.Has(eRuntimeTag)}");
85 | Console.WriteLine($"has ({nameof(eRuntimeTag)}, {nameof(Position)}): {e5.HasSecond(eRuntimeTag)}");
86 |
87 | Console.WriteLine($"has ({nameof(Expires)}, {nameof(eRuntimeTag)}): {e5.Has(eRuntimeTag)}");
88 | Console.WriteLine($"has ({nameof(eRuntimeTag)}, {nameof(Expires)}): {e5.HasSecond(eRuntimeTag)}");
89 |
90 | ref var e4RuntimePos = ref e5.Get(eRuntimeTag);
91 | ref var e4RuntimeExpires = ref e5.GetSecond(eRuntimeTag);
92 | Console.WriteLine($"({nameof(Position)}, {nameof(eRuntimeTag)}) (2 comps, second is runtime tag) {nameof(Position)}: {e4RuntimePos.X}/{e4RuntimePos.Y}");
93 | Console.WriteLine($"({nameof(eRuntimeTag)}, {nameof(Expires)}) (2 comps, first is runtime tag) {nameof(Expires)}: {e4RuntimeExpires.Timeout}");
94 |
95 | Console.WriteLine("\n\nComponents e1");
96 | IterateComponents(e1);
97 | Console.WriteLine("Components e2");
98 | IterateComponents(e2);
99 | Console.WriteLine("Components e3");
100 | IterateComponents(e3);
101 | Console.WriteLine("Components e4");
102 | IterateComponents(e4);
103 |
104 | return world.Fini();
105 | }
106 |
107 | private static void IterateComponents(Entity entity)
108 | {
109 | // First get the entity's type, which is a vector of (component) ids.
110 | var type = entity.Type();
111 |
112 | // 1. The easiest way to print the components is the type's string
113 | var typeString = type.String();
114 | Console.WriteLine("Type: " + typeString);
115 |
116 | // 2. To print individual ids, iterate the type array with ecs_id_str
117 | var i = 0;
118 | foreach (var identifier in type.Identifiers())
119 | {
120 | var identifierString = identifier.String();
121 | Console.WriteLine(i + ": " + identifierString);
122 | i++;
123 | }
124 |
125 | Console.WriteLine();
126 |
127 | // 3. we can also inspect and print the ids in our own way. This is a
128 | // bit more complicated as we need to handle the edge cases of what can be
129 | // encoded in an id, but provides the most flexibility.
130 | i = 0;
131 | foreach (var identifier in type.Identifiers())
132 | {
133 | Console.Write(i + ": ");
134 |
135 | var roleString = identifier.RoleString();
136 | if (roleString != "UNKNOWN")
137 | {
138 | Console.Write("Role: " + roleString + ", ");
139 | }
140 |
141 | if (identifier.IsPair)
142 | {
143 | var pair = identifier.AsPair();
144 | var relationName = pair.First.Name();
145 | var objectName = pair.Second.Name();
146 | Console.Write("Relation: " + relationName + ", Object: " + objectName);
147 | }
148 | else
149 | {
150 | var component = identifier.AsComponent();
151 | var componentName = component.Name();
152 | Console.Write("Name: " + componentName);
153 | }
154 |
155 | Console.WriteLine();
156 | i++;
157 | }
158 |
159 | Console.WriteLine();
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/World.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.Runtime.CompilerServices;
8 | using System.Runtime.InteropServices;
9 | using bottlenoselabs.C2CS.Runtime;
10 | using JetBrains.Annotations;
11 | using static flecs_hub.Interop.Flecs.PInvoke;
12 |
13 | namespace Flecs;
14 |
15 | [PublicAPI]
16 | public unsafe class World
17 | {
18 | // Relationships
19 | public Entity EcsIsA => new(this, pinvoke_EcsIsA());
20 |
21 | public Entity EcsDependsOn => new(this, pinvoke_EcsDependsOn());
22 |
23 | public Entity EcsChildOf => new(this, pinvoke_EcsChildOf());
24 |
25 | public Entity EcsSlotOf => new(this, pinvoke_EcsSlotOf());
26 |
27 | // Entity tags
28 | public Entity EcsPrefab => new(this, pinvoke_EcsPrefab());
29 |
30 | // System tags
31 | public Entity EcsPreFrame => new(this, pinvoke_EcsPreFrame());
32 |
33 | public Entity EcsOnLoad => new(this, pinvoke_EcsOnLoad());
34 |
35 | public Entity EcsPostLoad => new(this, pinvoke_EcsPostLoad());
36 |
37 | public Entity EcsPreUpdate => new(this, pinvoke_EcsPreUpdate());
38 |
39 | public Entity EcsOnUpdate => new(this, pinvoke_EcsOnUpdate());
40 |
41 | public Entity EcsOnValidate => new(this, pinvoke_EcsOnValidate());
42 |
43 | public Entity EcsPostUpdate => new(this, pinvoke_EcsPostUpdate());
44 |
45 | public Entity EcsPreStore => new(this, pinvoke_EcsPreStore());
46 |
47 | public Entity EcsOnStore => new(this, pinvoke_EcsOnStore());
48 |
49 | public Entity EcsPostFrame => new(this, pinvoke_EcsPostFrame());
50 |
51 | public Entity EcsPhase => new Entity(this, pinvoke_EcsPhase());
52 |
53 | internal static Dictionary Pointers = new();
54 |
55 | internal readonly ecs_world_t* Handle;
56 | // tags = components without data
57 | private Dictionary _componentIdentifiersByType = new();
58 |
59 | public int ExitCode { get; private set; }
60 |
61 | public World(string[] args)
62 | {
63 | var argv = args.Length == 0 ? default : CStrings.CStringArray(args);
64 | Handle = ecs_init_w_args(args.Length, argv);
65 | Pointers.Add((IntPtr)Handle, this);
66 |
67 | for (var i = 0; i < args.Length; i++)
68 | {
69 | Marshal.FreeHGlobal(argv[i].Pointer);
70 | }
71 | }
72 |
73 | public int Fini()
74 | {
75 | Pointers.Remove((IntPtr)Handle);
76 | var exitCode = ecs_fini(Handle);
77 | return exitCode;
78 | }
79 |
80 | public void RegisterComponent(ComponentHooks? hooks = null)
81 | where TComponent : unmanaged
82 | {
83 | var type = typeof(TComponent);
84 | var componentName = GetFlecsTypeName(type);
85 | var structLayoutAttribute = type.StructLayoutAttribute;
86 | CheckStructLayout(structLayoutAttribute);
87 | var structSize = Unsafe.SizeOf();
88 | var structAlignment = structLayoutAttribute!.Pack;
89 | if (structAlignment == 0)
90 | {
91 | structAlignment = 1;
92 | }
93 |
94 | ecs_entity_desc_t entityDesc = default;
95 | entityDesc.name = componentName;
96 | entityDesc.symbol = componentName;
97 | ecs_component_desc_t componentDesc = default;
98 | componentDesc.entity = ecs_entity_init(Handle, &entityDesc);
99 | componentDesc.type.size = structSize;
100 | componentDesc.type.alignment = structAlignment;
101 | var id = ecs_component_init(Handle, &componentDesc);
102 | _componentIdentifiersByType[typeof(TComponent)] = id.Data.Data;
103 | SetHooks(hooks, id);
104 | }
105 |
106 | public void RegisterTag()
107 | where TTag : unmanaged, ITag
108 | {
109 | ecs_entity_desc_t desc = default;
110 | var type = typeof(TTag);
111 | var typeName = GetFlecsTypeName();
112 | desc.name = typeName;
113 | var id = ecs_entity_init(Handle, &desc);
114 | Debug.Assert(id.Data != 0, "ECS_INVALID_PARAMETER");
115 | _componentIdentifiersByType[type] = id.Data.Data;
116 | }
117 |
118 | public void RegisterSystem(
119 | CallbackIterator callback, Entity phase, string filterExpression, string? name = null)
120 | {
121 | RegisterSystem(callback, phase._handle, filterExpression, name);
122 | }
123 |
124 | public void RegisterSystem(
125 | CallbackIterator callback, ecs_entity_t phase, string filterExpression, string? name = null)
126 | {
127 | ecs_system_desc_t desc = default;
128 | FillSystemDescriptorCommon(ref desc, callback, phase, name);
129 |
130 | desc.query.filter.expr = filterExpression;
131 | ecs_system_init(Handle, &desc);
132 | }
133 |
134 | public void RegisterSystem(
135 | CallbackIterator callback, Entity phase, string? name = null)
136 | {
137 | ecs_system_desc_t desc = default;
138 | FillSystemDescriptorCommon(ref desc, callback, phase._handle, name);
139 |
140 | desc.query.filter.expr = GetFlecsTypeName();
141 | ecs_system_init(Handle, &desc);
142 | }
143 |
144 | public void RegisterSystem(
145 | CallbackIterator callback, string? name = null)
146 | {
147 | ecs_system_desc_t desc = default;
148 | // desc.query.filter.name = (Runtime.CString)(name ?? callback.Method.Name);
149 | var phase = EcsOnUpdate;
150 | FillSystemDescriptorCommon(ref desc, callback, phase._handle, name);
151 |
152 | var componentName1 = GetFlecsTypeName();
153 | var componentName2 = GetFlecsTypeName();
154 | desc.query.filter.expr = componentName1 + ", " + componentName2;
155 | ecs_system_init(Handle, &desc);
156 | }
157 |
158 | public Entity CreateEntity(string name)
159 | {
160 | var desc = default(ecs_entity_desc_t);
161 | desc.name = name;
162 | var entity = ecs_entity_init(Handle, &desc);
163 | var result = new Entity(this, entity);
164 | return result;
165 | }
166 |
167 | public Entity CreatePrefab(string name)
168 | {
169 | var desc = default(ecs_entity_desc_t);
170 | desc.name = name;
171 | desc.add[0] = pinvoke_EcsPrefab();
172 |
173 | var entity = ecs_entity_init(Handle, &desc);
174 | var result = new Entity(this, entity);
175 | return result;
176 | }
177 |
178 | public EntityIterator EntityIterator()
179 | where TComponent : unmanaged, IComponent
180 | {
181 | var term = default(ecs_term_t);
182 | term.id = _componentIdentifiersByType[typeof(TComponent)];
183 | var iterator = ecs_term_iter(Handle, &term);
184 | var result = new EntityIterator(this, iterator);
185 | return result;
186 | }
187 |
188 | public bool Progress(float deltaTime)
189 | {
190 | return ecs_progress(Handle, deltaTime);
191 | }
192 |
193 | public string GetFlecsTypeName(Type type)
194 | {
195 | #if !UNITY_5_3_OR_NEWER
196 | #pragma warning disable CA1307
197 | return type.FullName!.Replace("+", ".");
198 | #pragma warning restore CA1307
199 | #else
200 | return type.FullName!.Replace("+", ".", StringComparison.InvariantCulture);
201 | #endif
202 | }
203 |
204 | public string GetFlecsTypeName()
205 | {
206 | return GetFlecsTypeName(typeof(T));
207 | }
208 |
209 | public Identifier GetIdentifier()
210 | where T : unmanaged, IEcsComponent
211 | {
212 | var type = typeof(T);
213 | var containsKey = _componentIdentifiersByType.TryGetValue(type, out var value);
214 | if (!containsKey)
215 | {
216 | RegisterComponent();
217 | value = _componentIdentifiersByType[type];
218 | }
219 |
220 | var id = default(ecs_id_t);
221 | id.Data = value;
222 | return new Identifier(this, id);
223 | }
224 |
225 | private void FillSystemDescriptorCommon(
226 | ref ecs_system_desc_t systemDesc, CallbackIterator callback, ecs_entity_t phase, string? name)
227 | {
228 | ecs_entity_desc_t entityDesc = default;
229 | entityDesc.name = name ?? callback.Method.Name;
230 | entityDesc.add[0] = phase.Data != 0 ? ecs_pair(EcsDependsOn._handle, phase) : default;
231 | entityDesc.add[1] = phase;
232 | systemDesc.entity = ecs_entity_init(Handle, &entityDesc);
233 | #if UNITY_5_3_OR_NEWER
234 | systemDesc.callback.Data.Pointer = Marshal.GetFunctionPointerForDelegate(SystemCallback);
235 | #else
236 | systemDesc.callback.Data.Pointer = &SystemCallback;
237 | #endif
238 | systemDesc.binding_ctx = (void*)CallbacksHelper.CreateSystemCallbackContext(this, callback);
239 | }
240 |
241 | #if !UNITY_5_3_OR_NEWER
242 | [UnmanagedCallersOnly]
243 | #endif
244 | private static void SystemCallback(ecs_iter_t* it)
245 | {
246 | CallbacksHelper.GetSystemCallbackContext((IntPtr)it->binding_ctx, out var data);
247 |
248 | var iterator = new Iterator(data.World, it);
249 | data.Callback(iterator);
250 | }
251 |
252 | private void SetHooks(ComponentHooks? hooksNullable, ecs_entity_t id)
253 | {
254 | if (hooksNullable == null)
255 | {
256 | return;
257 | }
258 |
259 | var hooksDesc = default(ecs_type_hooks_t);
260 | var hooks = hooksNullable.Value;
261 | ComponentHooks.Fill(this, ref hooks, &hooksDesc);
262 | ecs_set_hooks_id(Handle, id, &hooksDesc);
263 | }
264 |
265 | private static void CheckStructLayout(StructLayoutAttribute? structLayoutAttribute)
266 | {
267 | if (structLayoutAttribute == null || structLayoutAttribute.Value == LayoutKind.Auto)
268 | {
269 | throw new FlecsException(
270 | "Component must have a StructLayout attribute with LayoutKind sequential or explicit. This is to ensure that the struct fields are not reorganized by the C# compiler.");
271 | }
272 | }
273 | }
274 |
--------------------------------------------------------------------------------
/src/cs/Flecs.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.1.32210.238
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{9E1476CE-E22E-44FD-ABC4-93625DDBBA99}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Production", "Production", "{39423871-7923-4AFB-A756-35E17FCBA274}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Core", "production\Flecs.Core\Flecs.Core.csproj", "{5EB4443F-134E-43A0-9607-9F3504671E47}"
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Entities", "Entities", "{3DA02832-2DA5-49CC-929D-6DB290DA28EC}"
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.HelloWorld", "examples\Flecs.Examples.HelloWorld\Flecs.Examples.HelloWorld.csproj", "{E5E0E0A5-DF34-403B-A2BD-93EFF21C4825}"
15 | EndProject
16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Entities.Hierarchy", "examples\entities\Flecs.Examples.Entities.Hierarchy\Flecs.Examples.Entities.Hierarchy.csproj", "{603A7B38-8FEF-45A6-8EA7-1AE82D9504C4}"
17 | EndProject
18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Entities.Basics", "examples\entities\Flecs.Examples.Entities.Basics\Flecs.Examples.Entities.Basics.csproj", "{5B604D6C-EDC7-4D7F-8CF4-D368CAE30A37}"
19 | EndProject
20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Entities.Hooks", "examples\entities\Flecs.Examples.Entities.Hooks\Flecs.Examples.Entities.Hooks.csproj", "{CA4D5654-1D45-442E-9C18-F93B1F670263}"
21 | EndProject
22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Entities.IterateComponents", "examples\entities\Flecs.Examples.Entities.IterateComponents\Flecs.Examples.Entities.IterateComponents.csproj", "{449DE999-B69C-43D7-9848-0F4BDE7CCC24}"
23 | EndProject
24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Entities.Prefab", "examples\entities\Flecs.Examples.Entities.Prefab\Flecs.Examples.Entities.Prefab.csproj", "{D298B204-9318-44F9-9330-A1EFAADCD205}"
25 | EndProject
26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Entities.RelationComponents", "examples\entities\Flecs.Examples.Entities.RelationComponents\Flecs.Examples.Entities.RelationComponents.csproj", "{63057DDB-7E98-465D-91AE-396037A0B282}"
27 | EndProject
28 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Entities.RelationBasic", "examples\entities\Flecs.Examples.Entities.RelationBasic\Flecs.Examples.Entities.RelationBasic.csproj", "{EC0A2533-C10C-412F-8D98-7B37AB53FA28}"
29 | EndProject
30 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Queries", "Queries", "{04650426-AD83-4E99-B211-3C70309C6FCF}"
31 | EndProject
32 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Queries.OptionalOr", "examples\queries\Flecs.Examples.Queries.OptionalOr\Flecs.Examples.Queries.OptionalOr.csproj", "{4A8057DB-51F1-4BDB-B40C-1EAAD4620234}"
33 | EndProject
34 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Entities.PrefabSlot", "examples\entities\Flecs.Examples.Entities.PrefabSlot\Flecs.Examples.Entities.PrefabSlot.csproj", "{B8C4D7B7-45C4-46A8-8C7E-03C36F5949B2}"
35 | EndProject
36 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Systems", "Systems", "{36062DD2-C7DC-4074-B1EC-218636DD4B76}"
37 | EndProject
38 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flecs.Examples.Systems.CustomPhase", "examples\systems\Flecs.Examples.Systems.CustomPhase\Flecs.Examples.Systems.CustomPhase.csproj", "{81CFEB14-4C31-4CEF-BE4B-B281EC42D060}"
39 | EndProject
40 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flecs.Unity", "production\Flecs.Unity\Flecs.Unity.csproj", "{45B80105-C0E9-42E0-9D70-D42B65958262}"
41 | EndProject
42 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Flecs.Core", "production\Interop.Flecs.Core\Interop.Flecs.Core.csproj", "{1C5CE028-B4F3-4D18-9BF5-8785103B6138}"
43 | EndProject
44 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Flecs.Unity", "production\Interop.Flecs.Unity\Interop.Flecs.Unity.csproj", "{26B6B8F0-2CAE-4DFC-9F79-9313682F10BA}"
45 | EndProject
46 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Flecs.runtime.linux-x64", "production\Interop.Flecs.runtime.linux-x64\Interop.Flecs.runtime.linux-x64.csproj", "{B6EA6A81-D9D9-4B20-B897-7A8DED05CB00}"
47 | EndProject
48 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Flecs.runtime.osx", "production\Interop.Flecs.runtime.osx\Interop.Flecs.runtime.osx.csproj", "{BFC9867A-C542-401D-AF76-7094D3D4261A}"
49 | EndProject
50 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Flecs.runtime.win-x64", "production\Interop.Flecs.runtime.win-x64\Interop.Flecs.runtime.win-x64.csproj", "{F205AFC3-2ED6-4F65-BD63-7077F3CE07C0}"
51 | EndProject
52 | Global
53 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
54 | Debug|Any CPU = Debug|Any CPU
55 | Release|Any CPU = Release|Any CPU
56 | EndGlobalSection
57 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
58 | {5EB4443F-134E-43A0-9607-9F3504671E47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
59 | {5EB4443F-134E-43A0-9607-9F3504671E47}.Debug|Any CPU.Build.0 = Debug|Any CPU
60 | {5EB4443F-134E-43A0-9607-9F3504671E47}.Release|Any CPU.ActiveCfg = Release|Any CPU
61 | {5EB4443F-134E-43A0-9607-9F3504671E47}.Release|Any CPU.Build.0 = Release|Any CPU
62 | {E5E0E0A5-DF34-403B-A2BD-93EFF21C4825}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
63 | {E5E0E0A5-DF34-403B-A2BD-93EFF21C4825}.Debug|Any CPU.Build.0 = Debug|Any CPU
64 | {E5E0E0A5-DF34-403B-A2BD-93EFF21C4825}.Release|Any CPU.ActiveCfg = Release|Any CPU
65 | {E5E0E0A5-DF34-403B-A2BD-93EFF21C4825}.Release|Any CPU.Build.0 = Release|Any CPU
66 | {603A7B38-8FEF-45A6-8EA7-1AE82D9504C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
67 | {603A7B38-8FEF-45A6-8EA7-1AE82D9504C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
68 | {603A7B38-8FEF-45A6-8EA7-1AE82D9504C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
69 | {603A7B38-8FEF-45A6-8EA7-1AE82D9504C4}.Release|Any CPU.Build.0 = Release|Any CPU
70 | {5B604D6C-EDC7-4D7F-8CF4-D368CAE30A37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
71 | {5B604D6C-EDC7-4D7F-8CF4-D368CAE30A37}.Debug|Any CPU.Build.0 = Debug|Any CPU
72 | {5B604D6C-EDC7-4D7F-8CF4-D368CAE30A37}.Release|Any CPU.ActiveCfg = Release|Any CPU
73 | {5B604D6C-EDC7-4D7F-8CF4-D368CAE30A37}.Release|Any CPU.Build.0 = Release|Any CPU
74 | {CA4D5654-1D45-442E-9C18-F93B1F670263}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
75 | {CA4D5654-1D45-442E-9C18-F93B1F670263}.Debug|Any CPU.Build.0 = Debug|Any CPU
76 | {CA4D5654-1D45-442E-9C18-F93B1F670263}.Release|Any CPU.ActiveCfg = Release|Any CPU
77 | {CA4D5654-1D45-442E-9C18-F93B1F670263}.Release|Any CPU.Build.0 = Release|Any CPU
78 | {449DE999-B69C-43D7-9848-0F4BDE7CCC24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
79 | {449DE999-B69C-43D7-9848-0F4BDE7CCC24}.Debug|Any CPU.Build.0 = Debug|Any CPU
80 | {449DE999-B69C-43D7-9848-0F4BDE7CCC24}.Release|Any CPU.ActiveCfg = Release|Any CPU
81 | {449DE999-B69C-43D7-9848-0F4BDE7CCC24}.Release|Any CPU.Build.0 = Release|Any CPU
82 | {D298B204-9318-44F9-9330-A1EFAADCD205}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
83 | {D298B204-9318-44F9-9330-A1EFAADCD205}.Debug|Any CPU.Build.0 = Debug|Any CPU
84 | {D298B204-9318-44F9-9330-A1EFAADCD205}.Release|Any CPU.ActiveCfg = Release|Any CPU
85 | {D298B204-9318-44F9-9330-A1EFAADCD205}.Release|Any CPU.Build.0 = Release|Any CPU
86 | {63057DDB-7E98-465D-91AE-396037A0B282}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
87 | {63057DDB-7E98-465D-91AE-396037A0B282}.Debug|Any CPU.Build.0 = Debug|Any CPU
88 | {63057DDB-7E98-465D-91AE-396037A0B282}.Release|Any CPU.ActiveCfg = Release|Any CPU
89 | {63057DDB-7E98-465D-91AE-396037A0B282}.Release|Any CPU.Build.0 = Release|Any CPU
90 | {EC0A2533-C10C-412F-8D98-7B37AB53FA28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
91 | {EC0A2533-C10C-412F-8D98-7B37AB53FA28}.Debug|Any CPU.Build.0 = Debug|Any CPU
92 | {EC0A2533-C10C-412F-8D98-7B37AB53FA28}.Release|Any CPU.ActiveCfg = Release|Any CPU
93 | {EC0A2533-C10C-412F-8D98-7B37AB53FA28}.Release|Any CPU.Build.0 = Release|Any CPU
94 | {4A8057DB-51F1-4BDB-B40C-1EAAD4620234}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
95 | {4A8057DB-51F1-4BDB-B40C-1EAAD4620234}.Debug|Any CPU.Build.0 = Debug|Any CPU
96 | {4A8057DB-51F1-4BDB-B40C-1EAAD4620234}.Release|Any CPU.ActiveCfg = Release|Any CPU
97 | {4A8057DB-51F1-4BDB-B40C-1EAAD4620234}.Release|Any CPU.Build.0 = Release|Any CPU
98 | {B8C4D7B7-45C4-46A8-8C7E-03C36F5949B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
99 | {B8C4D7B7-45C4-46A8-8C7E-03C36F5949B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
100 | {B8C4D7B7-45C4-46A8-8C7E-03C36F5949B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
101 | {B8C4D7B7-45C4-46A8-8C7E-03C36F5949B2}.Release|Any CPU.Build.0 = Release|Any CPU
102 | {81CFEB14-4C31-4CEF-BE4B-B281EC42D060}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
103 | {81CFEB14-4C31-4CEF-BE4B-B281EC42D060}.Debug|Any CPU.Build.0 = Debug|Any CPU
104 | {81CFEB14-4C31-4CEF-BE4B-B281EC42D060}.Release|Any CPU.ActiveCfg = Release|Any CPU
105 | {81CFEB14-4C31-4CEF-BE4B-B281EC42D060}.Release|Any CPU.Build.0 = Release|Any CPU
106 | {45B80105-C0E9-42E0-9D70-D42B65958262}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
107 | {45B80105-C0E9-42E0-9D70-D42B65958262}.Debug|Any CPU.Build.0 = Debug|Any CPU
108 | {45B80105-C0E9-42E0-9D70-D42B65958262}.Release|Any CPU.ActiveCfg = Release|Any CPU
109 | {45B80105-C0E9-42E0-9D70-D42B65958262}.Release|Any CPU.Build.0 = Release|Any CPU
110 | {1C5CE028-B4F3-4D18-9BF5-8785103B6138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
111 | {1C5CE028-B4F3-4D18-9BF5-8785103B6138}.Debug|Any CPU.Build.0 = Debug|Any CPU
112 | {1C5CE028-B4F3-4D18-9BF5-8785103B6138}.Release|Any CPU.ActiveCfg = Release|Any CPU
113 | {1C5CE028-B4F3-4D18-9BF5-8785103B6138}.Release|Any CPU.Build.0 = Release|Any CPU
114 | {26B6B8F0-2CAE-4DFC-9F79-9313682F10BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
115 | {26B6B8F0-2CAE-4DFC-9F79-9313682F10BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
116 | {26B6B8F0-2CAE-4DFC-9F79-9313682F10BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
117 | {26B6B8F0-2CAE-4DFC-9F79-9313682F10BA}.Release|Any CPU.Build.0 = Release|Any CPU
118 | {B6EA6A81-D9D9-4B20-B897-7A8DED05CB00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
119 | {B6EA6A81-D9D9-4B20-B897-7A8DED05CB00}.Debug|Any CPU.Build.0 = Debug|Any CPU
120 | {B6EA6A81-D9D9-4B20-B897-7A8DED05CB00}.Release|Any CPU.ActiveCfg = Release|Any CPU
121 | {B6EA6A81-D9D9-4B20-B897-7A8DED05CB00}.Release|Any CPU.Build.0 = Release|Any CPU
122 | {BFC9867A-C542-401D-AF76-7094D3D4261A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
123 | {BFC9867A-C542-401D-AF76-7094D3D4261A}.Debug|Any CPU.Build.0 = Debug|Any CPU
124 | {BFC9867A-C542-401D-AF76-7094D3D4261A}.Release|Any CPU.ActiveCfg = Release|Any CPU
125 | {BFC9867A-C542-401D-AF76-7094D3D4261A}.Release|Any CPU.Build.0 = Release|Any CPU
126 | {F205AFC3-2ED6-4F65-BD63-7077F3CE07C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
127 | {F205AFC3-2ED6-4F65-BD63-7077F3CE07C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
128 | {F205AFC3-2ED6-4F65-BD63-7077F3CE07C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
129 | {F205AFC3-2ED6-4F65-BD63-7077F3CE07C0}.Release|Any CPU.Build.0 = Release|Any CPU
130 | EndGlobalSection
131 | GlobalSection(SolutionProperties) = preSolution
132 | HideSolutionNode = FALSE
133 | EndGlobalSection
134 | GlobalSection(NestedProjects) = preSolution
135 | {5EB4443F-134E-43A0-9607-9F3504671E47} = {39423871-7923-4AFB-A756-35E17FCBA274}
136 | {3DA02832-2DA5-49CC-929D-6DB290DA28EC} = {9E1476CE-E22E-44FD-ABC4-93625DDBBA99}
137 | {E5E0E0A5-DF34-403B-A2BD-93EFF21C4825} = {9E1476CE-E22E-44FD-ABC4-93625DDBBA99}
138 | {603A7B38-8FEF-45A6-8EA7-1AE82D9504C4} = {3DA02832-2DA5-49CC-929D-6DB290DA28EC}
139 | {5B604D6C-EDC7-4D7F-8CF4-D368CAE30A37} = {3DA02832-2DA5-49CC-929D-6DB290DA28EC}
140 | {CA4D5654-1D45-442E-9C18-F93B1F670263} = {3DA02832-2DA5-49CC-929D-6DB290DA28EC}
141 | {449DE999-B69C-43D7-9848-0F4BDE7CCC24} = {3DA02832-2DA5-49CC-929D-6DB290DA28EC}
142 | {D298B204-9318-44F9-9330-A1EFAADCD205} = {3DA02832-2DA5-49CC-929D-6DB290DA28EC}
143 | {63057DDB-7E98-465D-91AE-396037A0B282} = {3DA02832-2DA5-49CC-929D-6DB290DA28EC}
144 | {EC0A2533-C10C-412F-8D98-7B37AB53FA28} = {3DA02832-2DA5-49CC-929D-6DB290DA28EC}
145 | {04650426-AD83-4E99-B211-3C70309C6FCF} = {9E1476CE-E22E-44FD-ABC4-93625DDBBA99}
146 | {4A8057DB-51F1-4BDB-B40C-1EAAD4620234} = {04650426-AD83-4E99-B211-3C70309C6FCF}
147 | {B8C4D7B7-45C4-46A8-8C7E-03C36F5949B2} = {3DA02832-2DA5-49CC-929D-6DB290DA28EC}
148 | {36062DD2-C7DC-4074-B1EC-218636DD4B76} = {9E1476CE-E22E-44FD-ABC4-93625DDBBA99}
149 | {81CFEB14-4C31-4CEF-BE4B-B281EC42D060} = {36062DD2-C7DC-4074-B1EC-218636DD4B76}
150 | {45B80105-C0E9-42E0-9D70-D42B65958262} = {39423871-7923-4AFB-A756-35E17FCBA274}
151 | {1C5CE028-B4F3-4D18-9BF5-8785103B6138} = {39423871-7923-4AFB-A756-35E17FCBA274}
152 | {26B6B8F0-2CAE-4DFC-9F79-9313682F10BA} = {39423871-7923-4AFB-A756-35E17FCBA274}
153 | {B6EA6A81-D9D9-4B20-B897-7A8DED05CB00} = {39423871-7923-4AFB-A756-35E17FCBA274}
154 | {BFC9867A-C542-401D-AF76-7094D3D4261A} = {39423871-7923-4AFB-A756-35E17FCBA274}
155 | {F205AFC3-2ED6-4F65-BD63-7077F3CE07C0} = {39423871-7923-4AFB-A756-35E17FCBA274}
156 | EndGlobalSection
157 | GlobalSection(ExtensibilityGlobals) = postSolution
158 | SolutionGuid = {C4B6B4B9-1CB6-414C-BF33-521394D6CD71}
159 | EndGlobalSection
160 | EndGlobal
161 |
--------------------------------------------------------------------------------
/src/cs/production/Flecs.Core/Entity.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Flecs Hub (https://github.com/flecs-hub). All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the Git repository root directory for full license information.
3 |
4 | using System.Runtime.CompilerServices;
5 | using System.Runtime.InteropServices;
6 | using bottlenoselabs.C2CS.Runtime;
7 | using JetBrains.Annotations;
8 | using static flecs_hub.Interop.Flecs.PInvoke;
9 |
10 | namespace Flecs;
11 |
12 | [PublicAPI]
13 | public readonly unsafe struct Entity
14 | {
15 | internal readonly ecs_entity_t _handle;
16 | private readonly World _world;
17 |
18 | internal Entity(World world, ecs_entity_t handle)
19 | {
20 | _world = world;
21 | _handle = handle;
22 | }
23 |
24 | public static Entity FromIdentifier(Identifier identifier)
25 | {
26 | return new Entity(identifier.World, identifier.Handle);
27 | }
28 |
29 | public EntityType Type()
30 | {
31 | var type = ecs_get_type(_world.Handle, _handle);
32 | var result = new EntityType(_world, type);
33 | return result;
34 | }
35 |
36 | public void Add()
37 | where T : unmanaged, IEcsComponent
38 | {
39 | var tagId = _world.GetIdentifier();
40 | ecs_add_id(_world.Handle, _handle, tagId.Handle);
41 | }
42 |
43 | public void Add(Entity entity)
44 | {
45 | ecs_add_id(_world.Handle, _handle, entity._handle);
46 | }
47 |
48 | public void Remove()
49 | where T : unmanaged, IEcsComponent
50 | {
51 | var tagId = _world.GetIdentifier();
52 | ecs_remove_id(_world.Handle, _handle, tagId.Handle);
53 | }
54 |
55 | public void Remove(Entity entity)
56 | {
57 | ecs_remove_id(_world.Handle, _handle, entity._handle);
58 | }
59 |
60 | public void Add()
61 | where TTag1 : unmanaged, ITag
62 | where TTag2 : unmanaged, ITag
63 | {
64 | var tagId1 = _world.GetIdentifier();
65 | var tagId2 = _world.GetIdentifier();
66 | var id = ecs_pair(tagId1.Handle, tagId2.Handle);
67 | ecs_add_id(_world.Handle, _handle, id);
68 | }
69 |
70 | public void AddOverride()
71 | where TTag1 : unmanaged, ITag
72 | where TTag2 : unmanaged, ITag
73 | {
74 | var tagId1 = _world.GetIdentifier();
75 | var tagId2 = _world.GetIdentifier();
76 | var id = ecs_pair(tagId1.Handle, tagId2.Handle);
77 | ecs_override_id(_world.Handle, _handle, id);
78 | }
79 |
80 | public void Add(Entity first, Entity second)
81 | {
82 | var id = ecs_pair(first._handle, second._handle);
83 | ecs_add_id(_world.Handle, _handle, id);
84 | }
85 |
86 | public void AddOverride(Entity first, Entity second)
87 | {
88 | var id = ecs_pair(first._handle, second._handle);
89 | ecs_override_id(_world.Handle, _handle, id);
90 | }
91 |
92 | public void Add(Entity first)
93 | where TTag : unmanaged, ITag
94 | {
95 | var tagId = _world.GetIdentifier();
96 | var id = ecs_pair(first._handle, tagId.Handle);
97 | ecs_add_id(_world.Handle, _handle, id);
98 | }
99 |
100 | public void AddOverride(Entity first)
101 | where TTag : unmanaged, ITag
102 | {
103 | var tagId = _world.GetIdentifier();
104 | var id = ecs_pair(first._handle, tagId.Handle);
105 | ecs_override_id(_world.Handle, _handle, id);
106 | }
107 |
108 | public void AddSecond(Entity second)
109 | where TTag : unmanaged, ITag
110 | {
111 | var tagId = _world.GetIdentifier();
112 | var id = ecs_pair(tagId.Handle, second._handle);
113 | ecs_add_id(_world.Handle, _handle, id);
114 | }
115 |
116 | public void AddSecondOverride(Entity second)
117 | where TTag : unmanaged, ITag
118 | {
119 | var tagId = _world.GetIdentifier();
120 | var id = ecs_pair(tagId.Handle, second._handle);
121 | ecs_override_id(_world.Handle, _handle, id);
122 | }
123 |
124 | public void Set(TComponent component) // right comp
125 | where TEcsComponent : unmanaged, IEcsComponent
126 | where TComponent : unmanaged, IComponent
127 | {
128 | var ecsCompId = _world.GetIdentifier();
129 | var compId = _world.GetIdentifier();
130 | SetPairData(component, ecsCompId, compId);
131 | }
132 |
133 | public void SetOverride(TComponent component) // right comp
134 | where TEcsComponent : unmanaged, IEcsComponent
135 | where TComponent : unmanaged, IComponent
136 | {
137 | var ecsCompId = _world.GetIdentifier();
138 | var compId = _world.GetIdentifier();
139 | SetPairDataOverride(component, ecsCompId, compId);
140 | }
141 |
142 | public void Set(TComponent component) // left comp
143 | where TComponent : unmanaged, IComponent
144 | where TEcsComponent : unmanaged, IEcsComponent
145 | {
146 | var compId = _world.GetIdentifier();
147 | var ecsCompId = _world.GetIdentifier();
148 | SetPairData(component, compId, ecsCompId);
149 | }
150 |
151 | public void SetOverride(TComponent component) // left comp
152 | where TComponent : unmanaged, IComponent
153 | where TEcsComponent : unmanaged, IEcsComponent
154 | {
155 | var compId = _world.GetIdentifier();
156 | var ecsCompId = _world.GetIdentifier();
157 | SetPairData(component, compId, ecsCompId);
158 | }
159 |
160 | public void Set(TComponent first, Entity second) // assume left comp, right is used as tag
161 | where TComponent : unmanaged, IComponent
162 | {
163 | var firstId = _world.GetIdentifier();
164 | var secondId = new Identifier(_world, second._handle);
165 | SetPairData(first, firstId, secondId);
166 | }
167 |
168 | public void SetOverride(TComponent first, Entity second) // assume left comp, right is used as tag
169 | where TComponent : unmanaged, IComponent
170 | {
171 | var firstId = _world.GetIdentifier();
172 | var secondId = new Identifier(_world, second._handle);
173 | SetPairDataOverride(first, firstId, secondId);
174 | }
175 |
176 | public void Set(Entity first, TComponent second) // assume left comp, right is used as tag
177 | where TComponent : unmanaged, IComponent
178 | {
179 | var firstId = new Identifier(_world, first._handle);
180 | var secondId = _world.GetIdentifier();
181 | SetPairData(second, firstId, secondId);
182 | }
183 |
184 | public void SetOverride(Entity first, TComponent second) // assume left comp, right is used as tag
185 | where TComponent : unmanaged, IComponent
186 | {
187 | var firstId = new Identifier(_world, first._handle);
188 | var secondId = _world.GetIdentifier();
189 | SetPairDataOverride(second, firstId, secondId);
190 | }
191 |
192 | public ref TComponent Get()
193 | where TComponent : unmanaged, IComponent
194 | where TEscComponent : unmanaged, IEcsComponent
195 | {
196 | var compId = _world.GetIdentifier();
197 | var tagId = _world.GetIdentifier();
198 | return ref GetPairData(compId, tagId);
199 | }
200 |
201 | public ref TComponent GetSecond()
202 | where TEscComponent : unmanaged, IEcsComponent
203 | where TComponent : unmanaged, IComponent
204 | {
205 | var tagId = _world.GetIdentifier();
206 | var compId = _world.GetIdentifier();
207 | return ref GetPairData(tagId, compId);
208 | }
209 |
210 | public ref TComponent Get(Entity second)
211 | where TComponent : unmanaged, IComponent
212 | {
213 | var compId = _world.GetIdentifier();
214 | return ref GetPairData(compId, new Identifier(_world, second._handle));
215 | }
216 |
217 | public ref TComponent GetSecond(Entity first)
218 | where TComponent : unmanaged, IComponent
219 | {
220 | var compId = _world.GetIdentifier();
221 | return ref GetPairData(new Identifier(_world, first._handle), compId);
222 | }
223 |
224 | public Entity GetTarget(Entity relation)
225 | {
226 | var target = ecs_get_target(_world.Handle, _handle, relation._handle, 0);
227 | return new Entity(_world, target);
228 | }
229 |
230 | public void AddParent(Entity entity)
231 | {
232 | var id = ecs_pair(EcsChildOf, entity._handle);
233 | ecs_add_id(_world.Handle, _handle, id);
234 | }
235 |
236 | public void IsA(Entity entity)
237 | {
238 | var id = ecs_pair(EcsIsA, entity._handle);
239 | ecs_add_id(_world.Handle, _handle, id);
240 | }
241 |
242 | public void AddSlotOf(Entity entity)
243 | {
244 | var id = ecs_pair(EcsSlotOf, entity._handle);
245 | ecs_add_id(_world.Handle, _handle, id);
246 | }
247 |
248 | public ref TComponent GetComponent()
249 | where TComponent : unmanaged, IComponent
250 | {
251 | var componentId = _world.GetIdentifier();
252 | var pointer = ecs_get_id(_world.Handle, _handle, componentId.Handle);
253 | return ref Unsafe.AsRef(pointer);
254 | }
255 |
256 | public void Set(ref TComponent component)
257 | where TComponent : unmanaged, IComponent
258 | {
259 | var componentId = _world.GetIdentifier();
260 | var structSize = Unsafe.SizeOf();
261 | var pointer = Unsafe.AsPointer(ref component);
262 | ecs_set_id(_world.Handle, _handle, componentId.Handle, (ulong)structSize, pointer);
263 | }
264 |
265 | public void Set(TComponent component)
266 | where TComponent : unmanaged, IComponent
267 | {
268 | Set(ref component);
269 | }
270 |
271 | public void SetOverride(ref TComponent component)
272 | where TComponent : unmanaged, IComponent
273 | {
274 | var componentId = _world.GetIdentifier();
275 | var structSize = Unsafe.SizeOf();
276 | var pointer = Unsafe.AsPointer(ref component);
277 |
278 | var overrideValue = ECS_OVERRIDE.Data;
279 | var identifierValue = overrideValue | componentId.Handle.Data;
280 | ecs_add_id(_world.Handle, _handle, *(ecs_id_t*)&identifierValue);
281 | ecs_set_id(_world.Handle, _handle, componentId.Handle, (ulong)structSize, pointer);
282 | }
283 |
284 | public void SetOverride(TComponent component)
285 | where TComponent : unmanaged, IComponent
286 | {
287 | SetOverride(ref component);
288 | }
289 |
290 | public void Delete()
291 | {
292 | ecs_delete(_world.Handle, _handle);
293 | }
294 |
295 | public string Name()
296 | {
297 | var result = ecs_get_name(_world.Handle, _handle);
298 | return result.ToString();
299 | }
300 |
301 | public bool Has()
302 | where T : unmanaged, IEcsComponent
303 | {
304 | var compId = _world.GetIdentifier();
305 | return ecs_has_id(_world.Handle, _handle, compId.Handle);
306 | }
307 |
308 | public bool Has()
309 | where T1 : unmanaged, IEcsComponent
310 | where T2 : unmanaged, IEcsComponent
311 | {
312 | var id1 = _world.GetIdentifier();
313 | var id2 = _world.GetIdentifier();
314 | var id = ecs_pair(id1.Handle, id2.Handle);
315 | return ecs_has_id(_world.Handle, _handle, id);
316 | }
317 |
318 | public bool Has(Entity first, Entity second)
319 | {
320 | var id = ecs_pair(first._handle, second._handle);
321 | return ecs_has_id(_world.Handle, _handle, id);
322 | }
323 |
324 | public bool Has(Entity second)
325 | where T : unmanaged, IEcsComponent
326 | {
327 | var compId = _world.GetIdentifier();
328 | var id = ecs_pair(compId.Handle, second._handle);
329 | return ecs_has_id(_world.Handle, _handle, id);
330 | }
331 |
332 | public bool HasSecond(Entity first)
333 | where T : unmanaged, IEcsComponent
334 | {
335 | var compId = _world.GetIdentifier();
336 | var id = ecs_pair(first._handle, compId.Handle);
337 | return ecs_has_id(_world.Handle, _handle, id);
338 | }
339 |
340 | public void DependsOn(Entity entity)
341 | {
342 | Add(new Entity(_world, EcsDependsOn), entity);
343 | }
344 |
345 | public bool IsChildOf(Entity entity)
346 | {
347 | var pair = ecs_childof(entity._handle);
348 | var result = ecs_has_id(_world.Handle, _handle, pair);
349 | return result;
350 | }
351 |
352 | public string FullPathString()
353 | {
354 | var cString = ecs_get_path_w_sep(_world.Handle, default, _handle, (CString)".", default);
355 | var result = Marshal.PtrToStringAnsi(cString.Pointer)!;
356 | Marshal.FreeHGlobal(cString.Pointer);
357 | return result;
358 | }
359 |
360 | public EntityIterator Children()
361 | {
362 | var term = default(ecs_term_t);
363 | term.id = ecs_childof(_handle);
364 | var iterator = ecs_term_iter(_world.Handle, &term);
365 | var result = new EntityIterator(_world, iterator);
366 | return result;
367 | }
368 |
369 | private ref TComp GetPairData(Identifier first, Identifier second)
370 | where TComp : unmanaged, IComponent
371 | {
372 | var id = ecs_pair(first.Handle, second.Handle);
373 | var pointer = ecs_get_id(_world.Handle, _handle, id);
374 | return ref Unsafe.AsRef(pointer);
375 | }
376 |
377 | private void SetPairData(TComponent component, Identifier left, Identifier right)
378 | where TComponent : unmanaged, IComponent
379 | {
380 | var id = ecs_pair(left.Handle, right.Handle);
381 | var structSize = Unsafe.SizeOf();
382 | var pointer = Unsafe.AsPointer(ref component);
383 | ecs_set_id(_world.Handle, _handle, id, (ulong)structSize, pointer);
384 | }
385 |
386 | private void SetPairDataOverride(TComponent component, Identifier left, Identifier right)
387 | where TComponent : unmanaged, IComponent
388 | {
389 | var id = ecs_pair(left.Handle, right.Handle);
390 | var structSize = Unsafe.SizeOf();
391 | var pointer = Unsafe.AsPointer(ref component);
392 | ecs_override_id(_world.Handle, _handle, id);
393 | ecs_set_id(_world.Handle, _handle, id, (ulong)structSize, pointer);
394 | }
395 | }
396 |
--------------------------------------------------------------------------------