├── .gitattributes
├── .gitignore
├── DragonECS.asmdef
├── DragonECS.asmdef.meta
├── DragonECS.csproj
├── DragonECS.csproj.meta
├── LICENSE.md
├── LICENSE.md.meta
├── README-RU.md
├── README-RU.md.meta
├── README-ZH.md
├── README-ZH.md.meta
├── README.md
├── README.md.meta
├── package.json
├── package.json.meta
├── src.meta
└── src
├── Builtin.meta
├── Builtin
├── Aspects.cs
├── Aspects.cs.meta
├── BaseProcesses.cs
├── BaseProcesses.cs.meta
├── Worlds.cs
└── Worlds.cs.meta
├── Collections.meta
├── Collections
├── EcsGroup.cs
├── EcsGroup.cs.meta
├── EcsSpan.cs
└── EcsSpan.cs.meta
├── Consts.cs
├── Consts.cs.meta
├── DataInterfaces.cs
├── DataInterfaces.cs.meta
├── DebugUtils.meta
├── DebugUtils
├── EcsDebug.cs
├── EcsDebug.cs.meta
├── EcsDebugUtility.cs
├── EcsDebugUtility.cs.meta
├── Interfaces.meta
├── Interfaces
│ ├── IEcsTypeMetaProvider.cs
│ └── IEcsTypeMetaProvider.cs.meta
├── MetaAttributes.meta
├── MetaAttributes
│ ├── EcsMetaAttribute.cs
│ ├── EcsMetaAttribute.cs.meta
│ ├── MetaColorAttribute.cs
│ ├── MetaColorAttribute.cs.meta
│ ├── MetaDescriptionAttribute.cs
│ ├── MetaDescriptionAttribute.cs.meta
│ ├── MetaGroupAttribute.cs
│ ├── MetaGroupAttribute.cs.meta
│ ├── MetaIDAttribute.cs
│ ├── MetaIDAttribute.cs.meta
│ ├── MetaNameAttribute.cs
│ ├── MetaNameAttribute.cs.meta
│ ├── MetaTagsAttribute.cs
│ └── MetaTagsAttribute.cs.meta
├── TypeMeta.cs
└── TypeMeta.cs.meta
├── EcsAspect.cs
├── EcsAspect.cs.meta
├── EcsMask.cs
├── EcsMask.cs.meta
├── EcsPipeline.Builder.cs
├── EcsPipeline.Builder.cs.meta
├── EcsPipeline.cs
├── EcsPipeline.cs.meta
├── EcsRunner.cs
├── EcsRunner.cs.meta
├── EcsStaticMask.cs
├── EcsStaticMask.cs.meta
├── EcsWorld.cache.cs
├── EcsWorld.cache.cs.meta
├── EcsWorld.cs
├── EcsWorld.cs.meta
├── EcsWorld.pools.cs
├── EcsWorld.pools.cs.meta
├── EcsWorld.static.cs
├── EcsWorld.static.cs.meta
├── Executors.meta
├── Executors
├── EcsWhereExecutor.cs
├── EcsWhereExecutor.cs.meta
├── EcsWhereToGroupExecutor.cs
├── EcsWhereToGroupExecutor.cs.meta
├── MaskQueryExecutor.cs
├── MaskQueryExecutor.cs.meta
├── Queries.cs
└── Queries.cs.meta
├── Injections.meta
├── Injections
├── EcsPipelineExtensions.cs
├── EcsPipelineExtensions.cs.meta
├── Graph.meta
├── Graph
│ ├── InjectionBranch.cs
│ ├── InjectionBranch.cs.meta
│ ├── InjectionNode.cs
│ └── InjectionNode.cs.meta
├── Injector.cs
├── Injector.cs.meta
├── Utils.meta
└── Utils
│ ├── Interfaces.cs
│ └── Interfaces.cs.meta
├── Internal.meta
├── Internal
├── Allocators.meta
├── Allocators
│ ├── AllocatorUtility.cs
│ ├── AllocatorUtility.cs.meta
│ ├── MemoryAllocator.cs
│ ├── MemoryAllocator.cs.meta
│ ├── TempBuffer.cs
│ └── TempBuffer.cs.meta
├── ArraySortHalperX.cs
├── ArraySortHalperX.cs.meta
├── ArrayUtility.cs
├── ArrayUtility.cs.meta
├── BitsUtility.cs
├── BitsUtility.cs.meta
├── EcsTypeCodeManager.cs
├── EcsTypeCodeManager.cs.meta
├── IdDispenser.cs
├── IdDispenser.cs.meta
├── ReflectionUtility.cs
├── ReflectionUtility.cs.meta
├── SparseArray.cs
├── SparseArray.cs.meta
├── StructList.cs
├── StructList.cs.meta
├── UnsafeArray.cs
└── UnsafeArray.cs.meta
├── Pools.meta
├── Pools
├── EcsPool.cs
├── EcsPool.cs.meta
├── EcsPoolBase.cs
├── EcsPoolBase.cs.meta
├── EcsTagPool.cs
└── EcsTagPool.cs.meta
├── Utils.meta
├── Utils
├── AllowedInWorldsAttribute.cs
├── AllowedInWorldsAttribute.cs.meta
├── DependencyGraph.cs
├── DependencyGraph.cs.meta
├── EcsPipelineTemplate.cs
├── EcsPipelineTemplate.cs.meta
├── EcsTypeCode.cs
├── EcsTypeCode.cs.meta
├── Exceptions.cs
├── Exceptions.cs.meta
├── IConfigContainer.cs
├── IConfigContainer.cs.meta
├── ITemplateNode.cs
├── ITemplateNode.cs.meta
├── LayersMap.cs
├── LayersMap.cs.meta
├── ReadOnlySpanDummy.cs
├── ReadOnlySpanDummy.cs.meta
├── Uncheked.meta
└── Uncheked
│ ├── EntitiesMatrix.cs
│ ├── EntitiesMatrix.cs.meta
│ ├── EntitySlotInfo.cs
│ ├── EntitySlotInfo.cs.meta
│ ├── UncheckedUtility.cs
│ └── UncheckedUtility.cs.meta
├── entlong.cs
└── entlong.cs.meta
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This .gitignore file should be placed at the root of your Unity project directory
2 | #
3 | # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
4 | #
5 | /[Ll]ibrary/
6 | /[Tt]emp/
7 | /[Oo]bj/
8 | /[Bb]uild/
9 | /[Bb]uilds/
10 | /[Ll]ogs/
11 | /[Uu]ser[Ss]ettings/
12 |
13 | # MemoryCaptures can get excessive in size.
14 | # They also could contain extremely sensitive data
15 | /[Mm]emoryCaptures/
16 |
17 | # Recordings can get excessive in size
18 | /[Rr]ecordings/
19 |
20 | # Uncomment this line if you wish to ignore the asset store tools plugin
21 | # /[Aa]ssets/AssetStoreTools*
22 |
23 | # Autogenerated Jetbrains Rider plugin
24 | /[Aa]ssets/Plugins/Editor/JetBrains*
25 |
26 | # Visual Studio cache directory
27 | .vs/
28 |
29 | # Rider settings directory
30 | .idea/
31 |
32 | # Gradle cache directory
33 | .gradle/
34 |
35 | # Autogenerated VS/MD/Consulo solution and project files
36 | ExportedObj/
37 | .consulo/
38 | *.csproj
39 | *.unityproj
40 | *.sln
41 | *.sln.meta
42 | *.suo
43 | *.tmp
44 | *.user
45 | *.userprefs
46 | *.pidb
47 | *.booproj
48 | *.svd
49 | *.pdb
50 | *.mdb
51 | *.opendb
52 | *.VC.db
53 |
54 | # Unity3D generated meta files
55 | *.pidb.meta
56 | *.pdb.meta
57 | *.mdb.meta
58 |
59 | # Unity3D generated file on crash reports
60 | sysinfo.txt
61 |
62 | # Builds
63 | *.apk
64 | *.aab
65 | *.unitypackage
66 | *.app
67 |
68 | # Crashlytics generated file
69 | crashlytics-build.properties
70 |
71 | # Packed Addressables
72 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
73 |
74 | # Temporary auto-generated Android Assets
75 | /[Aa]ssets/[Ss]treamingAssets/aa.meta
76 | /[Aa]ssets/[Ss]treamingAssets/aa/*
77 |
78 | # Don't ignore main csproj file
79 | !DragonECS.csproj
80 |
81 | # Build results
82 | [Dd]ebug/
83 | [Dd]ebugPublic/
84 | [Rr]elease/
85 | [Rr]eleases/
86 | x64/
87 | x86/
88 | [Ww][Ii][Nn]32/
89 | [Aa][Rr][Mm]/
90 | [Aa][Rr][Mm]64/
91 | bld/
92 | [Bb]in/
93 | [Oo]bj/
94 | [Ll]og/
95 | [Ll]ogs/
96 |
97 | [Bb]in.meta
98 | [Oo]bj.meta
99 |
--------------------------------------------------------------------------------
/DragonECS.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DCFApixels.DragonECS",
3 | "rootNamespace": "DCFApixels",
4 | "references": [],
5 | "includePlatforms": [],
6 | "excludePlatforms": [],
7 | "allowUnsafeCode": true,
8 | "overrideReferences": false,
9 | "precompiledReferences": [],
10 | "autoReferenced": true,
11 | "defineConstraints": [],
12 | "versionDefines": [],
13 | "noEngineReferences": false
14 | }
--------------------------------------------------------------------------------
/DragonECS.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: abb125fa67fff1e45914d0825236f608
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/DragonECS.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.1
5 | 7.3
6 | disable
7 | disable
8 | true
9 | true
10 | DCFApixels.DragonECS
11 |
12 | DragonECS
13 | 0.9.14
14 | DCFApixels
15 | ECS Framework for Game Engines with C# and .Net Platform
16 | DCFApixels
17 | https://github.com/DCFApixels/DragonECS
18 | https://github.com/DCFApixels/DragonECS/blob/main/LICENSE.meta
19 | ecs; gamedev; unity; dragonecs
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/DragonECS.csproj.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 804a6bf72b77a844495db239765f33ca
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Mikhail(DCFApixels)
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.
22 |
--------------------------------------------------------------------------------
/LICENSE.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 511a67a8d03bfd74ca360bf03efad8a1
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README-RU.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8ef74daf0189576458371bc1d5142cf7
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README-ZH.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 877c188fb31b69045adeec8ca9a19b33
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c616a590311a3c441ba37782d0d09ba1
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "com.dcfa_pixels.dragonecs",
3 | "author":
4 | {
5 | "name": "DCFApixels",
6 | "url": "https://github.com/DCFApixels"
7 | },
8 | "displayName": "DragonECS",
9 | "description": "C# Entity Component System Framework",
10 | "unity": "2020.3",
11 | "version": "0.9.14",
12 | "repository": {
13 | "type": "git",
14 | "url": "https://github.com/DCFApixels/DragonECS.git"
15 | },
16 | "dependencies": { },
17 | "keywords":
18 | [
19 | "ecs",
20 | "performance",
21 | "dragonecs",
22 | "dragon-ecs",
23 | "framework"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/package.json.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 91e9ced1e8db96749b60772426d75c61
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/src.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0192fd952d3f4a24d8057af65f35d8e1
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Builtin.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f9f604669d2092e4a92d397e9c7db287
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Builtin/Aspects.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 53ad81582cda81545bfe9dfca9ee4892
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Builtin/BaseProcesses.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.RunnersCore;
5 | using System;
6 |
7 | namespace DCFApixels.DragonECS
8 | {
9 | [MetaName(nameof(PreInit))]
10 | [MetaColor(MetaColor.DragonRose)]
11 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
12 | [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Init() is called. Before Init")]
13 | [MetaID("DragonECS_DE26527C92015AFDD4ECF4D81A4C946B")]
14 | public interface IEcsPreInit : IEcsProcess
15 | {
16 | void PreInit();
17 | }
18 | [MetaName(nameof(Init))]
19 | [MetaColor(MetaColor.DragonRose)]
20 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
21 | [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Init() is called. After PreInit")]
22 | [MetaID("DragonECS_CC45527C9201DF82DCAAAEF33072F9EF")]
23 | public interface IEcsInit : IEcsProcess
24 | {
25 | void Init();
26 | }
27 | [MetaName(nameof(Run))]
28 | [MetaColor(MetaColor.DragonRose)]
29 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
30 | [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Run() is called.")]
31 | [MetaID("DragonECS_9654527C9201BE75546322B9BB03C131")]
32 | public interface IEcsRun : IEcsProcess
33 | {
34 | void Run();
35 | }
36 | [MetaName(nameof(RunFinally))]
37 | [MetaColor(MetaColor.DragonRose)]
38 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
39 | public interface IEcsRunFinally : IEcsProcess
40 | {
41 | void RunFinally();
42 | }
43 | [MetaName(nameof(Destroy))]
44 | [MetaColor(MetaColor.DragonRose)]
45 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
46 | [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Destroy() is called.")]
47 | [MetaID("DragonECS_4661527C9201EE669C6EB61B19899AE5")]
48 | public interface IEcsDestroy : IEcsProcess
49 | {
50 | void Destroy();
51 | }
52 | }
53 |
54 | namespace DCFApixels.DragonECS.Core.Internal
55 | {
56 | #if ENABLE_IL2CPP
57 | using Unity.IL2CPP.CompilerServices;
58 | [Il2CppSetOption(Option.NullChecks, false)]
59 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
60 | #endif
61 | [MetaColor(MetaColor.DragonRose)]
62 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
63 | [MetaDescription(EcsConsts.AUTHOR, "...")]
64 | [MetaTags(MetaTags.HIDDEN)]
65 | [MetaID("DragonECS_3273527C9201285BAA0A463F700A50FB")]
66 | internal sealed class EcsPreInitRunner : EcsRunner, IEcsPreInit
67 | {
68 | private RunHelper _helper;
69 | protected override void OnSetup()
70 | {
71 | _helper = new RunHelper(this);
72 | }
73 | public void PreInit()
74 | {
75 | _helper.Run(p => p.PreInit());
76 | }
77 | }
78 | #if ENABLE_IL2CPP
79 | [Il2CppSetOption(Option.NullChecks, false)]
80 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
81 | #endif
82 | [MetaColor(MetaColor.DragonRose)]
83 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
84 | [MetaDescription(EcsConsts.AUTHOR, "...")]
85 | [MetaTags(MetaTags.HIDDEN)]
86 | [MetaID("DragonECS_ED85527C9201A391AB8EC0B734917859")]
87 | internal sealed class EcsInitRunner : EcsRunner, IEcsInit
88 | {
89 | private RunHelper _helper;
90 | protected override void OnSetup()
91 | {
92 | _helper = new RunHelper(this);
93 | }
94 | public void Init()
95 | {
96 | _helper.Run(p => p.Init());
97 | }
98 | }
99 | #if ENABLE_IL2CPP
100 | [Il2CppSetOption(Option.NullChecks, false)]
101 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
102 | #endif
103 | [MetaColor(MetaColor.DragonRose)]
104 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
105 | [MetaDescription(EcsConsts.AUTHOR, "...")]
106 | [MetaTags(MetaTags.HIDDEN)]
107 | [MetaID("DragonECS_2098527C9201F260C840BFD50BC7E0BA")]
108 | internal sealed class EcsRunRunner : EcsRunner, IEcsRun
109 | {
110 | private readonly struct Pair
111 | {
112 | public readonly IEcsRun run;
113 | public readonly IEcsRunFinally cleanup;
114 | public Pair(IEcsRun run)
115 | {
116 | this.run = run;
117 | cleanup = run as IEcsRunFinally;
118 | }
119 | }
120 | private Pair[] _pairs;
121 | #if DEBUG
122 | private EcsProfilerMarker[] _markers;
123 | #endif
124 | protected override void OnSetup()
125 | {
126 | _pairs = new Pair[Process.Length];
127 | for (int i = 0; i < Process.Length; i++)
128 | {
129 | _pairs[i] = new Pair(Process[i]);
130 | }
131 | #if DEBUG
132 | _markers = new EcsProfilerMarker[Process.Length];
133 | for (int i = 0; i < Process.Length; i++)
134 | {
135 | _markers[i] = new EcsProfilerMarker($"{Process[i].GetMeta().Name}.{nameof(Run)}");
136 | }
137 | #endif
138 | }
139 | public void Run()
140 | {
141 | #if DEBUG
142 | for (int i = 0, n = _pairs.Length < _markers.Length ? _pairs.Length : _markers.Length; i < n; i++)
143 | {
144 | var pair = _pairs[i];
145 | _markers[i].Begin();
146 | try
147 | {
148 | pair.run.Run();
149 | }
150 | catch (Exception e)
151 | {
152 | #if DRAGONECS_DISABLE_CATH_EXCEPTIONS
153 | throw e;
154 | #else
155 | EcsDebug.PrintError(e);
156 | #endif
157 | }
158 | finally
159 | {
160 | pair.cleanup?.RunFinally();
161 | }
162 | _markers[i].End();
163 | }
164 | #else
165 | foreach (var item in Process)
166 | {
167 | try { item.Run(); }
168 | catch (Exception e)
169 | {
170 | #if DRAGONECS_DISABLE_CATH_EXCEPTIONS
171 | throw e;
172 | #else
173 | EcsDebug.PrintError(e);
174 | #endif
175 | }
176 | }
177 | #endif
178 | }
179 | }
180 | #if ENABLE_IL2CPP
181 | [Il2CppSetOption(Option.NullChecks, false)]
182 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
183 | #endif
184 | [MetaColor(MetaColor.DragonRose)]
185 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
186 | [MetaDescription(EcsConsts.AUTHOR, "...")]
187 | [MetaTags(MetaTags.HIDDEN)]
188 | [MetaID("DragonECS_06A6527C92010430ACEB3DA520F272CC")]
189 | internal sealed class EcsDestroyRunner : EcsRunner, IEcsDestroy
190 | {
191 | private RunHelper _helper;
192 | protected override void OnSetup()
193 | {
194 | _helper = new RunHelper(this);
195 | }
196 | public void Destroy()
197 | {
198 | _helper.Run(p => p.Destroy());
199 | }
200 | }
201 | }
--------------------------------------------------------------------------------
/src/Builtin/BaseProcesses.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 074bd83936df7c84daf6e295b2f21a9a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Builtin/Worlds.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System.Diagnostics;
5 |
6 | namespace DCFApixels.DragonECS
7 | {
8 | /// EcsWrold for store regular game entities.
9 | [MetaColor(MetaColor.DragonRose)]
10 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)]
11 | [MetaDescription(EcsConsts.AUTHOR, "Inherits EcsWorld without extending its functionality and is used for specific injections. Can be used to store regular game entities, can also be used as a single world in the game for all entities.")]
12 | [DebuggerTypeProxy(typeof(DebuggerProxy))]
13 | [MetaID("DragonECS_4EE3527C92015BAB0299CB7B4E2663D1")]
14 | public sealed class EcsDefaultWorld : EcsWorld, IInjectionUnit
15 | {
16 | private const string DEFAULT_NAME = "Default";
17 | public EcsDefaultWorld() : base(default(EcsWorldConfig), DEFAULT_NAME) { }
18 | public EcsDefaultWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? DEFAULT_NAME : name, worldID) { }
19 | public EcsDefaultWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? DEFAULT_NAME : name, worldID) { }
20 | void IInjectionUnit.InitInjectionNode(InjectionGraph nodes) { nodes.AddNode(this); }
21 | }
22 | /// EcsWrold for store event entities.
23 | [MetaColor(MetaColor.DragonRose)]
24 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)]
25 | [MetaDescription(EcsConsts.AUTHOR, "Inherits EcsWorld without extending its functionality and is used for specific injections. Can be used to store event entities.")]
26 | [DebuggerTypeProxy(typeof(DebuggerProxy))]
27 | [MetaID("DragonECS_D7CE527C920160BCD765EFA72DBF8B89")]
28 | public sealed class EcsEventWorld : EcsWorld, IInjectionUnit
29 | {
30 | private const string DEFAULT_NAME = "Events";
31 | public EcsEventWorld() : base(default(EcsWorldConfig), DEFAULT_NAME) { }
32 | public EcsEventWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? DEFAULT_NAME : name, worldID) { }
33 | public EcsEventWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? DEFAULT_NAME : name, worldID) { }
34 | void IInjectionUnit.InitInjectionNode(InjectionGraph nodes) { nodes.AddNode(this); }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Builtin/Worlds.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 76bb6fc0896102347bbd36ed235e45f7
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Collections.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2e026d1a6d4fd884ea7324b6097703c5
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Collections/EcsGroup.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 375bb17cd9e70d248b9beb2d8d187fa2
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Collections/EcsSpan.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 55c6215b2c0f45849b191532a01e1dfe
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Consts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DCFApixels.DragonECS
4 | {
5 | public static class EcsConsts
6 | {
7 | public const string AUTHOR = "DCFApixels";
8 | public const string FRAMEWORK_NAME = "DragonECS";
9 | public const string NAME_SPACE = AUTHOR + "." + FRAMEWORK_NAME + ".";
10 | public const string EXCEPTION_MESSAGE_PREFIX = "[" + FRAMEWORK_NAME + "] ";
11 | public const string DEBUG_PREFIX = "[DEBUG] ";
12 | public const string DEBUG_WARNING_TAG = "WARNING";
13 | public const string DEBUG_ERROR_TAG = "ERROR";
14 | public const string DEBUG_PASS_TAG = "PASS";
15 |
16 | public const string PRE_BEGIN_LAYER = NAME_SPACE + nameof(PRE_BEGIN_LAYER);
17 | public const string BEGIN_LAYER = NAME_SPACE + nameof(BEGIN_LAYER);
18 | public const string BASIC_LAYER = NAME_SPACE + nameof(BASIC_LAYER);
19 | public const string END_LAYER = NAME_SPACE + nameof(END_LAYER);
20 | public const string POST_END_LAYER = NAME_SPACE + nameof(POST_END_LAYER);
21 |
22 | public const string META_HIDDEN_TAG = "HiddenInDebagging";
23 | public const string META_OBSOLETE_TAG = "Obsolete";
24 | public const string META_ENGINE_MEMBER_TAG = "EngineMember";
25 |
26 | public const int MAGIC_PRIME = 314159;
27 |
28 | public const int NULL_ENTITY_ID = 0;
29 | public const short NULL_WORLD_ID = 0;
30 | /// meta subgroups
31 |
32 | public const string PACK_GROUP = "_" + FRAMEWORK_NAME + "/_Core";
33 | public const string WORLDS_GROUP = "Worlds";
34 | public const string DI_GROUP = "DI";
35 | public const string POOLS_GROUP = "Pools";
36 | public const string PROCESSES_GROUP = "Processes";
37 | public const string DEBUG_GROUP = "Debug";
38 | public const string OTHER_GROUP = "Other";
39 | public const string OBSOLETE_GROUP = "Obsolete";
40 | public const string TEMPLATES_GROUP = "Templates";
41 | public const string IMPLEMENTATIONS_GROUP = "Implementation";
42 |
43 | public const string COMPONENTS_GROUP = "Components";
44 | public const string SYSTEMS_GROUP = "Systems";
45 | public const string MODULES_GROUP = "Modules";
46 | }
47 |
48 | public static class EcsDefines
49 | {
50 | public const bool DRAGONECS_ENABLE_DEBUG_SERVICE =
51 | #if DRAGONECS_ENABLE_DEBUG_SERVICE
52 | true;
53 | #else
54 | false;
55 | #endif
56 | public const bool DRAGONECS_DISABLE_POOLS_EVENTS =
57 | #if DRAGONECS_DISABLE_POOLS_EVENTS
58 | true;
59 | #else
60 | false;
61 | #endif
62 | public const bool DRAGONECS_DISABLE_CATH_EXCEPTIONS =
63 | #if DRAGONECS_DISABLE_CATH_EXCEPTIONS
64 | true;
65 | #else
66 | false;
67 | #endif
68 | public const bool DRAGONECS_STABILITY_MODE =
69 | #if DRAGONECS_STABILITY_MODE
70 | true;
71 | #else
72 | false;
73 | #endif
74 | public const bool DRAGONECS_DEEP_DEBUG =
75 | #if DRAGONECS_DEEP_DEBUG
76 | true;
77 | #else
78 | false;
79 | #endif
80 | public const bool DISABLE_DEBUG =
81 | #if DISABLE_DEBUG
82 | true;
83 | #else
84 | false;
85 | #endif
86 | public const bool REFLECTION_DISABLED =
87 | #if REFLECTION_DISABLED
88 | true;
89 | #else
90 | false;
91 | #endif
92 |
93 |
94 |
95 | [Obsolete("DRAGONECS_ENABLE_DEBUG_SERVICE")]
96 | public const bool ENABLE_DRAGONECS_DEBUGGER =
97 | #if ENABLE_DRAGONECS_DEBUGGER
98 | true;
99 | #else
100 | false;
101 | #endif
102 | [Obsolete("DRAGONECS_DISABLE_POOLS_EVENTS")]
103 | public const bool DISABLE_POOLS_EVENTS =
104 | #if DISABLE_POOLS_EVENTS
105 | true;
106 | #else
107 | false;
108 | #endif
109 | [Obsolete("DRAGONECS_DISABLE_CATH_EXCEPTIONS")]
110 | public const bool DISABLE_CATH_EXCEPTIONS =
111 | #if DISABLE_CATH_EXCEPTIONS
112 | true;
113 | #else
114 | false;
115 | #endif
116 | [Obsolete("DRAGONECS_STABILITY_MODE")]
117 | public const bool ENABLE_DRAGONECS_ASSERT_CHEKS =
118 | #if ENABLE_DRAGONECS_ASSERT_CHEKS
119 | true;
120 | #else
121 | false;
122 | #endif
123 | [Obsolete]
124 | public const bool ENABLE_DUMMY_SPAN =
125 | #if ENABLE_DUMMY_SPAN
126 | true;
127 | #else
128 | false;
129 | #endif
130 | }
131 | }
132 | //#if UNITY_2020_3_OR_NEWER
133 | // [UnityEngine.Scripting.RequireDerived, UnityEngine.Scripting.Preserve]
134 | //#endif
135 |
136 |
137 |
138 |
139 | #if ENABLE_IL2CPP
140 | // Unity IL2CPP performance optimization attribute.
141 | namespace Unity.IL2CPP.CompilerServices
142 | {
143 | using System;
144 | internal enum Option
145 | {
146 | NullChecks = 1,
147 | ArrayBoundsChecks = 2,
148 | DivideByZeroChecks = 3,
149 | }
150 | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Delegate, Inherited = false, AllowMultiple = true)]
151 | internal class Il2CppSetOptionAttribute : Attribute
152 | {
153 | public Option Option { get; private set; }
154 | public object Value { get; private set; }
155 | public Il2CppSetOptionAttribute(Option option, object value)
156 | {
157 | Option = option;
158 | Value = value;
159 | }
160 | }
161 | }
162 | #endif
--------------------------------------------------------------------------------
/src/Consts.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3c30dd6d8ecfdbd4aaceccd22bfb85c4
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DataInterfaces.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System.Runtime.CompilerServices;
5 |
6 | namespace DCFApixels.DragonECS.Core
7 | {
8 | #region IEcsWorldComponent
9 | public interface IEcsWorldComponent
10 | {
11 | void Init(ref T component, EcsWorld world);
12 | void OnDestroy(ref T component, EcsWorld world);
13 | }
14 | public static class EcsWorldComponentHandler
15 | {
16 | public static readonly IEcsWorldComponent instance;
17 | public static readonly bool isHasHandler;
18 | static EcsWorldComponentHandler()
19 | {
20 | T def = default;
21 | if (def is IEcsWorldComponent intrf)
22 | {
23 | isHasHandler = true;
24 | instance = intrf;
25 | }
26 | else
27 | {
28 | isHasHandler = false;
29 | instance = new DummyHandler();
30 | }
31 | }
32 | private class DummyHandler : IEcsWorldComponent
33 | {
34 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
35 | public void Init(ref T component, EcsWorld world) { }
36 | public void OnDestroy(ref T component, EcsWorld world) { }
37 | }
38 | }
39 | #endregion
40 |
41 | #region IEcsComponentReset
42 | public interface IEcsComponentLifecycle
43 | {
44 | void Enable(ref T component);
45 | void Disable(ref T component);
46 | }
47 | public static class EcsComponentLifecycleHandler
48 | {
49 | public static readonly IEcsComponentLifecycle instance;
50 | public static readonly bool isHasHandler;
51 | static EcsComponentLifecycleHandler()
52 | {
53 | T def = default;
54 | if (def is IEcsComponentLifecycle intrf)
55 | {
56 | isHasHandler = true;
57 | instance = intrf;
58 | }
59 | else
60 | {
61 | isHasHandler = false;
62 | instance = new DummyHandler();
63 | }
64 | }
65 | private sealed class DummyHandler : IEcsComponentLifecycle
66 | {
67 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
68 | public void Enable(ref T component) { component = default; }
69 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
70 | public void Disable(ref T component) { component = default; }
71 | }
72 | }
73 | #endregion
74 |
75 | #region IEcsComponentCopy
76 | public interface IEcsComponentCopy
77 | {
78 | void Copy(ref T from, ref T to);
79 | }
80 | public static class EcsComponentCopyHandler
81 | {
82 | public static readonly IEcsComponentCopy instance;
83 | public static readonly bool isHasHandler;
84 | static EcsComponentCopyHandler()
85 | {
86 | T def = default;
87 | if (def is IEcsComponentCopy intrf)
88 | {
89 | isHasHandler = true;
90 | instance = intrf;
91 | }
92 | else
93 | {
94 | isHasHandler = false;
95 | instance = new DummyHandler();
96 | }
97 | }
98 | private sealed class DummyHandler : IEcsComponentCopy
99 | {
100 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
101 | public void Copy(ref T from, ref T to) { to = from; }
102 | }
103 | }
104 | #endregion
105 | }
106 |
--------------------------------------------------------------------------------
/src/DataInterfaces.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 917643bbbff27894997fde6ede12f9c4
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 23d4c5f7a01e47f479e93dcee99e77b2
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/DebugUtils/EcsDebug.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0b40701424b50164b9c76021678c908b
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/EcsDebugUtility.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core.Internal;
5 | using System;
6 | using System.Collections.Generic;
7 | #if DEBUG || !REFLECTION_DISABLED
8 | using System.Reflection;
9 | #endif
10 |
11 | namespace DCFApixels.DragonECS
12 | {
13 | public static class EcsDebugUtility
14 | {
15 | #if DEBUG || !REFLECTION_DISABLED
16 | private const BindingFlags RFL_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
17 | #endif
18 |
19 | #region GetGenericTypeName
20 | public static string GetGenericTypeFullName(int maxDepth = 2)
21 | {
22 | return GetGenericTypeFullName(typeof(T), maxDepth);
23 | }
24 | public static string GetGenericTypeFullName(Type type, int maxDepth = 2)
25 | {
26 | return GetGenericTypeName_Internal(type, maxDepth, true);
27 | }
28 | public static string GetGenericTypeName(int maxDepth = 2)
29 | {
30 | return GetGenericTypeName(typeof(T), maxDepth);
31 | }
32 | public static string GetGenericTypeName(Type type, int maxDepth = 2)
33 | {
34 | return GetGenericTypeName_Internal(type, maxDepth, false);
35 | }
36 | private static string GetGenericTypeName_Internal(Type type, int maxDepth, bool isFull)
37 | {
38 | #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
39 | string typeName = isFull ? type.FullName : type.Name;
40 | if (!type.IsGenericType || maxDepth == 0)
41 | {
42 | return typeName;
43 | }
44 | int genericInfoIndex = typeName.LastIndexOf('`');
45 | if (genericInfoIndex > 0)
46 | {
47 | typeName = typeName.Remove(genericInfoIndex);
48 | }
49 |
50 | string genericParams = "";
51 | Type[] typeParameters = type.GetGenericArguments();
52 | for (int i = 0; i < typeParameters.Length; ++i)
53 | {
54 | //чтобы строка не была слишком длинной, используются сокращенные имена для типов аргументов
55 | string paramTypeName = GetGenericTypeName_Internal(typeParameters[i], maxDepth - 1, false);
56 | genericParams += (i == 0 ? paramTypeName : $", {paramTypeName}");
57 | }
58 | return $"{typeName}<{genericParams}>";
59 | #else
60 | EcsDebug.PrintWarning($"Reflection is not available, the {nameof(GetGenericTypeName_Internal)} method does not work.");
61 | return isFull ? type.FullName : type.Name;
62 | #endif
63 | }
64 | #endregion
65 |
66 | #region AutoToString
67 | /// slow but automatic conversion of ValueType to string in the format "name(field1, field2... fieldn)"
68 | public static string AutoToString(this T self, bool isWriteName = true) where T : struct
69 | {
70 | return AutoToString(self, typeof(T), isWriteName);
71 | }
72 |
73 | internal static string AutoToString(object target, Type type, bool isWriteName)
74 | {
75 | #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
76 | #pragma warning disable IL2070 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.
77 | var fields = type.GetFields(RFL_FLAGS);
78 | #pragma warning restore IL2070
79 | string[] values = new string[fields.Length];
80 | for (int i = 0; i < fields.Length; i++)
81 | {
82 | values[i] = (fields[i].GetValue(target) ?? "NULL").ToString();
83 | }
84 | if (isWriteName)
85 | {
86 | return $"{type.Name}({string.Join(", ", values)})";
87 | }
88 | else
89 | {
90 | return $"({string.Join(", ", values)})";
91 | }
92 | #else
93 | EcsDebug.PrintWarning($"Reflection is not available, the {nameof(AutoToString)} method does not work.");
94 | return string.Empty;
95 | #endif
96 | }
97 | #endregion
98 |
99 | #region GetName
100 | public static string GetMetaName(object obj)
101 | {
102 | return GetTypeMeta(obj).Name;
103 | }
104 | public static string GetMetaName()
105 | {
106 | return GetTypeMeta().Name;
107 | }
108 | public static string GetMetaName(Type type)
109 | {
110 | return GetTypeMeta(type).Name;
111 | }
112 |
113 | public static bool TryGetMetaName(object obj, out string name)
114 | {
115 | TypeMeta meta = GetTypeMeta(obj);
116 | name = meta.Name;
117 | return meta.IsCustomName;
118 | }
119 | public static bool TryGetMetaName(out string name)
120 | {
121 | TypeMeta meta = GetTypeMeta();
122 | name = meta.Name;
123 | return meta.IsCustomName;
124 | }
125 | public static bool TryGetMetaName(Type type, out string name)
126 | {
127 | TypeMeta meta = GetTypeMeta(type);
128 | name = meta.Name;
129 | return meta.IsCustomName;
130 | }
131 | #endregion
132 |
133 | #region GetColor
134 | public static MetaColor GetColor(object obj)
135 | {
136 | return GetTypeMeta(obj).Color;
137 | }
138 | public static MetaColor GetColor()
139 | {
140 | return GetTypeMeta().Color;
141 | }
142 | public static MetaColor GetColor(Type type)
143 | {
144 | return GetTypeMeta(type).Color;
145 | }
146 |
147 | public static bool TryGetColor(object obj, out MetaColor color)
148 | {
149 | TypeMeta meta = GetTypeMeta(obj);
150 | color = meta.Color;
151 | return meta.IsCustomColor;
152 | }
153 | public static bool TryGetColor(out MetaColor color)
154 | {
155 | TypeMeta meta = GetTypeMeta();
156 | color = meta.Color;
157 | return meta.IsCustomColor;
158 | }
159 | public static bool TryGetColor(Type type, out MetaColor color)
160 | {
161 | TypeMeta meta = GetTypeMeta(type);
162 | color = meta.Color;
163 | return meta.IsCustomColor;
164 | }
165 | #endregion
166 |
167 | #region GetDescription
168 | public static MetaDescription GetDescription(object obj)
169 | {
170 | return GetTypeMeta(obj).Description;
171 | }
172 | public static MetaDescription GetDescription()
173 | {
174 | return GetTypeMeta().Description;
175 | }
176 | public static MetaDescription GetDescription(Type type)
177 | {
178 | return GetTypeMeta(type).Description;
179 | }
180 |
181 | public static bool TryGetDescription(object obj, out MetaDescription description)
182 | {
183 | TypeMeta meta = GetTypeMeta(obj);
184 | description = meta.Description;
185 | return description != MetaDescription.Empty;
186 | }
187 | public static bool TryGetDescription(out MetaDescription description)
188 | {
189 | TypeMeta meta = GetTypeMeta();
190 | description = meta.Description;
191 | return description != MetaDescription.Empty;
192 | }
193 | public static bool TryGetDescription(Type type, out MetaDescription description)
194 | {
195 | TypeMeta meta = GetTypeMeta(type);
196 | description = meta.Description;
197 | return description != MetaDescription.Empty;
198 | }
199 | #endregion
200 |
201 | #region GetGroup
202 | public static MetaGroup GetGroup(object obj)
203 | {
204 | return GetTypeMeta(obj).Group;
205 | }
206 | public static MetaGroup GetGroup()
207 | {
208 | return GetTypeMeta().Group;
209 | }
210 | public static MetaGroup GetGroup(Type type)
211 | {
212 | return GetTypeMeta(type).Group;
213 | }
214 |
215 | public static bool TryGetGroup(object obj, out MetaGroup group)
216 | {
217 | TypeMeta meta = GetTypeMeta(obj);
218 | group = meta.Group;
219 | return group != MetaGroup.Empty;
220 | }
221 | public static bool TryGetGroup(out MetaGroup group)
222 | {
223 | TypeMeta meta = GetTypeMeta();
224 | group = meta.Group;
225 | return group != MetaGroup.Empty;
226 | }
227 | public static bool TryGetGroup(Type type, out MetaGroup group)
228 | {
229 | TypeMeta meta = GetTypeMeta(type);
230 | group = meta.Group;
231 | return group != MetaGroup.Empty;
232 | }
233 | #endregion
234 |
235 | #region GetTags
236 | public static IReadOnlyCollection GetTags(object obj)
237 | {
238 | return GetTypeMeta(obj).Tags;
239 | }
240 | public static IReadOnlyCollection GetTags()
241 | {
242 | return GetTypeMeta().Tags;
243 | }
244 | public static IReadOnlyCollection GetTags(Type type)
245 | {
246 | return GetTypeMeta(type).Tags;
247 | }
248 |
249 | public static bool TryGetTags(object obj, out IReadOnlyCollection tags)
250 | {
251 | TypeMeta meta = GetTypeMeta(obj);
252 | tags = meta.Tags;
253 | return tags.Count <= 0;
254 | }
255 | public static bool TryGetTags(out IReadOnlyCollection tags)
256 | {
257 | TypeMeta meta = GetTypeMeta();
258 | tags = meta.Tags;
259 | return tags.Count <= 0;
260 | }
261 | public static bool TryGetTags(Type type, out IReadOnlyCollection tags)
262 | {
263 | TypeMeta meta = GetTypeMeta(type);
264 | tags = meta.Tags;
265 | return tags.Count <= 0;
266 | }
267 | #endregion
268 |
269 | #region IsHidden
270 | public static bool IsHidden(object obj)
271 | {
272 | return GetTypeMeta(obj).IsHidden;
273 | }
274 | public static bool IsHidden()
275 | {
276 | return GetTypeMeta().IsHidden;
277 | }
278 | public static bool IsHidden(Type type)
279 | {
280 | return GetTypeMeta(type).IsHidden;
281 | }
282 | #endregion
283 |
284 | #region GetTypeMeta
285 | public static TypeMeta GetTypeMeta(object obj)
286 | {
287 | if (obj == null) { return TypeMeta.NullTypeMeta; }
288 | return TypeMeta.Get(GetTypeMetaSource(obj).GetType());
289 | }
290 | public static TypeMeta GetTypeMeta()
291 | {
292 | return TypeMeta.Get(typeof(T));
293 | }
294 | public static TypeMeta GetTypeMeta(Type type)
295 | {
296 | return TypeMeta.Get(type);
297 | }
298 | #endregion
299 |
300 | #region TypeMetaProvider
301 | public static bool IsTypeMetaProvided(object obj)
302 | {
303 | return obj is IEcsTypeMetaProvider;
304 | }
305 | public static object GetTypeMetaSource(object obj)
306 | {
307 | return obj is IEcsTypeMetaProvider intr ? intr.MetaSource : obj;
308 | }
309 | #endregion
310 | }
311 |
312 | public static class TypeMetaDataCachedExtensions
313 | {
314 | public static TypeMeta GetMeta(this object self)
315 | {
316 | #if DEBUG && DRAGONECS_DEEP_DEBUG
317 | if (self is Type type) { Throw.DeepDebugException(); }
318 | #endif
319 | return EcsDebugUtility.GetTypeMeta(self);
320 | }
321 | public static TypeMeta ToMeta(this Type self)
322 | {
323 | return EcsDebugUtility.GetTypeMeta(self);
324 | }
325 | }
326 | }
--------------------------------------------------------------------------------
/src/DebugUtils/EcsDebugUtility.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 61b9ff184ea168146a3caf22f015852a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/Interfaces.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 50bc53c3762bf6b4ea127004a89a894e
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/DebugUtils/Interfaces/IEcsTypeMetaProvider.cs:
--------------------------------------------------------------------------------
1 | namespace DCFApixels.DragonECS
2 | {
3 | public interface IEcsTypeMetaProvider
4 | {
5 | object MetaSource { get; }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/DebugUtils/Interfaces/IEcsTypeMetaProvider.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4a642dc8905124247bf83c9d13d8fb13
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 269d1f5d46517e14a8563d7f239fa559
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/EcsMetaAttribute.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 |
6 | namespace DCFApixels.DragonECS.Core
7 | {
8 | public abstract class EcsMetaAttribute : Attribute { }
9 |
10 | internal static class EcsMetaAttributeHalper
11 | {
12 | internal const string EMPTY_NO_SENSE_MESSAGE = "With empty parameters, this attribute makes no sense.";
13 | [ThreadStatic]
14 | private static string[] _splitBuffer;
15 | public static unsafe string[] Split(char separator, string value)
16 | {
17 | if (_splitBuffer == null)
18 | {
19 | _splitBuffer = new string[128];
20 | }
21 | int length = value.Length;
22 | int bufferIndex = 0;
23 | fixed (char* ptr = value)
24 | {
25 | var reader = new SplitStream(ptr, value.Length, separator);
26 | while (reader.Next())
27 | {
28 | if (reader.current != null)
29 | {
30 | if (_splitBuffer.Length == bufferIndex)
31 | {
32 | Array.Resize(ref _splitBuffer, _splitBuffer.Length << 1);
33 | }
34 | _splitBuffer[bufferIndex++] = reader.current;
35 | }
36 | }
37 | }
38 |
39 | string[] result = new string[bufferIndex];
40 | for (int i = 0; i < bufferIndex; i++)
41 | {
42 | result[i] = _splitBuffer[i];
43 | }
44 | return result;
45 | }
46 |
47 | #region SplitStream
48 | private unsafe ref struct SplitStream
49 | {
50 | public string current;
51 | public char* ptr;
52 | public int length;
53 | public readonly char separator;
54 | public SplitStream(char* ptr, int length, char separator)
55 | {
56 | this.ptr = ptr;
57 | this.length = length;
58 | this.separator = separator;
59 | current = null;
60 | }
61 | public bool Next()
62 | {
63 | if (length <= 0) { return false; }
64 | char chr;
65 |
66 | char* spanPtr;
67 | while (char.IsWhiteSpace(chr = *ptr) && length > 0) { ptr++; length--; }
68 | spanPtr = ptr;
69 |
70 | char* spanEndPtr = spanPtr;
71 | while ((chr = *ptr) != separator && length > 0)
72 | {
73 | ptr++; length--;
74 | if (char.IsWhiteSpace(chr) == false)
75 | {
76 | spanEndPtr = ptr;
77 | }
78 | }
79 | ptr++; length--;
80 |
81 | current = spanPtr < spanEndPtr ? new string(spanPtr, 0, (int)(spanEndPtr - spanPtr)) : null;
82 | return true;
83 | }
84 | }
85 | #endregion
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/EcsMetaAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: eb8cc656a6e80f843b8794af9f63faa8
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4b96ad0ff9cf7124d8539afccec8f1ae
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaDescriptionAttribute.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core;
5 | using System;
6 |
7 | namespace DCFApixels.DragonECS
8 | {
9 | [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
10 | public sealed class MetaDescriptionAttribute : EcsMetaAttribute
11 | {
12 | public readonly MetaDescription Data;
13 | public MetaDescriptionAttribute(string text)
14 | {
15 | Data = new MetaDescription(null, text);
16 | }
17 | public MetaDescriptionAttribute(string author, string text)
18 | {
19 | Data = new MetaDescription(author, text);
20 | }
21 | }
22 | public class MetaDescription
23 | {
24 | public static readonly MetaDescription Empty = new MetaDescription(null, null);
25 | public readonly string Author;
26 | public readonly string Text;
27 | public bool IsHasAutor
28 | {
29 | get { return string.IsNullOrEmpty(Author) == false; }
30 | }
31 | public MetaDescription(string text) : this(null, text) { }
32 | public MetaDescription(string author, string text)
33 | {
34 | if (author == null) { author = string.Empty; }
35 | if (text == null) { text = string.Empty; }
36 | Author = author;
37 | Text = text;
38 | }
39 | public override string ToString()
40 | {
41 | if (string.IsNullOrEmpty(Author))
42 | {
43 | return Text;
44 | }
45 | else
46 | {
47 | return $"[{Author}] Text";
48 | }
49 | }
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaDescriptionAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1d10298ed9d8a3649b590f8326310e3c
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Diagnostics;
8 | using System.Text.RegularExpressions;
9 |
10 | namespace DCFApixels.DragonECS
11 | {
12 | [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
13 | public sealed class MetaGroupAttribute : EcsMetaAttribute
14 | {
15 | public const char SEPARATOR = MetaGroup.SEPARATOR;
16 | public readonly string Name = string.Empty;
17 |
18 | [Obsolete(EcsMetaAttributeHalper.EMPTY_NO_SENSE_MESSAGE)]
19 | public MetaGroupAttribute() { }
20 | public MetaGroupAttribute(string name) { Name = name; }
21 | public MetaGroupAttribute(params string[] path) { Name = string.Join(SEPARATOR, path); }
22 | }
23 | [DebuggerDisplay("{Name}")]
24 | public class MetaGroup
25 | {
26 | public const char SEPARATOR = '/';
27 | private const string SEPARATOR_STR = "/";
28 | public const string UNGROUPED = "";
29 | private const string PATTERN = @"Module(?=/)";
30 | public static readonly MetaGroup Empty = new MetaGroup(UNGROUPED);
31 |
32 | public readonly string Name;
33 | private string[] _splited = null;
34 | public IReadOnlyCollection Splited
35 | {
36 | get
37 | {
38 | if (_splited == null)
39 | {
40 | _splited = EcsMetaAttributeHalper.Split(SEPARATOR, Name);
41 | }
42 | return _splited;
43 | }
44 | }
45 | public bool IsEmpty
46 | {
47 | get { return this == Empty; }
48 | }
49 | private MetaGroup(string name)
50 | {
51 | if (string.IsNullOrEmpty(name))
52 | {
53 | Name = UNGROUPED;
54 | return;
55 | }
56 | name = Regex.Replace(name, @"(\s*[\/\\]+\s*)+", SEPARATOR_STR).Trim();
57 | if (name[name.Length - 1] != SEPARATOR)
58 | {
59 | name += SEPARATOR;
60 | }
61 | if (name[0] == SEPARATOR)
62 | {
63 | name = name.Substring(1);
64 | }
65 | Name = Regex.Replace(name, PATTERN, "");
66 | Name = string.Intern(Name);
67 | }
68 | public static MetaGroup FromName(string name)
69 | {
70 | if (string.IsNullOrWhiteSpace(name))
71 | {
72 | return Empty;
73 | }
74 | return new MetaGroup(name);
75 | }
76 | public static MetaGroup FromNameSpace(Type type)
77 | {
78 | if (string.IsNullOrWhiteSpace(type.Namespace))
79 | {
80 | return Empty;
81 | }
82 | return new MetaGroup(type.Namespace.Replace('.', SEPARATOR));
83 | }
84 | public override string ToString() { return Name; }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c447392c75f8b4a42a2e5c3eb49e5b82
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 145ce3aab9f970b4a8c936e1adf5de95
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaNameAttribute.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core;
5 | using System;
6 |
7 | namespace DCFApixels.DragonECS
8 | {
9 | [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
10 | public sealed class MetaNameAttribute : EcsMetaAttribute
11 | {
12 | public readonly string name;
13 | public readonly bool isHideGeneric;
14 | public MetaNameAttribute(string name, bool isHideGeneric = false)
15 | {
16 | this.name = name;
17 | this.isHideGeneric = isHideGeneric;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaNameAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5fc5d312c53d511498dc7d8abdb1e4c8
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaTagsAttribute.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core;
5 | using System;
6 | using System.Collections.Generic;
7 |
8 | namespace DCFApixels.DragonECS
9 | {
10 | [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
11 | public sealed class MetaTagsAttribute : EcsMetaAttribute
12 | {
13 | public const char SEPARATOR = ',';
14 | private readonly string[] _tags = Array.Empty();
15 | public IReadOnlyList Tags
16 | {
17 | get { return _tags; }
18 | }
19 |
20 | [Obsolete(EcsMetaAttributeHalper.EMPTY_NO_SENSE_MESSAGE)]
21 | public MetaTagsAttribute() { }
22 | public MetaTagsAttribute(string tags)
23 | {
24 | _tags = EcsMetaAttributeHalper.Split(SEPARATOR, tags);
25 | for (int i = 0; i < _tags.Length; i++)
26 | {
27 | _tags[i] = string.Intern(_tags[i]);
28 | }
29 | }
30 | public MetaTagsAttribute(string tag0, string tag1) : this($"{tag0},{tag1}") { }
31 | public MetaTagsAttribute(string tag0, string tag1, string tag2) : this($"{tag0},{tag1},{tag2}") { }
32 | public MetaTagsAttribute(string tag0, string tag1, string tag2, string tag3) : this($"{tag0},{tag1},{tag2},{tag3}") { }
33 | public MetaTagsAttribute(string tag0, string tag1, string tag2, string tag3, string tag4) : this($"{tag0},{tag1},{tag2},{tag3},{tag4}") { }
34 | public MetaTagsAttribute(string tag0, string tag1, string tag2, string tag3, string tag4, string tag5) : this($"{tag0},{tag1},{tag2},{tag3},{tag4},{tag5}") { }
35 | public MetaTagsAttribute(string tag0, string tag1, string tag2, string tag3, string tag4, string tag5, string tag6) : this($"{tag0},{tag1},{tag2},{tag3},{tag4},{tag5},{tag6}") { }
36 | public MetaTagsAttribute(string tag0, string tag1, string tag2, string tag3, string tag4, string tag5, string tag6, string tag7) : this($"{tag0},{tag1},{tag2},{tag3},{tag4},{tag5},{tag6},{tag7}") { }
37 | public MetaTagsAttribute(params string[] tags) : this(string.Join(SEPARATOR, tags)) { }
38 | }
39 | public readonly ref struct MetaTags
40 | {
41 | public const string HIDDEN = EcsConsts.META_HIDDEN_TAG;
42 | public const string OBSOLETE = EcsConsts.META_OBSOLETE_TAG;
43 | public const string ENGINE_MEMBER = EcsConsts.META_ENGINE_MEMBER_TAG;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/DebugUtils/MetaAttributes/MetaTagsAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b733e9a3fe4b974478c982962d45f94f
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/DebugUtils/TypeMeta.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4f969a5755aec72419e45d175d1d46b9
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsAspect.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 094f935216fa31840883f30e413d7f0c
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsMask.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e1975c74e7ab50e4dba6bf01902e26e9
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsPipeline.Builder.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e33b301d2d9766e42ad884fff3df44b4
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsPipeline.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bb5d6e45240ecad428d33758c4cc4c49
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsRunner.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ae6eb3472cd282b46b26ab9f1e97ec81
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsStaticMask.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 758f168275884084fb30e071ef3cc858
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsWorld.cache.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core;
5 | using DCFApixels.DragonECS.PoolsCore;
6 |
7 | namespace DCFApixels.DragonECS
8 | {
9 | public partial class EcsWorld
10 | {
11 | internal readonly struct PoolCache : IEcsWorldComponent>
12 | where T : IEcsPoolImplementation, new()
13 | {
14 | public readonly T Instance;
15 | public PoolCache(T instance) { Instance = instance; }
16 | void IEcsWorldComponent>.Init(ref PoolCache component, EcsWorld world)
17 | {
18 | component = new PoolCache(world.FindOrAutoCreatePool());
19 | }
20 | void IEcsWorldComponent>.OnDestroy(ref PoolCache component, EcsWorld world)
21 | {
22 | component = default;
23 | }
24 | }
25 | internal readonly struct AspectCache : IEcsWorldComponent>
26 | where T : new()
27 | {
28 | public readonly T Instance;
29 | public readonly EcsMask Mask;
30 | public AspectCache(T instance, EcsMask mask)
31 | {
32 | Instance = instance;
33 | Mask = mask;
34 | }
35 | void IEcsWorldComponent>.Init(ref AspectCache component, EcsWorld world)
36 | {
37 | #if DEBUG
38 | AllowedInWorldsAttribute.CheckAllows(world, typeof(T));
39 | #endif
40 | var result = EcsAspect.Builder.New(world);
41 | component = new AspectCache(result.aspect, result.mask);
42 | }
43 | void IEcsWorldComponent>.OnDestroy(ref AspectCache component, EcsWorld world)
44 | {
45 | component = default;
46 | }
47 | }
48 |
49 | internal readonly struct WhereQueryCache : IEcsWorldComponent>
50 | where TExecutor : MaskQueryExecutor, new()
51 | where TAspcet : new()
52 | {
53 | public readonly TExecutor Executor;
54 | public readonly TAspcet Aspcet;
55 | public WhereQueryCache(TExecutor executor, TAspcet aspcet)
56 | {
57 | Executor = executor;
58 | Aspcet = aspcet;
59 | }
60 | void IEcsWorldComponent>.Init(ref WhereQueryCache component, EcsWorld world)
61 | {
62 | TAspcet aspect = world.GetAspect(out EcsMask mask);
63 | TExecutor instance = world.GetExecutorForMask(mask);
64 | instance.Initialize(world, mask);
65 | component = new WhereQueryCache(instance, aspect);
66 | }
67 | void IEcsWorldComponent>.OnDestroy(ref WhereQueryCache component, EcsWorld world)
68 | {
69 | component = default;
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/EcsWorld.cache.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5cae52accc835594f95c8d972e40c57e
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsWorld.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b045d6a8b5bcf654f9c2be8012a526f6
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsWorld.pools.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2832746be4142a847b513bab5c276ba7
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/EcsWorld.static.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 30c8fd4d7c5aeae4486e16024b4f50cc
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Executors.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 07e42ed02d7289f41aa28e44c6e83ce3
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Executors/EcsWhereExecutor.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Runtime.CompilerServices;
6 | #if ENABLE_IL2CPP
7 | using Unity.IL2CPP.CompilerServices;
8 | #endif
9 |
10 | namespace DCFApixels.DragonECS.Core.Internal
11 | {
12 | #if ENABLE_IL2CPP
13 | [Il2CppSetOption(Option.NullChecks, false)]
14 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
15 | #endif
16 | internal sealed class EcsWhereExecutor : MaskQueryExecutor
17 | {
18 | private EcsMaskIterator _iterator;
19 |
20 | private int[] _filteredAllEntities = new int[32];
21 | private int _filteredAllEntitiesCount = 0;
22 | private int[] _filteredEntities = null;
23 | private int _filteredEntitiesCount = 0;
24 |
25 | private long _version;
26 | private WorldStateVersionsChecker _versionsChecker;
27 |
28 | public bool _isDestroyed = false;
29 |
30 | #region Properties
31 | public sealed override long Version
32 | {
33 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
34 | get { return _version; }
35 | }
36 | public sealed override bool IsCached
37 | {
38 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
39 | get { return _versionsChecker.Check(); }
40 | }
41 | public sealed override int LastCachedCount
42 | {
43 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
44 | get { return _filteredAllEntitiesCount; }
45 | }
46 | #endregion
47 |
48 | #region OnInitialize/OnDestroy
49 | protected sealed override void OnInitialize()
50 | {
51 | _versionsChecker = new WorldStateVersionsChecker(Mask);
52 | _iterator = Mask.GetIterator();
53 | }
54 | protected sealed override void OnDestroy()
55 | {
56 | if (_isDestroyed) { return; }
57 | _isDestroyed = true;
58 | _versionsChecker.Dispose();
59 | }
60 | #endregion
61 |
62 | #region Methods
63 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
64 | private void Execute_Iternal()
65 | {
66 | World.ReleaseDelEntityBufferAllAuto();
67 | if (_versionsChecker.CheckAndNext() == false)
68 | {
69 | _version++;
70 | _filteredAllEntitiesCount = _iterator.IterateTo(World.Entities, ref _filteredAllEntities);
71 | }
72 | }
73 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
74 | private void ExecuteFor_Iternal(EcsSpan span)
75 | {
76 | #if DEBUG || DRAGONECS_STABILITY_MODE
77 | if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
78 | if (span.WorldID != World.ID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
79 | #endif
80 | if (_filteredEntities == null)
81 | {
82 | _filteredEntities = new int[32];
83 | }
84 | _filteredEntitiesCount = _iterator.IterateTo(span, ref _filteredEntities);
85 | }
86 |
87 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
88 | public EcsSpan Execute()
89 | {
90 | Execute_Iternal();
91 | #if DEBUG && DRAGONECS_DEEP_DEBUG
92 | var newSpan = new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount);
93 | using (EcsGroup group = EcsGroup.New(World))
94 | {
95 | foreach (var e in World.Entities)
96 | {
97 | if (World.IsMatchesMask(Mask, e))
98 | {
99 | group.Add(e);
100 | }
101 | }
102 |
103 | if (group.SetEquals(newSpan) == false)
104 | {
105 | int[] array = new int[_filteredAllEntities.Length];
106 | var count = _iterator.IterateTo(World.Entities, ref array);
107 |
108 | EcsDebug.PrintError(newSpan.ToString() + "\r\n" + group.ToSpan().ToString());
109 | Throw.DeepDebugException();
110 | }
111 | }
112 | #endif
113 | return new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount);
114 | }
115 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
116 | public EcsSpan ExecuteFor(EcsSpan span)
117 | {
118 | if (span.IsSourceEntities)
119 | {
120 | return Execute();
121 | }
122 | ExecuteFor_Iternal(span);
123 | #if DEBUG && DRAGONECS_DEEP_DEBUG
124 | var newSpan = new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount);
125 | foreach (var e in newSpan)
126 | {
127 | if (World.IsMatchesMask(Mask, e) == false)
128 | {
129 | Throw.DeepDebugException();
130 | }
131 | }
132 | #endif
133 | return new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount);
134 | }
135 |
136 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
137 | public EcsSpan Execute(Comparison comparison)
138 | {
139 | Execute_Iternal();
140 | ArraySortHalperX.Sort(_filteredAllEntities, comparison, _filteredAllEntitiesCount);
141 | return new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount);
142 | }
143 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
144 | public EcsSpan ExecuteFor(EcsSpan span, Comparison comparison)
145 | {
146 | if (span.IsSourceEntities)
147 | {
148 | return Execute(comparison);
149 | }
150 | ExecuteFor_Iternal(span);
151 | ArraySortHalperX.Sort(_filteredEntities, comparison, _filteredEntitiesCount);
152 | return new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount);
153 | }
154 | #endregion
155 | }
156 | }
--------------------------------------------------------------------------------
/src/Executors/EcsWhereExecutor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fbae61c9d9f10ff4093153506723af17
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Executors/EcsWhereToGroupExecutor.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System.Runtime.CompilerServices;
5 | #if ENABLE_IL2CPP
6 | using Unity.IL2CPP.CompilerServices;
7 | #endif
8 |
9 | namespace DCFApixels.DragonECS.Core.Internal
10 | {
11 | #if ENABLE_IL2CPP
12 | [Il2CppSetOption(Option.NullChecks, false)]
13 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
14 | #endif
15 | internal sealed class EcsWhereToGroupExecutor : MaskQueryExecutor
16 | {
17 | private EcsMaskIterator _iterator;
18 |
19 | private EcsGroup _filteredAllGroup;
20 | private EcsGroup _filteredGroup;
21 |
22 | private long _version;
23 | private WorldStateVersionsChecker _versionsChecker;
24 |
25 | public bool _isDestroyed = false;
26 |
27 | #region Properties
28 | public sealed override long Version
29 | {
30 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
31 | get { return _version; }
32 | }
33 | public sealed override bool IsCached
34 | {
35 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
36 | get { return _versionsChecker.Check(); }
37 | }
38 | public sealed override int LastCachedCount
39 | {
40 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
41 | get { return _filteredAllGroup.Count; }
42 | }
43 | #endregion
44 |
45 | #region OnInitialize/OnDestroy
46 | protected sealed override void OnInitialize()
47 | {
48 | _versionsChecker = new WorldStateVersionsChecker(Mask);
49 | _filteredAllGroup = EcsGroup.New(World);
50 | _iterator = Mask.GetIterator();
51 | }
52 | protected sealed override void OnDestroy()
53 | {
54 | if (_isDestroyed) { return; }
55 | _isDestroyed = true;
56 | _filteredAllGroup.Dispose();
57 | _versionsChecker.Dispose();
58 | }
59 | #endregion
60 |
61 | #region Methods
62 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
63 | private void Execute_Iternal()
64 | {
65 | World.ReleaseDelEntityBufferAllAuto();
66 | if (_versionsChecker.CheckAndNext() == false)
67 | {
68 | _version++;
69 | _iterator.IterateTo(World.Entities, _filteredAllGroup);
70 | #if DEBUG && DRAGONECS_DEEP_DEBUG
71 | if (_filteredGroup == null)
72 | {
73 | _filteredGroup = EcsGroup.New(World);
74 | }
75 | _filteredGroup.Clear();
76 | foreach (var e in World.Entities)
77 | {
78 | if (World.IsMatchesMask(Mask, e))
79 | {
80 | _filteredGroup.Add(e);
81 | }
82 | }
83 | if (_filteredAllGroup.SetEquals(_filteredGroup) == false)
84 | {
85 | throw new System.InvalidOperationException();
86 | }
87 | #endif
88 | }
89 | }
90 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
91 | private void ExecuteFor_Iternal(EcsSpan span)
92 | {
93 | #if DEBUG || DRAGONECS_STABILITY_MODE
94 | if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
95 | if (span.WorldID != World.ID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
96 | #endif
97 | if (_filteredGroup == null)
98 | {
99 | _filteredGroup = EcsGroup.New(World);
100 | }
101 | _iterator.IterateTo(span, _filteredGroup);
102 | }
103 |
104 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
105 | public EcsReadonlyGroup Execute()
106 | {
107 | Execute_Iternal();
108 | return _filteredAllGroup;
109 | }
110 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
111 | public EcsReadonlyGroup ExecuteFor(EcsSpan span)
112 | {
113 | if (span.IsSourceEntities)
114 | {
115 | return Execute();
116 | }
117 | ExecuteFor_Iternal(span);
118 | return _filteredGroup;
119 | }
120 | #endregion
121 | }
122 | }
--------------------------------------------------------------------------------
/src/Executors/EcsWhereToGroupExecutor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5623a418399b20d46b965dcd1e8ef983
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Executors/MaskQueryExecutor.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core;
5 | using DCFApixels.DragonECS.Core.Internal;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Runtime.CompilerServices;
9 |
10 | namespace DCFApixels.DragonECS
11 | {
12 | public partial class EcsWorld
13 | {
14 | private readonly Dictionary<(Type, object), IQueryExecutorImplementation> _executorCoures;
15 |
16 | public TExecutor GetExecutorForMask(IComponentMask gmask)
17 | where TExecutor : MaskQueryExecutor, new()
18 | {
19 | var executorType = typeof(TExecutor);
20 | //проверяет ключ по абстрактной маске
21 | if (_executorCoures.TryGetValue((executorType, gmask), out IQueryExecutorImplementation executor) == false)
22 | {
23 | var mask = gmask.ToMask(this);
24 | //проверяет ключ по конкретной маске, или что конкретная и абстрактая одна и таже
25 | if (mask == gmask ||
26 | _executorCoures.TryGetValue((executorType, mask), out executor) == false)
27 | {
28 | TExecutor executorCore = new TExecutor();
29 | executorCore.Initialize(this, mask);
30 | executor = executorCore;
31 | }
32 | _executorCoures.Add((executorType, gmask), executor);
33 | }
34 | return (TExecutor)executor;
35 | }
36 |
37 | public void GetMaskQueryExecutors(List result, ref int version)
38 | {
39 | if (_executorCoures == null || version == _executorCoures.Count)
40 | {
41 | return;
42 | }
43 |
44 | result.Clear();
45 |
46 | foreach (var item in _executorCoures)
47 | {
48 | if (item.Value is MaskQueryExecutor x)
49 | {
50 | result.Add(x);
51 | }
52 | }
53 |
54 | version = _executorCoures.Count;
55 | }
56 | }
57 | }
58 |
59 | namespace DCFApixels.DragonECS.Core
60 | {
61 | public interface IQueryExecutorImplementation
62 | {
63 | EcsWorld World { get; }
64 | long Version { get; }
65 | bool IsCached { get; }
66 | int LastCachedCount { get; }
67 | void Destroy();
68 | }
69 | public abstract class MaskQueryExecutor : IQueryExecutorImplementation
70 | {
71 | private EcsWorld _source;
72 | private EcsMask _mask;
73 | public short WorldID
74 | {
75 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
76 | get { return _source.ID; }
77 | }
78 | public EcsWorld World
79 | {
80 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
81 | get { return _source; }
82 | }
83 | public EcsMask Mask
84 | {
85 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
86 | get { return _mask; }
87 | }
88 | public abstract long Version { get; }
89 | public abstract bool IsCached { get; }
90 | public abstract int LastCachedCount { get; }
91 | internal void Initialize(EcsWorld world, EcsMask mask)
92 | {
93 | _source = world;
94 | _mask = mask;
95 | OnInitialize();
96 | }
97 | void IQueryExecutorImplementation.Destroy()
98 | {
99 | OnDestroy();
100 | _source = null;
101 | }
102 | protected abstract void OnInitialize();
103 | protected abstract void OnDestroy();
104 | }
105 |
106 | public readonly unsafe struct WorldStateVersionsChecker : IDisposable
107 | {
108 | private readonly EcsWorld _world;
109 | private readonly int[] _maskInc;
110 | private readonly int[] _maskExc;
111 | // [0] world version
112 | // [-> _maskInc.Length] inc versions
113 | // [-> _maskExc.Length] exc versions
114 | private readonly long* _versions;
115 | private readonly int _count;
116 | public long Version
117 | {
118 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
119 | get { return _versions[0]; }
120 | }
121 |
122 | public WorldStateVersionsChecker(EcsMask mask)
123 | {
124 | _world = mask.World;
125 | _maskInc = mask._incs;
126 | _maskExc = mask._excs;
127 | _count = 1 + mask._incs.Length + mask._excs.Length;
128 |
129 | _versions = UnmanagedArrayUtility.NewAndInit(_count);
130 | }
131 | public bool Check()
132 | {
133 | if (*_versions == _world.Version)
134 | {
135 | return true;
136 | }
137 |
138 | long* versionsPtr = _versions;
139 | var slots = _world._poolSlots;
140 | foreach (var slotIndex in _maskInc)
141 | {
142 | versionsPtr++;
143 | if (*versionsPtr != slots[slotIndex].version)
144 | {
145 | return false;
146 | }
147 | }
148 | foreach (var slotIndex in _maskExc)
149 | {
150 | versionsPtr++;
151 | if (*versionsPtr != slots[slotIndex].version)
152 | {
153 | return false;
154 | }
155 | }
156 | return true;
157 | }
158 | public void Next()
159 | {
160 | *_versions = _world.Version;
161 |
162 | long* versionsPtr = _versions;
163 | var slots = _world._poolSlots;
164 | foreach (var slotIndex in _maskInc)
165 | {
166 | versionsPtr++;
167 | *versionsPtr = slots[slotIndex].version;
168 | }
169 | foreach (var slotIndex in _maskExc)
170 | {
171 | versionsPtr++;
172 | *versionsPtr = slots[slotIndex].version;
173 | }
174 | }
175 | public bool CheckAndNext()
176 | {
177 | if (*_versions == _world.Version)
178 | {
179 | return true;
180 | }
181 | *_versions = _world.Version;
182 |
183 | long* versionsPtr = _versions;
184 | var slots = _world._poolSlots;
185 | // Так как проверки EXC работают не правильно при отсутсвии INC,
186 | // то проверки без INC должны всегда возвращать false.
187 | bool result = _maskInc.Length > 0;
188 | foreach (var slotIndex in _maskInc)
189 | {
190 | versionsPtr++;
191 | if (*versionsPtr != slots[slotIndex].version)
192 | {
193 | result = false;
194 | *versionsPtr = slots[slotIndex].version;
195 | }
196 | }
197 | foreach (var slotIndex in _maskExc)
198 | {
199 | versionsPtr++;
200 | if (*versionsPtr != slots[slotIndex].version)
201 | {
202 | result = false;
203 | *versionsPtr = slots[slotIndex].version;
204 | }
205 | }
206 | return result;
207 | }
208 |
209 | public void Dispose()
210 | {
211 | UnmanagedArrayUtility.Free(_versions);
212 | }
213 | }
214 | }
--------------------------------------------------------------------------------
/src/Executors/MaskQueryExecutor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7c672e7ce63d932459174248bd154d07
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Executors/Queries.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core;
5 | using DCFApixels.DragonECS.Core.Internal;
6 | using System;
7 |
8 | namespace DCFApixels.DragonECS
9 | {
10 | public interface IEntityStorage
11 | {
12 | EcsWorld World { get; }
13 | EcsSpan ToSpan();
14 | }
15 | public static class QueriesExtensions
16 | {
17 | #region Where
18 | public static EcsSpan Where(this TCollection entities, out TAspect aspect)
19 | where TAspect : new()
20 | where TCollection : IEntityStorage
21 | {
22 | return entities.ToSpan().Where(out aspect);
23 | }
24 | public static EcsSpan Where(this EcsReadonlyGroup group, out TAspect aspect)
25 | where TAspect : new()
26 | {
27 | return group.ToSpan().Where(out aspect);
28 | }
29 | public static EcsSpan Where(this EcsSpan span, out TAspect aspect)
30 | where TAspect : new()
31 | {
32 | span.World.GetQueryCache(out EcsWhereExecutor executor, out aspect);
33 | return executor.ExecuteFor(span);
34 | }
35 |
36 | public static EcsSpan Where(this TCollection entities, IComponentMask mask)
37 | where TCollection : IEntityStorage
38 | {
39 | return entities.ToSpan().Where(mask);
40 | }
41 | public static EcsSpan Where(this EcsReadonlyGroup group, IComponentMask mask)
42 | {
43 | return group.ToSpan().Where(mask);
44 | }
45 | public static EcsSpan Where(this EcsSpan span, IComponentMask mask)
46 | {
47 | var executor = span.World.GetExecutorForMask(mask);
48 | return executor.ExecuteFor(span);
49 | }
50 | #endregion
51 |
52 | #region Where with sort
53 | public static EcsSpan Where(this TCollection entities, out TAspect aspect, Comparison comparison)
54 | where TAspect : new()
55 | where TCollection : IEntityStorage
56 | {
57 | return entities.ToSpan().Where(out aspect, comparison);
58 | }
59 | public static EcsSpan Where(this EcsReadonlyGroup group, out TAspect aspect, Comparison comparison)
60 | where TAspect : new()
61 | {
62 | return group.ToSpan().Where(out aspect, comparison);
63 | }
64 | public static EcsSpan Where(this EcsSpan span, out TAspect aspect, Comparison comparison)
65 | where TAspect : new()
66 | {
67 | span.World.GetQueryCache(out EcsWhereExecutor executor, out aspect);
68 | return executor.ExecuteFor(span, comparison);
69 | }
70 |
71 | public static EcsSpan Where(this TCollection entities, IComponentMask mask, Comparison comparison)
72 | where TCollection : IEntityStorage
73 | {
74 | return entities.ToSpan().Where(mask, comparison);
75 | }
76 | public static EcsSpan Where(this EcsReadonlyGroup group, IComponentMask mask, Comparison comparison)
77 | {
78 | return group.ToSpan().Where(mask, comparison);
79 | }
80 | public static EcsSpan Where(this EcsSpan span, IComponentMask mask, Comparison comparison)
81 | {
82 | var executor = span.World.GetExecutorForMask(mask);
83 | return executor.ExecuteFor(span);
84 | }
85 | #endregion
86 |
87 | #region WhereToGroup
88 | public static EcsReadonlyGroup WhereToGroup(this TCollection entities, out TAspect aspect)
89 | where TAspect : new()
90 | where TCollection : IEntityStorage
91 | {
92 | return entities.ToSpan().WhereToGroup(out aspect);
93 | }
94 | public static EcsReadonlyGroup WhereToGroup(this EcsReadonlyGroup group, out TAspect aspect)
95 | where TAspect : new()
96 | {
97 | return group.ToSpan().WhereToGroup(out aspect);
98 | }
99 | public static EcsReadonlyGroup WhereToGroup(this EcsSpan span, out TAspect aspect)
100 | where TAspect : new()
101 | {
102 | span.World.GetQueryCache(out EcsWhereToGroupExecutor executor, out aspect);
103 | return executor.ExecuteFor(span);
104 | }
105 |
106 | public static EcsReadonlyGroup WhereToGroup(this TCollection entities, IComponentMask mask)
107 | where TCollection : IEntityStorage
108 | {
109 | return entities.ToSpan().WhereToGroup(mask);
110 | }
111 | public static EcsReadonlyGroup WhereToGroup(this EcsReadonlyGroup group, IComponentMask mask)
112 | {
113 | return group.ToSpan().WhereToGroup(mask);
114 | }
115 | public static EcsReadonlyGroup WhereToGroup(this EcsSpan span, IComponentMask mask)
116 | {
117 | var executor = span.World.GetExecutorForMask(mask);
118 | return executor.ExecuteFor(span);
119 | }
120 | #endregion
121 | }
122 | }
--------------------------------------------------------------------------------
/src/Executors/Queries.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 41740479532f2a543acd1ba18bf95af9
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Injections.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 546107521fffb574e8db9730a87c7337
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Injections/EcsPipelineExtensions.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core.Internal;
5 |
6 | namespace DCFApixels.DragonECS
7 | {
8 | public static partial class EcsPipelineBuilderExtensions
9 | {
10 | public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T data)
11 | {
12 | if (data == null) { Throw.ArgumentNull(); }
13 | self.Injector.Inject(data);
14 | if (data is IEcsModule module)
15 | {
16 | self.AddModule(module);
17 | }
18 | return self;
19 | }
20 | public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1)
21 | {
22 | return self.Inject(d0).Inject(d1);
23 | }
24 | public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2)
25 | {
26 | return self.Inject(d0).Inject(d1).Inject(d2);
27 | }
28 | public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3)
29 | {
30 | return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3);
31 | }
32 | public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4)
33 | {
34 | return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4);
35 | }
36 | public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 d5)
37 | {
38 | return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(d5);
39 | }
40 | public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 d5, T6 d6)
41 | {
42 | return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(d5).Inject(d6);
43 | }
44 | public static EcsPipeline.Builder Inject(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 d5, T6 d6, T7 d7)
45 | {
46 | return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(d5).Inject(d6).Inject(d7);
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Injections/EcsPipelineExtensions.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6e83a9465b34a8148936bba8c2ee46ac
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Injections/Graph.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b2dfe81532e7bfc4b805fdad7e75885c
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Injections/Graph/InjectionBranch.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace DCFApixels.DragonECS.Core.Internal
8 | {
9 | internal class InjectionBranch
10 | {
11 | private readonly Injector _source;
12 | private readonly Type _type;
13 | private InjectionNodeBase[] _nodes = new InjectionNodeBase[4];
14 | private int _nodesCount = 0;
15 |
16 | public Type Type
17 | {
18 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
19 | get { return _type; }
20 | }
21 | public ReadOnlySpan Nodes
22 | {
23 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
24 | get { return new ReadOnlySpan(_nodes, 0, _nodesCount); }
25 | }
26 | public InjectionBranch(Injector source, Type type)
27 | {
28 | _source = source;
29 | _type = type;
30 | }
31 | public void Inject(object obj)
32 | {
33 | for (int i = 0; i < _nodesCount; i++)
34 | {
35 | _nodes[i].Inject(obj);
36 | }
37 | if (obj is IInjectionBlock block)
38 | {
39 | block.InjectTo(_source);
40 | }
41 | }
42 | public void AddNode(InjectionNodeBase node)
43 | {
44 | if (_nodesCount >= _nodes.Length)
45 | {
46 | Array.Resize(ref _nodes, (_nodes.Length << 1) + 1);
47 | }
48 | _nodes[_nodesCount++] = node;
49 | }
50 | public void Trim()
51 | {
52 | if (_nodesCount <= 0)
53 | {
54 | _nodes = Array.Empty();
55 | return;
56 | }
57 |
58 | InjectionNodeBase[] newNodes = new InjectionNodeBase[_nodesCount];
59 | for (int i = 0; i < newNodes.Length; i++)
60 | {
61 | newNodes[i] = _nodes[i];
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Injections/Graph/InjectionBranch.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: eb1a80182ece42c4281aaf3257cd727c
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Injections/Graph/InjectionNode.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace DCFApixels.DragonECS
8 | {
9 | public abstract class InjectionNodeBase
10 | {
11 | private readonly Type _type;
12 | public Type Type { get { return _type; } }
13 | public abstract object CurrentInjectedDependencyRaw { get; }
14 | protected InjectionNodeBase(Type type) { _type = type; }
15 | public abstract void Inject(object obj);
16 | public abstract void ExtractTo(object target);
17 | public abstract void Init(EcsPipeline pipeline);
18 | }
19 | }
20 | namespace DCFApixels.DragonECS.Core.Internal
21 | {
22 | internal sealed class InjectionNode : InjectionNodeBase
23 | {
24 | private EcsPipeline _pipeline;
25 | private EcsProcess> _process;
26 | private T _currentInjectedDependency;
27 | public sealed override object CurrentInjectedDependencyRaw
28 | {
29 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
30 | get { return _currentInjectedDependency; }
31 | }
32 | public T CurrentInjectedDependency
33 | {
34 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
35 | get { return _currentInjectedDependency; }
36 | }
37 | public InjectionNode() : base(typeof(T)) { }
38 | public sealed override void Init(EcsPipeline pipeline)
39 | {
40 | _pipeline = pipeline;
41 | _process = pipeline.GetProcess>();
42 | }
43 | public sealed override void Inject(object raw)
44 | {
45 | T obj = (T)raw;
46 | _currentInjectedDependency = obj;
47 | for (int i = 0; i < _process.Length; i++)
48 | {
49 | _process[i].Inject(obj);
50 | }
51 | foreach (var runner in _pipeline.AllRunners)
52 | {
53 | ExtractTo_Internal(runner.Value);
54 | }
55 | }
56 | public sealed override void ExtractTo(object target)
57 | {
58 | if (_currentInjectedDependency == null) { return; }
59 | ExtractTo_Internal(target);
60 | }
61 | private void ExtractTo_Internal(object target)
62 | {
63 | var type = target.GetType();
64 | var intrfs = type.GetInterfaces();
65 | if (target is IEcsInject intrf)
66 | {
67 | intrf.Inject(_currentInjectedDependency);
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/Injections/Graph/InjectionNode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: da1da7839b55e5e45a04ee8fa740ba5a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Injections/Injector.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core.Internal;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Runtime.CompilerServices;
9 |
10 | namespace DCFApixels.DragonECS
11 | {
12 | public class Injector : IInjector
13 | {
14 | private EcsPipeline _pipeline;
15 | private Dictionary _branches = new Dictionary(32);
16 | private Dictionary _nodes = new Dictionary(32);
17 | private bool _isInit = false;
18 |
19 | #if DEBUG
20 | private HashSet _requiredInjectionTypes = new HashSet();
21 | #endif
22 |
23 | public EcsPipeline Pipelie
24 | {
25 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
26 | get { return _pipeline; }
27 | }
28 |
29 | private Injector() { }
30 |
31 | #region Inject/Extract/AddNode
32 | public void Inject(T obj)
33 | {
34 | object raw = obj;
35 | Type tType = typeof(T);
36 | Type objType = obj.GetType();
37 | if (_branches.TryGetValue(objType, out InjectionBranch branch) == false)
38 | {
39 | if (_nodes.ContainsKey(tType) == false)
40 | {
41 | InitNode(new InjectionNode());
42 | }
43 | bool hasNode = _nodes.ContainsKey(objType);
44 | if (hasNode == false && obj is IInjectionUnit unit)
45 | {
46 | unit.InitInjectionNode(new InjectionGraph(this));
47 | hasNode = _nodes.ContainsKey(objType);
48 | }
49 |
50 | branch = new InjectionBranch(this, objType);
51 | InitBranch(branch);
52 |
53 | #if DEBUG
54 | foreach (var requiredInjectionType in _requiredInjectionTypes)
55 | {
56 | if (requiredInjectionType.IsAssignableFrom(objType))
57 | {
58 | if (_nodes.ContainsKey(requiredInjectionType) == false)
59 | {
60 | throw new InjectionException($"A systems in the pipeline implements IEcsInject<{requiredInjectionType.Name}> interface, but no suitable injection node was found in the Injector. To create a node, use Injector.AddNode<{requiredInjectionType.Name}>() or implement the IInjectionUnit interface for type {objType.Name}.");
61 | }
62 | }
63 | }
64 | #endif
65 | }
66 | branch.Inject(raw);
67 | }
68 | public void ExtractAllTo(object target)
69 | {
70 | if (target is IEcsInjectProcess == false) { return; }
71 |
72 | foreach (var node in _nodes)
73 | {
74 | node.Value.ExtractTo(target);
75 | }
76 | }
77 | public T Extract()
78 | {
79 | return (T)Extract_Internal(typeof(T));
80 | }
81 | private object Extract_Internal(Type type)//TODO проверить
82 | {
83 | if (_nodes.TryGetValue(type, out InjectionNodeBase node))
84 | {
85 | return node.CurrentInjectedDependencyRaw;
86 | }
87 | throw new InjectionException($"The injection graph is missing a node for {type.Name} type. To create a node, use the Injector.AddNode<{type.Name}>() method directly in the injector or in the implementation of the IInjectionUnit for {type.Name}.");
88 | }
89 | public void AddNode()
90 | {
91 | if (_nodes.ContainsKey(typeof(T)) == false)
92 | {
93 | InitNode(new InjectionNode());
94 | }
95 | }
96 | #endregion
97 |
98 | #region Internal
99 | private void InitBranch(InjectionBranch branch)
100 | {
101 | _branches.Add(branch.Type, branch);
102 | foreach (var item in _nodes)
103 | {
104 | var type = item.Key;
105 | var node = item.Value;
106 | if (type.IsAssignableFrom(branch.Type))
107 | {
108 | branch.AddNode(node);
109 | }
110 | }
111 | }
112 | private void InitNode(InjectionNodeBase node)
113 | {
114 | if (_pipeline != null)
115 | {
116 | node.Init(_pipeline);
117 | }
118 | _nodes.Add(node.Type, node);
119 | foreach (var item in _branches)
120 | {
121 | //var type = item.Key;
122 | var branch = item.Value;
123 | if (node.Type.IsAssignableFrom(branch.Type))
124 | {
125 | branch.AddNode(node);
126 | }
127 | }
128 | }
129 | private bool IsCanInstantiated(Type type)
130 | {
131 | return !type.IsAbstract && !type.IsInterface;
132 | }
133 | #endregion
134 |
135 | #region Build
136 | private void Init(EcsPipeline pipeline)
137 | {
138 | if (_isInit) { Throw.Exception("Already initialized"); }
139 |
140 | _pipeline = pipeline;
141 | foreach (var pair in _nodes)
142 | {
143 | pair.Value.Init(pipeline);
144 | }
145 | _isInit = true;
146 |
147 | #if DEBUG
148 | var systems = _pipeline.AllSystems;
149 | var injectType = typeof(IEcsInject<>);
150 | foreach (var system in systems)
151 | {
152 | var type = system.GetType();
153 | foreach (var requiredInjectionType in type.GetInterfaces().Where(o => o.IsGenericType && o.GetGenericTypeDefinition() == injectType).Select(o => o.GenericTypeArguments[0]))
154 | {
155 | _requiredInjectionTypes.Add(requiredInjectionType);
156 | }
157 | }
158 | #endif
159 | }
160 | private bool TryDeclare()
161 | {
162 | Type type = typeof(T);
163 | if (_nodes.ContainsKey(type))
164 | {
165 | return false;
166 | }
167 | InitNode(new InjectionNode());
168 | #if !REFLECTION_DISABLED
169 | if (IsCanInstantiated(type))
170 | #endif
171 | {
172 | InitBranch(new InjectionBranch(this, type));
173 | }
174 | return true;
175 | }
176 |
177 | public class Builder : IInjector
178 | {
179 | private EcsPipeline.Builder _source;
180 | private Injector _instance;
181 | private List _initInjections = new List(16);
182 | private EcsWorld _monoWorld;
183 | internal Builder(EcsPipeline.Builder source)
184 | {
185 | _source = source;
186 | _instance = new Injector();
187 | }
188 | public EcsPipeline.Builder AddNode()
189 | {
190 | _instance.TryDeclare();
191 | return _source;
192 | }
193 | public EcsPipeline.Builder Inject(T obj)
194 | {
195 | if (obj is EcsWorld objWorld)
196 | {
197 | if (_monoWorld == null)
198 | {
199 | _monoWorld = objWorld;
200 | }
201 | else
202 | {
203 | Type monoWorldType = _monoWorld.GetType();
204 | Type objWorldType = objWorld.GetType();
205 | if (monoWorldType != objWorldType)
206 | {
207 | if (objWorldType == typeof(EcsWorld))
208 | { // Екземпляр EcsWorld имеет самый больший приоритет.
209 | _monoWorld = objWorld;
210 | }
211 | if (objWorldType == typeof(EcsDefaultWorld) &&
212 | monoWorldType != typeof(EcsWorld))
213 | { // Екземпляр EcsDefaultWorld имеет приоритет больше других типов, но меньше приоритета EcsWorld.
214 | _monoWorld = objWorld;
215 | }
216 | }
217 | }
218 | }
219 | _initInjections.Add(new InitInject(obj));
220 | return _source;
221 | }
222 | public EcsPipeline.Builder Extract(ref T obj) // TODO проверить
223 | {
224 | Type type = typeof(T);
225 | for (int i = _initInjections.Count - 1; i >= 0; i--)
226 | {
227 | var item = _initInjections[i];
228 | if (type.IsAssignableFrom(item.Type))
229 | {
230 | obj = (T)item.Raw;
231 | return _source;
232 | }
233 | }
234 | Throw.UndefinedException();
235 | return default;
236 | }
237 | public Injector Build(EcsPipeline pipeline)
238 | {
239 | var monoWorldProcess = pipeline.GetProcess(); // TODO Проверить IMonoWorldInject
240 | foreach (var monoWorldSystem in monoWorldProcess)
241 | {
242 | monoWorldSystem.World = _monoWorld;
243 | }
244 |
245 |
246 | var initInjectionCallbacks = pipeline.GetProcess();
247 | foreach (var system in initInjectionCallbacks)
248 | {
249 | system.OnBeforeInitInjection();
250 | }
251 | _instance.Init(pipeline);
252 | foreach (var item in _initInjections)
253 | {
254 | item.InjectTo(_instance);
255 | }
256 | foreach (var system in initInjectionCallbacks)
257 | {
258 | system.OnInitInjectionComplete();
259 | }
260 | return _instance;
261 | }
262 | public void Add(Builder other)
263 | {
264 | foreach (var item in other._initInjections)
265 | {
266 | _initInjections.Add(item);
267 | }
268 | }
269 |
270 | void IInjector.Inject(T obj) { Inject(obj); }
271 | T IInjector.Extract()
272 | {
273 | T result = default;
274 | Extract(ref result);
275 | return result;
276 | }
277 |
278 | private abstract class InitInjectBase
279 | {
280 | public abstract Type Type { get; }
281 | public abstract object Raw { get; }
282 | public abstract void InjectTo(Injector instance);
283 | }
284 | private sealed class InitInject : InitInjectBase
285 | {
286 | private T _injectedData;
287 | public override Type Type { get { return typeof(T); } }
288 | public override object Raw { get { return _injectedData; } }
289 | public InitInject(T injectedData)
290 | {
291 | _injectedData = injectedData;
292 | }
293 | public override void InjectTo(Injector instance)
294 | {
295 | instance.Inject(_injectedData);
296 | }
297 | }
298 | }
299 | #endregion
300 | }
301 | }
--------------------------------------------------------------------------------
/src/Injections/Injector.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 06cb87ee84ccf854d95ddb744081f667
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Injections/Utils.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f5d8c72b3decc2b488a616932366ff0f
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Injections/Utils/Interfaces.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 |
5 | namespace DCFApixels.DragonECS
6 | {
7 | public interface IEcsInjectProcess : IEcsProcess { }
8 | [MetaName(nameof(Inject))]
9 | [MetaColor(MetaColor.DragonRose)]
10 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DI_GROUP)]
11 | [MetaDescription(EcsConsts.AUTHOR, "The interface of the dependency injection process.")]
12 | [MetaID("DragonECS_4C86537C92019AA24383CBF53CBD456C")]
13 | public interface IEcsInject : IEcsInjectProcess
14 | {
15 | void Inject(T obj);
16 | }
17 | public interface IMonoWorldInject : IEcsProcess
18 | {
19 | EcsWorld World { get; set; }
20 | }
21 | [MetaName(nameof(OnInitInjectionComplete))]
22 | [MetaColor(MetaColor.DragonRose)]
23 | [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DI_GROUP)]
24 | [MetaDescription(EcsConsts.AUTHOR, "The process interface that signals the completion of injection during pipeline initialization via the EcsPipeline.Init() method.")]
25 | [MetaID("DragonECS_05C3537C920155AFC044C900E4F17D90")]
26 | public interface IOnInitInjectionComplete : IEcsProcess
27 | {
28 | void OnBeforeInitInjection();
29 | void OnInitInjectionComplete();
30 | }
31 | public interface IInjector
32 | {
33 | void Inject(T obj);
34 | T Extract();
35 | }
36 | public interface IInjectionBlock
37 | {
38 | void InjectTo(Injector inj);
39 | }
40 | public readonly struct InjectionGraph
41 | {
42 | private readonly Injector _injector;
43 | internal InjectionGraph(Injector injector)
44 | {
45 | _injector = injector;
46 | }
47 | public void AddNode(T obj = default)
48 | {
49 | _injector.AddNode();
50 | }
51 | }
52 | public interface IInjectionUnit
53 | {
54 | void InitInjectionNode(InjectionGraph graph);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Injections/Utils/Interfaces.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ee045b3db15333b46944240b586a7d92
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8aab9d072e532314286f6c3a2d3fe128
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Internal/Allocators.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d8485ca259b2d014c8923171b4c314a8
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Internal/Allocators/AllocatorUtility.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DCFApixels.DragonECS.Core.Internal
4 | {
5 | internal static class AllocatorUtility
6 | {
7 | public static unsafe void ClearAllocatedMemory(IntPtr ptr, int startByte, int lengthInBytes)
8 | {
9 | ClearAllocatedMemory((byte*)ptr, startByte, lengthInBytes);
10 | }
11 | public static unsafe void ClearAllocatedMemory(byte* ptr, int startByte, int lengthInBytes)
12 | {
13 | Span memorySpan = new Span(ptr + startByte, lengthInBytes);
14 | memorySpan.Clear();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Internal/Allocators/AllocatorUtility.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c81510e4026b0884abe28740af408e53
--------------------------------------------------------------------------------
/src/Internal/Allocators/MemoryAllocator.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace DCFApixels.DragonECS.Core.Internal
8 | {
9 | internal unsafe static class MemoryAllocator
10 | {
11 | #if DEBUG
12 | private static IdDispenser _idDispenser;
13 | private static HandlerDebugInfo[] _debugInfos;
14 | #endif
15 |
16 | static MemoryAllocator()
17 | {
18 | StaticInit();
19 | }
20 | private static void StaticInit()
21 | {
22 | #if DEBUG
23 | _idDispenser = new IdDispenser();
24 | _debugInfos = new HandlerDebugInfo[32];
25 | #endif
26 | }
27 |
28 | #region AllocAndInit
29 | public static Handler AllocAndInit(int count) where T : unmanaged
30 | {
31 | return AllocAndInit_Internal(Marshal.SizeOf() * count, typeof(T));
32 | }
33 | public static Handler AllocAndInit(int byteLength)
34 | {
35 | return AllocAndInit_Internal(byteLength, null);
36 | }
37 | public static Handler AllocAndInit_Internal(int byteLength, Type type)
38 | {
39 | Handler handler = Alloc_Internal(byteLength, type);
40 | AllocatorUtility.ClearAllocatedMemory(handler.Ptr, 0, byteLength);
41 | return handler;
42 | }
43 | #endregion
44 |
45 | #region Alloc
46 | public static Handler Alloc(int count) where T : unmanaged
47 | {
48 | return Alloc_Internal(Marshal.SizeOf() * count, typeof(T));
49 | }
50 | public static Handler Alloc(int byteLength)
51 | {
52 | return Alloc_Internal(byteLength, null);
53 | }
54 | public static Handler Alloc_Internal(int byteLength, Type type)
55 | {
56 | byteLength = byteLength == 0 ? 1 : byteLength;
57 | #if DEBUG
58 | int id = 0;
59 | lock (_idDispenser)
60 | {
61 | if (_debugInfos.Length <= _idDispenser.Count)
62 | {
63 | Array.Resize(ref _debugInfos, _debugInfos.Length << 1);
64 | }
65 | id = _idDispenser.UseFree();
66 | }
67 | #endif
68 | Meta* newHandledPtr = (Meta*)Marshal.AllocHGlobal(byteLength + sizeof(Meta));
69 | Handler handler = Handler.FromHandledPtr(newHandledPtr);
70 |
71 | #if DEBUG
72 | newHandledPtr->ID = id;
73 | newHandledPtr->ByteLength = byteLength;
74 |
75 | #if DRAGONECS_DEEP_DEBUG
76 | _debugInfos[id].stackTrace = new System.Diagnostics.StackTrace();
77 | #endif
78 | _debugInfos[id].type = type;
79 | _debugInfos[id].handler = handler;
80 | #endif
81 |
82 | return handler;
83 | }
84 | #endregion
85 |
86 | #region ReallocAndInit
87 | public static Handler ReallocAndInit(void* target, int oldCount, int newCount) where T : unmanaged
88 | {
89 | return ReallocAndInit(Handler.FromDataPtr(target), oldCount, newCount);
90 | }
91 | public static Handler ReallocAndInit(void* target, int oldByteLength, int newByteLength)
92 | {
93 | return ReallocAndInit(Handler.FromDataPtr(target), oldByteLength, newByteLength);
94 | }
95 | public static Handler ReallocAndInit(Handler target, int oldCount, int newCount) where T : unmanaged
96 | {
97 | var size = Marshal.SizeOf();
98 | return ReallocAndInit_Internal(target, size * oldCount, size * newCount, typeof(T));
99 | }
100 | public static Handler ReallocAndInit(Handler target, int oldByteLength, int newByteLength)
101 | {
102 | return ReallocAndInit_Internal(target, oldByteLength, newByteLength, null);
103 | }
104 | private static Handler ReallocAndInit_Internal(Handler target, int oldByteLength, int newByteLength, Type newType)
105 | {
106 | Handler handler = Realloc_Internal(target, newByteLength, newType);
107 | AllocatorUtility.ClearAllocatedMemory(handler.Ptr, oldByteLength, newByteLength - oldByteLength);
108 | return handler;
109 | }
110 | #endregion
111 |
112 | #region Realloc
113 | public static Handler Realloc(void* target, int newCount) where T : unmanaged
114 | {
115 | return Realloc(Handler.FromDataPtr(target), Marshal.SizeOf() * newCount);
116 | }
117 | public static Handler Realloc(void* target, int newByteLength)
118 | {
119 | return Realloc(Handler.FromDataPtr(target), newByteLength);
120 | }
121 | public static Handler Realloc(Handler target, int newCount) where T : unmanaged
122 | {
123 | return Realloc_Internal(target, Marshal.SizeOf() * newCount, typeof(T));
124 | }
125 | public static Handler Realloc(Handler target, int newByteLength)
126 | {
127 | return Realloc_Internal(target, newByteLength, null);
128 | }
129 | private static Handler Realloc_Internal(Handler target, int newByteLength, Type newType)
130 | {
131 | newByteLength = newByteLength == 0 ? 1 : newByteLength;
132 | Meta* newHandledPtr = (Meta*)Marshal.ReAllocHGlobal((IntPtr)target.GetHandledPtr(), (IntPtr)newByteLength + sizeof(Meta));
133 | Handler handler = Handler.FromHandledPtr(newHandledPtr);
134 | #if DEBUG
135 | #if DRAGONECS_DEEP_DEBUG
136 | _debugInfos[newHandledPtr->ID].stackTrace = new System.Diagnostics.StackTrace();
137 | #endif
138 | _debugInfos[newHandledPtr->ID].type = newType;
139 | _debugInfos[newHandledPtr->ID].handler = handler;
140 | #endif
141 | return handler;
142 | }
143 | #endregion
144 |
145 | #region Free
146 | public static void Free(ref Handler target)
147 | {
148 | Free_Internal(target.GetHandledPtr());
149 | target = default;
150 | }
151 | public static void Free(void* dataPtr)
152 | {
153 | Free_Internal(((Meta*)dataPtr) - 1);
154 | }
155 | private static void Free_Internal(Meta* handledPtr)
156 | {
157 | #if DEBUG
158 | lock (_idDispenser)
159 | {
160 | _idDispenser.Release(handledPtr->ID);
161 | _debugInfos[handledPtr->ID] = default;
162 | }
163 | handledPtr->ID = default;
164 | handledPtr->ByteLength = default;
165 | #endif
166 | Marshal.FreeHGlobal((IntPtr)handledPtr);
167 | }
168 | #endregion
169 |
170 | #region Other
171 | internal static StateDebugInfo GetHandlerInfos_Debug()
172 | {
173 | StateDebugInfo result = default;
174 | #if DEBUG
175 | result.idDispenser = _idDispenser;
176 | result.debugInfos = _debugInfos;
177 | #endif
178 | return result;
179 | }
180 |
181 | internal struct Meta
182 | {
183 | #if DEBUG
184 | public int ID;
185 | public int ByteLength;
186 | #endif
187 | }
188 |
189 | #if DEBUG
190 | [System.Diagnostics.DebuggerDisplay("{handler.DebuggerDisplay()}")]
191 | #endif
192 | internal struct HandlerDebugInfo
193 | {
194 | #if DEBUG
195 | #if DRAGONECS_DEEP_DEBUG
196 | public System.Diagnostics.StackTrace stackTrace;
197 | #endif
198 | public Type type;
199 | public Handler handler;
200 | #endif
201 | }
202 | internal struct StateDebugInfo
203 | {
204 | public HandlerDebugInfo[] debugInfos;
205 | public IdDispenser idDispenser;
206 | }
207 | #endregion
208 |
209 | #if DEBUG
210 | [System.Diagnostics.DebuggerDisplay("{DebuggerDisplay()}")]
211 | [System.Diagnostics.DebuggerTypeProxy(typeof(DebuggerProxy))]
212 | #endif
213 | public readonly struct Handler : IDisposable
214 | {
215 | public static readonly Handler Empty = new Handler();
216 | internal readonly Meta* Data; // Data[-1] is meta;
217 | private Handler(Meta* dataPtr) { Data = dataPtr; }
218 | public static Handler FromHandledPtr(void* ptr) { return new Handler(((Meta*)ptr) + 1); }
219 | public static Handler FromDataPtr(void* ptr) { return new Handler((Meta*)ptr); }
220 | internal Meta* GetHandledPtr() { return Data - 1; }
221 | internal int GetID_Debug()
222 | {
223 | #if DEBUG
224 | return GetHandledPtr()->ID;
225 | #else
226 | return 0;
227 | #endif
228 | }
229 | internal int GetByteLength_Debug()
230 | {
231 | #if DEBUG
232 | return GetHandledPtr()->ByteLength;
233 | #else
234 | return 0;
235 | #endif
236 | }
237 |
238 | public bool IsEmpty { get { return Data == null; } }
239 | public IntPtr Ptr { get { return (IntPtr)Data; } }
240 | public T* As() where T : unmanaged { return (T*)Ptr; }
241 |
242 | void IDisposable.Dispose() { Free((void*)Ptr); }
243 |
244 | #region Debugger
245 | #if DEBUG
246 | #pragma warning disable IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
247 | internal unsafe string DebuggerDisplay()
248 | {
249 | if (Data == null)
250 | {
251 | return "-";
252 | }
253 |
254 | Meta meta = GetHandledPtr()[0];
255 | HandlerDebugInfo info = _debugInfos[meta.ID];
256 |
257 | if (info.type == null)
258 | {
259 | return $"Count: {meta.ByteLength} Unknown";
260 | }
261 |
262 | return $"Count: {meta.ByteLength / Marshal.SizeOf(info.type)} {info.type.Name}";
263 | }
264 | internal static Array CreateArray_Debug(Type type, int count, byte* data, int byteLength)
265 | {
266 | var array = Array.CreateInstance(type, count);
267 | if (array.Length > 0)
268 | {
269 | Union union = default;
270 | union.array = array;
271 | fixed (byte* arrayPtr = union.bytes)
272 | {
273 | for (int i = 0; i < byteLength; i++)
274 | {
275 | arrayPtr[i] = data[i];
276 | }
277 | }
278 | }
279 | return array;
280 | }
281 | [StructLayout(LayoutKind.Explicit)]
282 | private unsafe struct Union
283 | {
284 | [FieldOffset(0)]
285 | public Array array;
286 | [FieldOffset(0)]
287 | public byte[] bytes;
288 | }
289 | private class DebuggerProxy
290 | {
291 | private byte* _data;
292 | private Type _type;
293 | private int _count;
294 |
295 | public bool IsAlive;
296 | public Meta Meta;
297 | public HandlerDebugInfo DebugInfo;
298 | public Array Data;
299 |
300 | public HandlerDebugInfo[] OtherHandlersInfo;
301 |
302 | public unsafe DebuggerProxy(Handler handler)
303 | {
304 | IsAlive = handler.Ptr.ToPointer() != null;
305 | if (IsAlive == false) { return; }
306 |
307 | Meta = handler.GetHandledPtr()[0];
308 | _data = (byte*)handler.Ptr;
309 | DebugInfo = _debugInfos[Meta.ID];
310 |
311 | if (DebugInfo.type == null)
312 | {
313 | _type = typeof(byte);
314 | }
315 | else
316 | {
317 | _type = DebugInfo.type;
318 | }
319 |
320 | var size = Marshal.SizeOf(_type);
321 | _count = Meta.ByteLength / size;
322 |
323 | Data = CreateArray_Debug(_type, _count, _data, Meta.ByteLength);
324 |
325 | OtherHandlersInfo = _debugInfos;
326 | }
327 | }
328 | #pragma warning restore IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
329 | #endif
330 | #endregion
331 | }
332 | }
333 |
334 | internal static class MemoryAllocatorHandlerExtensions
335 | {
336 | public static void Dispose(this ref MemoryAllocator.Handler self)
337 | {
338 | MemoryAllocator.Free(ref self);
339 | }
340 | }
341 | }
--------------------------------------------------------------------------------
/src/Internal/Allocators/MemoryAllocator.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8c0a1776ab4060b4b9feb6349b708109
--------------------------------------------------------------------------------
/src/Internal/Allocators/TempBuffer.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Runtime.CompilerServices;
6 | using System.Runtime.InteropServices;
7 | #if ENABLE_IL2CPP
8 | using Unity.IL2CPP.CompilerServices;
9 | #endif
10 |
11 | namespace DCFApixels.DragonECS.Core.Internal
12 | {
13 | #if ENABLE_IL2CPP
14 | [Il2CppSetOption(Option.NullChecks, false)]
15 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
16 | #endif
17 | public static unsafe class TempBuffer where T : unmanaged
18 | {
19 | [ThreadStatic] private static T* _ptr;
20 | [ThreadStatic] private static int _size;
21 |
22 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
23 | public static T* Get(int size)
24 | {
25 | if (_size < size)
26 | {
27 | _ptr = TempBufferMemory.Get(size);
28 | _size = size;
29 | }
30 | return _ptr;
31 | }
32 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
33 | public static void Clear()
34 | {
35 | TempBufferMemory.Clear();
36 | }
37 | }
38 | #if ENABLE_IL2CPP
39 | [Il2CppSetOption(Option.NullChecks, false)]
40 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
41 | #endif
42 | internal static unsafe class TempBufferMemory
43 | {
44 | [ThreadStatic] private static byte* _ptr;
45 | [ThreadStatic] private static int _byteSize;
46 |
47 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
48 | public static T* Get(int size) where T : unmanaged
49 | {
50 | int byteSize = size * Marshal.SizeOf();
51 | if (_byteSize < byteSize)
52 | {
53 | if (_ptr != null)
54 | {
55 | MemoryAllocator.Free(_ptr);
56 | }
57 | _ptr = MemoryAllocator.Alloc(byteSize).As();
58 | _byteSize = byteSize;
59 | }
60 | return (T*)_ptr;
61 | }
62 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
63 | public static void Clear()
64 | {
65 | AllocatorUtility.ClearAllocatedMemory(_ptr, 0, _byteSize);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Internal/Allocators/TempBuffer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 46a39f6bfdf79e14eb05750c78f1c061
--------------------------------------------------------------------------------
/src/Internal/ArraySortHalperX.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Runtime.CompilerServices;
7 | #if ENABLE_IL2CPP
8 | using Unity.IL2CPP.CompilerServices;
9 | #endif
10 |
11 | namespace DCFApixels.DragonECS.Core.Internal
12 | {
13 | internal interface IStructComparer : IComparer
14 | {
15 | // a > b = return > 0
16 | // int Compare(T a, T b);
17 | }
18 |
19 | #if ENABLE_IL2CPP
20 | [Il2CppSetOption(Option.NullChecks, false)]
21 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
22 | #endif
23 | internal static class ArraySortHalperX
24 | {
25 | private const int IntrosortSizeThreshold = 16;
26 |
27 | #region IStructComparer
28 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
29 | public static void SwapIfGreater(T[] items, ref TComparer comparer, int i, int j) where TComparer : IStructComparer
30 | {
31 | if (comparer.Compare(items[i], items[j]) > 0)
32 | {
33 | T key = items[i];
34 | items[i] = items[j];
35 | items[j] = key;
36 | }
37 | }
38 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
39 | public static void InsertionSort(T[] items, ref TComparer comparer) where TComparer : IStructComparer
40 | {
41 | for (int i = 0; i < items.Length - 1; i++)
42 | {
43 | T t = items[i + 1];
44 |
45 | int j = i;
46 | while (j >= 0 && comparer.Compare(t, items[j]) < 0)
47 | {
48 | items[j + 1] = items[j];
49 | j--;
50 | }
51 |
52 | items[j + 1] = t;
53 | }
54 | }
55 |
56 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
57 | public static void Sort(T[] items, ref TComparer comparer) where TComparer : IStructComparer
58 | {
59 | int length = items.Length;
60 | if (length == 1)
61 | {
62 | return;
63 | }
64 |
65 | if (length <= IntrosortSizeThreshold)
66 | {
67 |
68 | if (length == 2)
69 | {
70 | SwapIfGreater(items, ref comparer, 0, 1);
71 | return;
72 | }
73 |
74 | if (length == 3)
75 | {
76 | SwapIfGreater(items, ref comparer, 0, 1);
77 | SwapIfGreater(items, ref comparer, 0, 2);
78 | SwapIfGreater(items, ref comparer, 1, 2);
79 | return;
80 | }
81 |
82 | InsertionSort(items, ref comparer);
83 | return;
84 | }
85 |
86 | IStructComparer packed = comparer;
87 | Array.Sort(items, 0, items.Length, packed);
88 | comparer = (TComparer)packed;
89 | }
90 | #endregion
91 |
92 | #region Comparison
93 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
94 | public static void SwapIfGreater(T[] items, Comparison comparison, int i, int j)
95 | {
96 | if (comparison(items[i], items[j]) > 0)
97 | {
98 | T key = items[i];
99 | items[i] = items[j];
100 | items[j] = key;
101 | }
102 | }
103 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
104 | public static void InsertionSort(T[] items, int length, Comparison comparison)
105 | {
106 | for (int i = 0; i < length - 1; i++)
107 | {
108 | T t = items[i + 1];
109 |
110 | int j = i;
111 | while (j >= 0 && comparison(t, items[j]) < 0)
112 | {
113 | items[j + 1] = items[j];
114 | j--;
115 | }
116 |
117 | items[j + 1] = t;
118 | }
119 | }
120 |
121 | #if ENABLE_IL2CPP
122 | [Il2CppSetOption(Option.NullChecks, false)]
123 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
124 | #endif
125 | private class ComparisonHach : IComparer
126 | {
127 | public static readonly ComparisonHach Instance = new ComparisonHach();
128 | public Comparison comparison;
129 | private ComparisonHach() { }
130 | public int Compare(T x, T y) { return comparison(x, y); }
131 | }
132 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
133 | public static void Sort(T[] items, Comparison comparison)
134 | {
135 | Sort(items, comparison, items.Length);
136 | }
137 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
138 | public static void Sort(T[] items, Comparison comparison, int length)
139 | {
140 | if (length <= IntrosortSizeThreshold)
141 | {
142 | if (length == 1)
143 | {
144 | return;
145 | }
146 | if (length == 2)
147 | {
148 | SwapIfGreater(items, comparison, 0, 1);
149 | return;
150 | }
151 | if (length == 3)
152 | {
153 | SwapIfGreater(items, comparison, 0, 1);
154 | SwapIfGreater(items, comparison, 0, 2);
155 | SwapIfGreater(items, comparison, 1, 2);
156 | return;
157 | }
158 | InsertionSort(items, length, comparison);
159 | return;
160 | }
161 | ComparisonHach.Instance.comparison = comparison;
162 | Array.Sort(items, 0, length, ComparisonHach.Instance);
163 | }
164 | #endregion
165 | }
166 |
167 | #if ENABLE_IL2CPP
168 | [Il2CppSetOption(Option.NullChecks, false)]
169 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
170 | #endif
171 | internal static unsafe class UnsafeArraySortHalperX where T : unmanaged
172 | {
173 | private const int IntrosortSizeThreshold = 16;
174 |
175 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
176 | public static void SwapIfGreater(T* items, ref TComparer comparer, int i, int j) where TComparer : IStructComparer
177 | {
178 | if (comparer.Compare(items[i], items[j]) > 0)
179 | {
180 | T key = items[i];
181 | items[i] = items[j];
182 | items[j] = key;
183 | }
184 | }
185 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
186 | public static void InsertionSort_Unchecked(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer
187 | {
188 | for (int i = 0; i < length - 1; i++)
189 | {
190 | T t = items[i + 1];
191 |
192 | int j = i;
193 | while (j >= 0 && comparer.Compare(t, items[j]) < 0)
194 | {
195 | items[j + 1] = items[j];
196 | j--;
197 | }
198 |
199 | items[j + 1] = t;
200 | }
201 | }
202 | //[MethodImpl(MethodImplOptions.AggressiveInlining)]
203 | //public static void OptimizedBubbleSort_Unchecked(T* items, int length, ref TComparer comparer) where TComparer : IComparerX
204 | //{
205 | // for (int i = 0, n = length - 1; i < n; i++)
206 | // {
207 | // bool noSwaped = true;
208 | // for (int j = 0; j < n - i;)
209 | // {
210 | // ref T j0 = ref items[j++];
211 | // if(comparer.Compare(j0, items[j]) < 0)
212 | // {
213 | // T tmp = items[j];
214 | // items[j] = j0;
215 | // j0 = tmp;
216 | // noSwaped = false;
217 | // }
218 | // }
219 | // if (noSwaped)
220 | // break;
221 | // }
222 | //}
223 | public static void InsertionSort(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer
224 | {
225 | if (length == 1)
226 | {
227 | return;
228 | }
229 |
230 | if (length == 2)
231 | {
232 | SwapIfGreater(items, ref comparer, 0, 1);
233 | return;
234 | }
235 |
236 | if (length == 3)
237 | {
238 | SwapIfGreater(items, ref comparer, 0, 1);
239 | SwapIfGreater(items, ref comparer, 0, 2);
240 | SwapIfGreater(items, ref comparer, 1, 2);
241 | return;
242 | }
243 |
244 | InsertionSort_Unchecked(items, length, ref comparer);
245 | }
246 | //public static void OptimizedBubbleSort(T* items, int length, ref TComparer comparer) where TComparer : IComparerX
247 | //{
248 | // if (length == 1)
249 | // {
250 | // return;
251 | // }
252 | //
253 | // if (length == 2)
254 | // {
255 | // SwapIfGreater(items, ref comparer, 0, 1);
256 | // return;
257 | // }
258 | //
259 | // if (length == 3)
260 | // {
261 | // SwapIfGreater(items, ref comparer, 0, 1);
262 | // SwapIfGreater(items, ref comparer, 0, 2);
263 | // SwapIfGreater(items, ref comparer, 1, 2);
264 | // return;
265 | // }
266 | //
267 | // OptimizedBubbleSort_Unchecked(items, length, ref comparer);
268 | //}
269 | }
270 | }
271 |
272 |
273 |
--------------------------------------------------------------------------------
/src/Internal/ArraySortHalperX.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a591de1858028504d819333121bfddd6
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal/ArrayUtility.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 19c100fbdef4f7e4dad9b545c11b9317
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal/BitsUtility.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 06a40460050b1ef4fa037b3a3cac9a8b
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal/EcsTypeCodeManager.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.Linq;
8 | using System.Runtime.CompilerServices;
9 | #if ENABLE_IL2CPP
10 | using Unity.IL2CPP.CompilerServices;
11 | #endif
12 |
13 | namespace DCFApixels.DragonECS.Core.Internal
14 | {
15 | //TODO разработать возможность ручного устанавливания ID типам.
16 | //это может быть полезно как детерминированность для сети
17 | #if ENABLE_IL2CPP
18 | [Il2CppSetOption(Option.NullChecks, false)]
19 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
20 | #endif
21 | internal static class EcsTypeCodeManager
22 | {
23 | private static readonly Dictionary _codes = new Dictionary();
24 | private static int _increment = 1;
25 | private static readonly object _lock = new object();
26 | public static int Count
27 | {
28 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
29 | get { return _codes.Count; }
30 | }
31 | public static EcsTypeCode Get(Type type)
32 | {
33 | lock (_lock)
34 | {
35 | if (!_codes.TryGetValue(type, out EcsTypeCode code))
36 | {
37 | code = (EcsTypeCode)_increment++;
38 | _codes.Add(type, code);
39 | }
40 | return code;
41 | }
42 | }
43 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
44 | public static EcsTypeCode Get() { return EcsTypeCodeCache.code; }
45 | public static bool Has(Type type) { return _codes.ContainsKey(type); }
46 | public static EcsTypeCodeKey FindTypeOfCode(EcsTypeCode typeCode)
47 | {
48 | foreach (var item in _codes)
49 | {
50 | if (item.Value == typeCode)
51 | {
52 | return item.Key;
53 | }
54 | }
55 | return null;
56 | }
57 | public static IEnumerable GetDeclaredTypes() { return _codes.Select(o => new TypeCodeInfo(o.Key, o.Value)); }
58 | }
59 | #if ENABLE_IL2CPP
60 | [Il2CppSetOption(Option.NullChecks, false)]
61 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
62 | #endif
63 | internal static class EcsTypeCodeCache
64 | {
65 | public static readonly EcsTypeCode code = EcsTypeCodeManager.Get(typeof(T));
66 | }
67 | #if ENABLE_IL2CPP
68 | [Il2CppSetOption(Option.NullChecks, false)]
69 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
70 | #endif
71 | internal struct TypeCodeInfo
72 | {
73 | public EcsTypeCodeKey type;
74 | public EcsTypeCode code;
75 | public TypeCodeInfo(EcsTypeCodeKey type, EcsTypeCode code)
76 | {
77 | this.type = type;
78 | this.code = code;
79 | }
80 | public override string ToString()
81 | {
82 | return this.AutoToString(false);
83 | }
84 | }
85 | #if ENABLE_IL2CPP
86 | [Il2CppSetOption(Option.NullChecks, false)]
87 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
88 | #endif
89 | [DebuggerDisplay("{" + nameof(ToString) + "()}")]
90 | internal readonly struct EcsTypeCodeKey : IEquatable
91 | {
92 | public readonly Type Type;
93 | public readonly string NameKey;
94 | public EcsTypeCodeKey(Type type, string nameKey)
95 | {
96 | Type = type;
97 | NameKey = nameKey;
98 | }
99 | public bool Equals(EcsTypeCodeKey other)
100 | {
101 | return Type == other.Type && NameKey == other.NameKey;
102 | }
103 | public override bool Equals(object obj)
104 | {
105 | return obj is EcsTypeCodeKey other && Equals(other);
106 | }
107 | public override int GetHashCode()
108 | {
109 | return HashCode.Combine(Type, NameKey);
110 | }
111 | public override string ToString()
112 | {
113 | if (string.IsNullOrEmpty(NameKey))
114 | {
115 | return Type.ToString();
116 | }
117 | return $"{Type} {NameKey}";
118 | }
119 | public static implicit operator EcsTypeCodeKey(Type type) { return new EcsTypeCodeKey(type, string.Empty); }
120 | }
121 | }
--------------------------------------------------------------------------------
/src/Internal/EcsTypeCodeManager.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: be4c15a212b2a6941bdbe78f18b038b3
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal/IdDispenser.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 54c009cfa7ae0fd49938525468703c8b
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal/ReflectionUtility.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Reflection;
6 | using System.Runtime.CompilerServices;
7 |
8 | namespace DCFApixels.DragonECS.Core.Internal
9 | {
10 | internal static class ReflectionUtility
11 | {
12 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
13 | public static bool TryGetAttribute(this MemberInfo self, out T attribute) where T : Attribute
14 | {
15 | attribute = self.GetCustomAttribute();
16 | return attribute != null;
17 | }
18 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
19 | public static bool TryGetAttribute(this MemberInfo self, bool inherit, out T attribute) where T : Attribute
20 | {
21 | attribute = self.GetCustomAttribute(inherit);
22 | return attribute != null;
23 | }
24 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
25 | public static bool HasAttribute(this MemberInfo self) where T : Attribute
26 | {
27 | return self.GetCustomAttribute() != null;
28 | }
29 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
30 | public static bool HasAttribute(this MemberInfo self, bool inherit) where T : Attribute
31 | {
32 | return self.GetCustomAttribute(inherit) != null;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Internal/ReflectionUtility.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bfba14901791dae45bab76154086b299
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal/SparseArray.cs:
--------------------------------------------------------------------------------
1 | //SparseArray. Analogous to Dictionary, but faster.
2 | //Benchmark result of indexer.get speed test with 300 elements:
3 | //[Dictinary: 5.786us] [SparseArray: 2.047us].
4 | #if DISABLE_DEBUG
5 | #undef DEBUG
6 | #endif
7 | using System;
8 | using System.Diagnostics.Contracts;
9 | using System.Runtime.CompilerServices;
10 | using System.Runtime.InteropServices;
11 |
12 | namespace DCFApixels.DragonECS.Core.Internal
13 | {
14 | #if ENABLE_IL2CPP
15 | using Unity.IL2CPP.CompilerServices;
16 | [Il2CppSetOption(Option.NullChecks, false)]
17 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
18 | #endif
19 | public class SparseArray
20 | {
21 | public const int MIN_CAPACITY_BITS_OFFSET = 4;
22 | public const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET;
23 | private const int EMPTY = -1;
24 |
25 | private int[] _buckets = Array.Empty();
26 | private Entry[] _entries = Array.Empty();
27 |
28 | private int _count;
29 |
30 | private int _freeList;
31 | private int _freeCount;
32 |
33 | private int _modBitMask;
34 |
35 | #region Properties
36 | public TValue this[int keyX, int keyY]
37 | {
38 | get { return _entries[FindEntry((keyX << 16) | keyY)].value; }
39 | set { Insert(keyX + (keyY << 16), value); }
40 | }
41 | public TValue this[int key]
42 | {
43 | get { return _entries[FindEntry(key)].value; }
44 | set { Insert(key, value); }
45 | }
46 | public int Count { get { return _count; } }
47 | #endregion
48 |
49 | #region Constructors
50 | public SparseArray(int minCapacity = MIN_CAPACITY)
51 | {
52 | minCapacity = NormalizeCapacity(minCapacity);
53 | _buckets = new int[minCapacity];
54 | for (int i = 0; i < minCapacity; i++)
55 | _buckets[i] = EMPTY;
56 | _entries = new Entry[minCapacity];
57 | _modBitMask = (minCapacity - 1) & 0x7FFFFFFF;
58 | }
59 | #endregion
60 |
61 | #region Add/Contains/Remove
62 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
63 | public void Add(int keyX, int keyY, TValue value) { Add((keyX << 16) | keyY, value); }
64 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
65 | public void Add(int key, TValue value)
66 | {
67 | #if DEBUG
68 | if (Contains(key)) { throw new ArgumentException("Contains(hashKey) is true"); }
69 | #endif
70 | Insert(key, value);
71 | }
72 |
73 | public bool Contains(int keyX, int keyY) { return FindEntry((keyX << 16) | keyY) >= 0; }
74 | public bool Contains(int key) { return FindEntry(key) >= 0; }
75 |
76 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
77 | public bool Remove(int keyX, int keyY) { return Remove((keyX << 16) | keyY); }
78 | public bool Remove(int key)
79 | {
80 | int bucket = key & _modBitMask;
81 | int last = -1;
82 | for (int i = _buckets[bucket]; i >= 0; last = i, i = _entries[i].next)
83 | {
84 | if (_entries[i].hashKey == key)
85 | {
86 | if (last < 0)
87 | {
88 | _buckets[bucket] = _entries[i].next;
89 | }
90 | else
91 | {
92 | _entries[last].next = _entries[i].next;
93 | }
94 | _entries[i].next = _freeList;
95 | _entries[i].hashKey = -1;
96 | _entries[i].value = default;
97 | _freeList = i;
98 | _freeCount++;
99 | return true;
100 | }
101 | }
102 | return false;
103 | }
104 | #endregion
105 |
106 | #region Find/Insert
107 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
108 | private int FindEntry(int key)
109 | {
110 | for (int i = _buckets[key & _modBitMask]; i >= 0; i = _entries[i].next)
111 | if (_entries[i].hashKey == key) return i;
112 | return -1;
113 | }
114 | private void Insert(int key, TValue value)
115 | {
116 | int targetBucket = key & _modBitMask;
117 |
118 | for (int i = _buckets[targetBucket]; i >= 0; i = _entries[i].next)
119 | {
120 | if (_entries[i].hashKey == key)
121 | {
122 | _entries[i].value = value;
123 | return;
124 | }
125 | }
126 |
127 | int index;
128 | if (_freeCount > 0)
129 | {
130 | index = _freeList;
131 | _freeList = _entries[index].next;
132 | _freeCount--;
133 | }
134 | else
135 | {
136 | if (_count == _entries.Length)
137 | {
138 | Resize();
139 | targetBucket = key & _modBitMask;
140 | }
141 | index = _count++;
142 | }
143 |
144 | _entries[index].next = _buckets[targetBucket];
145 | _entries[index].hashKey = key;
146 | _entries[index].value = value;
147 | _buckets[targetBucket] = index;
148 | }
149 | #endregion
150 |
151 | #region TryGetValue
152 | public bool TryGetValue(int keyX, int keyY, out TValue value)
153 | {
154 | int index = FindEntry((keyX << 16) | keyY);
155 | if (index < 0)
156 | {
157 | value = default;
158 | return false;
159 | }
160 | value = _entries[index].value;
161 | return true;
162 | }
163 | public bool TryGetValue(int key, out TValue value)
164 | {
165 | int index = FindEntry(key);
166 | if (index < 0)
167 | {
168 | value = default;
169 | return false;
170 | }
171 | value = _entries[index].value;
172 | return true;
173 | }
174 | #endregion
175 |
176 | #region Clear
177 | public void Clear()
178 | {
179 | if (_count > 0)
180 | {
181 | for (int i = 0; i < _buckets.Length; i++)
182 | {
183 | _buckets[i] = -1;
184 | }
185 | Array.Clear(_entries, 0, _count);
186 | _count = 0;
187 | }
188 | }
189 | #endregion
190 |
191 | #region Resize
192 | private void Resize()
193 | {
194 | int newSize = _buckets.Length << 1;
195 | _modBitMask = (newSize - 1) & 0x7FFFFFFF;
196 |
197 | Contract.Assert(newSize >= _entries.Length);
198 | int[] newBuckets = new int[newSize];
199 | for (int i = 0; i < newBuckets.Length; i++)
200 | newBuckets[i] = EMPTY;
201 |
202 | Entry[] newEntries = new Entry[newSize];
203 | Array.Copy(_entries, 0, newEntries, 0, _count);
204 | for (int i = 0; i < _count; i++)
205 | {
206 | if (newEntries[i].hashKey >= 0)
207 | {
208 | int bucket = newEntries[i].hashKey % newSize;
209 | newEntries[i].next = newBuckets[bucket];
210 | newBuckets[bucket] = i;
211 | }
212 | }
213 | _buckets = newBuckets;
214 | _entries = newEntries;
215 | }
216 |
217 | private int NormalizeCapacity(int capacity)
218 | {
219 | int result = MIN_CAPACITY;
220 | while (result < capacity) result <<= 1;
221 | return result;
222 | }
223 | #endregion
224 |
225 | #region Utils
226 | [StructLayout(LayoutKind.Sequential, Pack = 4)]
227 | private struct Entry
228 | {
229 | public int next; // Index of next entry, -1 if last
230 | public int hashKey;
231 | public TValue value;
232 | }
233 | #endregion
234 | }
235 | }
--------------------------------------------------------------------------------
/src/Internal/SparseArray.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 25afb1113718f904c85dcbedd993d85e
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal/StructList.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.Linq;
8 | using System.Runtime.CompilerServices;
9 |
10 | namespace DCFApixels.DragonECS.Core.Internal
11 | {
12 | [DebuggerDisplay("Count: {Count}")]
13 | internal struct StructList
14 | {
15 | internal T[] _items;
16 | internal int _count;
17 | public int Count
18 | {
19 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
20 | get { return _count; }
21 | }
22 | public int Capacity
23 | {
24 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
25 | get { return _items.Length; }
26 | set
27 | {
28 | if (value <= _items.Length) { return; }
29 | value = ArrayUtility.NextPow2(value);
30 | Array.Resize(ref _items, value);
31 | }
32 | }
33 | public T this[int index]
34 | {
35 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
36 | get
37 | {
38 | #if DEBUG
39 | if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
40 | #endif
41 | return _items[index];
42 | }
43 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
44 | set
45 | {
46 | #if DEBUG
47 | if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
48 | #endif
49 | _items[index] = value;
50 | }
51 | }
52 |
53 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
54 | public StructList(int capacity)
55 | {
56 | _items = new T[ArrayUtility.NextPow2(capacity)];
57 | _count = 0;
58 | }
59 |
60 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
61 | public void Add(T item)
62 | {
63 | if (_count >= _items.Length)
64 | {
65 | Array.Resize(ref _items, _items.Length << 1);
66 | }
67 | _items[_count++] = item;
68 | }
69 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
70 | public int IndexOf(T item)
71 | {
72 | return Array.IndexOf(_items, item, 0, _count);
73 | }
74 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
75 | public void SwapAt(int idnex1, int idnex2)
76 | {
77 | T tmp = _items[idnex1];
78 | _items[idnex1] = _items[idnex2];
79 | _items[idnex2] = tmp;
80 | }
81 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
82 | public void FastRemoveAt(int index)
83 | {
84 | #if DEBUG
85 | if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
86 | #endif
87 | _items[index] = _items[--_count];
88 | }
89 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
90 | public void RemoveAt(int index)
91 | {
92 | #if DEBUG
93 | if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
94 | #endif
95 | _items[index] = _items[--_count];
96 | _items[_count] = default;
97 | }
98 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
99 | public void RemoveAtWithOrder(int index)
100 | {
101 | #if DEBUG
102 | if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
103 | #endif
104 | for (int i = index; i < _count;)
105 | {
106 | _items[i++] = _items[i];
107 | }
108 | }
109 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
110 | public bool Remove(T item)
111 | {
112 | int index = IndexOf(item);
113 | if (index >= 0)
114 | {
115 | RemoveAt(index);
116 | return true;
117 | }
118 | return false;
119 | }
120 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
121 | public bool RemoveWithOrder(T item)
122 | {
123 | int index = IndexOf(item);
124 | if (index >= 0)
125 | {
126 | RemoveAtWithOrder(index);
127 | return true;
128 | }
129 | return false;
130 | }
131 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
132 | public void FastClear()
133 | {
134 | _count = 0;
135 | }
136 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
137 | public void Clear()
138 | {
139 | for (int i = 0; i < _count; i++)
140 | {
141 | _items[i] = default;
142 | }
143 | _count = 0;
144 | }
145 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
146 | public ReadOnlySpan.Enumerator GetEnumerator()
147 | {
148 | return new ReadOnlySpan(_items, 0, _count).GetEnumerator();
149 | }
150 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
151 | public ReadOnlySpan ToReadOnlySpan()
152 | {
153 | return new ReadOnlySpan(_items, 0, _count);
154 | }
155 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
156 | public IEnumerable ToEnumerable()
157 | {
158 | return _items.Take(_count);
159 | }
160 | }
161 | }
--------------------------------------------------------------------------------
/src/Internal/StructList.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 950c90aee052a0c4cbb997d38024e133
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Internal/UnsafeArray.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Collections;
6 | using System.Collections.Generic;
7 | using System.Diagnostics;
8 | using System.Runtime.CompilerServices;
9 | #if ENABLE_IL2CPP
10 | using Unity.IL2CPP.CompilerServices;
11 | #endif
12 |
13 | namespace DCFApixels.DragonECS.Core.Internal
14 | {
15 | #if ENABLE_IL2CPP
16 | [Il2CppSetOption(Option.NullChecks, false)]
17 | [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
18 | #endif
19 | [DebuggerTypeProxy(typeof(UnsafeArray<>.DebuggerProxy))]
20 | internal unsafe struct UnsafeArray : IDisposable, IEnumerable
21 | where T : unmanaged
22 | {
23 | internal T* ptr;
24 | internal int Length;
25 |
26 | public static UnsafeArray FromArray(T[] array)
27 | {
28 | UnsafeArray result = new UnsafeArray(array.Length);
29 | for (int i = 0; i < array.Length; i++)
30 | {
31 | result.ptr[i] = array[i];
32 | }
33 | return result;
34 | }
35 |
36 |
37 |
38 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
39 | public UnsafeArray(int length)
40 | {
41 | UnmanagedArrayUtility.New(out ptr, length);
42 | Length = length;
43 | }
44 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
45 | public UnsafeArray(int length, bool isInit)
46 | {
47 | UnmanagedArrayUtility.NewAndInit(out ptr, length);
48 | Length = length;
49 | }
50 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
51 | private UnsafeArray(T* ptr, int length)
52 | {
53 | this.ptr = ptr;
54 | Length = length;
55 | }
56 |
57 | public static UnsafeArray Manual(T* ptr, int length)
58 | {
59 | return new UnsafeArray(ptr, length);
60 | }
61 |
62 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
63 | public UnsafeArray Slice(int start)
64 | {
65 | if ((uint)start > (uint)Length)
66 | {
67 | Throw.ArgumentOutOfRange();
68 | }
69 | return new UnsafeArray(ptr + start, Length - start);
70 | }
71 |
72 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
73 | public UnsafeArray Slice(int start, int length)
74 | {
75 | if ((uint)start > (uint)Length || (uint)length > (uint)(Length - start))
76 | {
77 | Throw.ArgumentOutOfRange();
78 | }
79 | return new UnsafeArray(ptr + start, length);
80 | }
81 |
82 | public void CopyFromArray_Unchecked(T[] array)
83 | {
84 | for (int i = 0; i < array.Length; i++)
85 | {
86 | ptr[i] = array[i];
87 | }
88 | }
89 |
90 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
91 | public UnsafeArray Clone()
92 | {
93 | return new UnsafeArray(UnmanagedArrayUtility.Clone(ptr, Length), Length);
94 | }
95 |
96 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
97 | public void Dispose()
98 | {
99 | UnmanagedArrayUtility.Free(ref ptr, ref Length);
100 | }
101 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
102 | public void ReadonlyDispose()
103 | {
104 | UnmanagedArrayUtility.Free(ptr);
105 | }
106 | public override string ToString()
107 | {
108 | T* ptr = this.ptr;
109 | var elements = new T[Length];
110 | for (int i = 0; i < Length; i++)
111 | {
112 | elements[i] = ptr[i];
113 | }
114 | return CollectionUtility.AutoToString(elements, "ua");
115 | }
116 |
117 | IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
118 | IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
119 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
120 | public Enumerator GetEnumerator() { return new Enumerator(ptr, Length); }
121 | public struct Enumerator : IEnumerator
122 | {
123 | private readonly T* _ptr;
124 | private readonly int _length;
125 | private int _index;
126 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
127 | public Enumerator(T* ptr, int length)
128 | {
129 | _ptr = ptr;
130 | _length = length;
131 | _index = -1;
132 | }
133 | public T Current
134 | {
135 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
136 | get { return _ptr[_index]; }
137 | }
138 | object IEnumerator.Current { get { return Current; } }
139 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
140 | public bool MoveNext() { return ++_index < _length; }
141 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
142 | void IDisposable.Dispose() { }
143 | void IEnumerator.Reset() { throw new NotSupportedException(); }
144 | }
145 |
146 | internal class DebuggerProxy
147 | {
148 | public T[] elements;
149 | public int length;
150 | public DebuggerProxy(UnsafeArray instance)
151 | {
152 | length = instance.Length;
153 | elements = new T[length];
154 | for (int i = 0; i < length; i++)
155 | {
156 | elements[i] = instance.ptr[i];
157 | }
158 | }
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/Internal/UnsafeArray.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5d8f3c5034bb040478b60d7421a38ef8
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Pools.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0115873d8e1ddc14091888b2b4d3f5f9
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Pools/EcsPool.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DCFApixels/DragonECS/bd192db22a0e87d7f8a9f6240a639c7d46de4131/src/Pools/EcsPool.cs
--------------------------------------------------------------------------------
/src/Pools/EcsPool.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ea5495513fa22a54987d75f5cc4fea42
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Pools/EcsPoolBase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f401b863396d3dd40a3a8755e828c958
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Pools/EcsTagPool.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1886a418a78fb3944a4df0f5e276959c
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Utils.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 16b79c30e1b668e47bd35de518796871
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/Utils/AllowedInWorldsAttribute.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using DCFApixels.DragonECS.Core.Internal;
5 | using System;
6 |
7 | namespace DCFApixels.DragonECS
8 | {
9 | [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
10 | public sealed class AllowedInWorldsAttribute : Attribute
11 | {
12 | public object[] AllowedWorlds;
13 | public AllowedInWorldsAttribute(params object[] allowedWorlds)
14 | {
15 | AllowedWorlds = allowedWorlds;
16 | }
17 |
18 | public static void CheckAllows(EcsWorld world, Type componentType)
19 | {
20 | Type worldType = world.GetType();
21 | if (componentType.TryGetAttribute(out AllowedInWorldsAttribute attribute))
22 | {
23 | foreach (var worldTag in attribute.AllowedWorlds)
24 | {
25 | bool result = false;
26 | if (worldTag is Type worldTypeTag)
27 | {
28 | result = worldTypeTag == worldType;
29 | }
30 | else
31 | {
32 | string worldStringTag = worldTag.ToString();
33 | result = world.Name == worldStringTag;
34 | }
35 | if (result)
36 | {
37 | return;
38 | }
39 | }
40 | throw new InvalidOperationException($"Using component {componentType.ToMeta().TypeName} is not allowed in the {worldType.ToMeta().TypeName} world.");
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Utils/AllowedInWorldsAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a39694cb8b5876346968ef45a8272000
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Utils/DependencyGraph.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5b6e0bcd95bfbfa4394109d33605f667
--------------------------------------------------------------------------------
/src/Utils/EcsPipelineTemplate.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Runtime.Serialization;
6 |
7 | namespace DCFApixels.DragonECS
8 | {
9 | using static EcsConsts;
10 |
11 | [Serializable]
12 | [DataContract]
13 | [MetaTags(MetaTags.HIDDEN)]
14 | [MetaDescription(AUTHOR, "...")]
15 | [MetaGroup(PACK_GROUP, OTHER_GROUP)]
16 | [MetaID("DragonECS_128D547C9201EEAC49B05F89E4A253DF")]
17 | [MetaColor(MetaColor.DragonRose)]
18 | public class EcsPipelineTemplate : IEcsModule
19 | {
20 | [DataMember] public string[] layers;
21 | [DataMember] public Record[] records;
22 | void IEcsModule.Import(EcsPipeline.Builder b)
23 | {
24 | b.Layers.MergeWith(layers);
25 | foreach (var s in records)
26 | {
27 | if (s.target == null) { continue; }
28 |
29 | b.Add(s.target, s.parameters);
30 | }
31 | }
32 | [Serializable]
33 | [DataContract]
34 | public struct Record
35 | {
36 | [DataMember] public object target;
37 | [DataMember] public AddParams parameters;
38 | public Record(object target, AddParams parameters)
39 | {
40 | this.target = target;
41 | this.parameters = parameters;
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Utils/EcsPipelineTemplate.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a4f0bb3a054f20f4d937499044d58c20
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Utils/EcsTypeCode.cs:
--------------------------------------------------------------------------------
1 | namespace DCFApixels.DragonECS
2 | {
3 | public enum EcsTypeCode : int
4 | {
5 | NULL = 0,
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/Utils/EcsTypeCode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b21f5b69a0fc3b447b93b34ef4377dbf
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Utils/Exceptions.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace DCFApixels.DragonECS
8 | {
9 | [Serializable]
10 | public class DeepDebugException : Exception
11 | {
12 | public DeepDebugException() { }
13 | public DeepDebugException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
14 | public DeepDebugException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
15 | }
16 | [Serializable]
17 | public class NullInstanceException : Exception
18 | {
19 | public NullInstanceException() { }
20 | public NullInstanceException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
21 | public NullInstanceException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
22 | }
23 | [Serializable]
24 | public class ImplementationException : Exception
25 | {
26 | public ImplementationException() { }
27 | public ImplementationException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
28 | public ImplementationException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
29 | }
30 | [Serializable]
31 | public class InjectionException : Exception
32 | {
33 | public InjectionException() { }
34 | public InjectionException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
35 | public InjectionException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
36 | }
37 | }
38 |
39 | namespace DCFApixels.DragonECS.Core.Internal
40 | {
41 | internal static class Throw
42 | {
43 | [MethodImpl(MethodImplOptions.NoInlining)]
44 | internal static void ConstraintIsAlreadyContainedInMask(EcsTypeCode typeCode)
45 | {
46 | string typeName = EcsDebugUtility.GetGenericTypeName(EcsTypeCodeManager.FindTypeOfCode(typeCode).Type);
47 | throw new ArgumentException($"The {typeName} constraint is already contained in the mask.");
48 | }
49 | [MethodImpl(MethodImplOptions.NoInlining)]
50 | internal static void Group_AlreadyContains(int entityID)
51 | {
52 | throw new ArgumentException($"This group already contains entity {entityID}.");
53 | }
54 | [MethodImpl(MethodImplOptions.NoInlining)]
55 | internal static void Group_DoesNotContain(int entityID)
56 | {
57 | throw new ArgumentException($"This group does not contain entity {entityID}.");
58 | }
59 | [MethodImpl(MethodImplOptions.NoInlining)]
60 | internal static void Group_ArgumentDifferentWorldsException()
61 | {
62 | throw new ArgumentException("The groups belong to different worlds.");
63 | }
64 |
65 | [MethodImpl(MethodImplOptions.NoInlining)]
66 | internal static void Pipeline_MethodCalledAfterInitialisation(string methodName)
67 | {
68 | throw new InvalidOperationException($"It is forbidden to call {methodName}, after initialization {nameof(EcsPipeline)}.");
69 | }
70 | [MethodImpl(MethodImplOptions.NoInlining)]
71 | internal static void Pipeline_MethodCalledBeforeInitialisation(string methodName)
72 | {
73 | throw new InvalidOperationException($"It is forbidden to call {methodName}, before initialization {nameof(EcsPipeline)}.");
74 | }
75 | [MethodImpl(MethodImplOptions.NoInlining)]
76 | internal static void Pipeline_MethodCalledAfterDestruction(string methodName)
77 | {
78 | throw new InvalidOperationException($"It is forbidden to call {methodName}, after destroying {nameof(EcsPipeline)}.");
79 | }
80 |
81 | [MethodImpl(MethodImplOptions.NoInlining)]
82 | internal static void World_InvalidIncrementComponentsBalance()
83 | {
84 | throw new InvalidOperationException("Invalid increment components balance.");
85 | }
86 | [MethodImpl(MethodImplOptions.NoInlining)]
87 | internal static void World_GroupDoesNotBelongWorld()
88 | {
89 | throw new InvalidOperationException("The Group does not belong in this world.");
90 | }
91 | [MethodImpl(MethodImplOptions.NoInlining)]
92 | public static void World_MaskDoesntBelongWorld()
93 | {
94 | throw new InvalidOperationException($"The mask doesn't belong in this world");
95 | }
96 | [MethodImpl(MethodImplOptions.NoInlining)]
97 | public static void World_EntityIsNotContained(int entityID)
98 | {
99 | throw new ArgumentException($"An entity with identifier {entityID} is not contained in this world");
100 | }
101 | [MethodImpl(MethodImplOptions.NoInlining)]
102 | public static void World_EntityIsAlreadyСontained(int entityID)
103 | {
104 | throw new ArgumentException($"An entity with identifier {entityID} is already contained in this world");
105 | }
106 | [MethodImpl(MethodImplOptions.NoInlining)]
107 | public static void World_PoolAlreadyCreated()
108 | {
109 | throw new ArgumentException("The pool has already been created.");
110 | }
111 | public static void World_WorldCantBeDestroyed()
112 | {
113 | throw new InvalidOperationException("This world can't be destroyed");
114 | }
115 | [MethodImpl(MethodImplOptions.NoInlining)]
116 | public static void World_MethodCalledAfterEntityCreation(string methodName)
117 | {
118 | throw new InvalidOperationException($"The method {methodName} can only be executed before creating entities in the world.");
119 | }
120 |
121 | [MethodImpl(MethodImplOptions.NoInlining)]
122 | internal static void Ent_ThrowIsNotAlive(EcsWorld world, int entityID)
123 | {
124 | Ent_ThrowIsNotAlive((world, entityID));
125 | }
126 | [MethodImpl(MethodImplOptions.NoInlining)]
127 | internal static void Ent_ThrowIsNotAlive(entlong entity)
128 | {
129 | if (entity.IsNull)
130 | {
131 | throw new InvalidOperationException($"The {entity} is null.");
132 | }
133 | else
134 | {
135 | throw new InvalidOperationException($"The {entity} is not alive.");
136 | }
137 | }
138 |
139 | [MethodImpl(MethodImplOptions.NoInlining)]
140 | internal static void Quiery_ArgumentDifferentWorldsException()
141 | {
142 | throw new ArgumentException("The groups belong to different worlds.");
143 | }
144 |
145 |
146 | [MethodImpl(MethodImplOptions.NoInlining)]
147 | internal static void ArgumentNull()
148 | {
149 | throw new ArgumentNullException();
150 | }
151 | [MethodImpl(MethodImplOptions.NoInlining)]
152 | internal static void ArgumentNull(string paramName)
153 | {
154 | throw new ArgumentNullException(paramName);
155 | }
156 | [MethodImpl(MethodImplOptions.NoInlining)]
157 | internal static void ArgumentOutOfRange()
158 | {
159 | throw new ArgumentOutOfRangeException($"index is less than 0 or is equal to or greater than Count.");
160 | }
161 | [MethodImpl(MethodImplOptions.NoInlining)]
162 | internal static void UndefinedException()
163 | {
164 | throw new Exception();
165 | }
166 | [MethodImpl(MethodImplOptions.NoInlining)]
167 | internal static void DeepDebugException()
168 | {
169 | throw new DeepDebugException();
170 | }
171 | internal static void OpeningClosingMethodsBalanceError()
172 | {
173 | throw new InvalidOperationException("Error of opening - closing methods. Closing method was called more often than opening method.");
174 | }
175 | internal static void CantReuseBuilder()
176 | {
177 | throw new InvalidOperationException("Builder has already worked out, use the new builder to build again.");
178 | }
179 | [MethodImpl(MethodImplOptions.NoInlining)]
180 | internal static void Exception(string message)
181 | {
182 | throw new Exception(message);
183 | }
184 | [MethodImpl(MethodImplOptions.NoInlining)]
185 | internal static void ArgumentException(string message)
186 | {
187 | throw new ArgumentException(message);
188 | }
189 |
190 | [MethodImpl(MethodImplOptions.NoInlining)]
191 | internal static void Aspect_CanOnlyBeUsedDuringInitialization(string methodName)
192 | {
193 | throw new InvalidOperationException($"{methodName} can only be used during field initialization and in the constructor.");
194 | }
195 | }
196 | }
197 |
198 |
--------------------------------------------------------------------------------
/src/Utils/Exceptions.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3fb0971f3d6096a4d8f5ede25ec50354
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/Utils/IConfigContainer.cs:
--------------------------------------------------------------------------------
1 | #if DISABLE_DEBUG
2 | #undef DEBUG
3 | #endif
4 | using System;
5 | using System.Collections;
6 | using System.Collections.Generic;
7 |
8 | namespace DCFApixels.DragonECS
9 | {
10 | public interface IConfigContainer
11 | {
12 | int Count { get; }
13 | bool Has();
14 | T Get();
15 | bool TryGet(out T value);
16 | IEnumerable> GetAllConfigs();
17 | }
18 | public interface IConfigContainerWriter
19 | {
20 | int Count { get; }
21 | void Set(T value);
22 | void Set(Type type, object value);
23 | bool Has();
24 | T Get