├── .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(); 25 | bool TryGet(out T value); 26 | void Remove(); 27 | IEnumerable> GetAllConfigs(); 28 | IConfigContainer GetContainer(); 29 | } 30 | public sealed class ConfigContainer : IConfigContainer, IConfigContainerWriter, IEnumerable> 31 | { 32 | public static readonly ConfigContainer Empty = new ConfigContainer(); 33 | 34 | private Dictionary _storage = new Dictionary(); 35 | 36 | public ConfigContainer() { } 37 | public ConfigContainer(IEnumerable range) 38 | { 39 | foreach (var item in range) 40 | { 41 | _storage.Add(item.GetType(), item); 42 | } 43 | } 44 | public ConfigContainer(params object[] range) 45 | { 46 | foreach (var item in range) 47 | { 48 | _storage.Add(item.GetType(), item); 49 | } 50 | } 51 | 52 | public int Count 53 | { 54 | get { return _storage.Count; } 55 | } 56 | public T Get() 57 | { 58 | return (T)_storage[typeof(T)]; 59 | } 60 | public bool Has() 61 | { 62 | return _storage.ContainsKey(typeof(T)); 63 | } 64 | public void Remove() 65 | { 66 | _storage.Remove(typeof(T)); 67 | } 68 | public ConfigContainer Set(T value) 69 | { 70 | _storage[typeof(T)] = value; 71 | return this; 72 | } 73 | public ConfigContainer Set(Type type, object value) 74 | { 75 | _storage[type] = value; 76 | return this; 77 | } 78 | void IConfigContainerWriter.Set(Type type, object value) 79 | { 80 | Set(type, value); 81 | } 82 | void IConfigContainerWriter.Set(T value) 83 | { 84 | Set(value); 85 | } 86 | public bool TryGet(out T value) 87 | { 88 | bool result = _storage.TryGetValue(typeof(T), out object rawValue); 89 | value = rawValue == null ? default : (T)rawValue; 90 | return result; 91 | } 92 | public IConfigContainer GetContainer() { return this; } 93 | public IEnumerable> GetAllConfigs() 94 | { 95 | return _storage; 96 | } 97 | public IEnumerator> GetEnumerator() 98 | { 99 | return _storage.GetEnumerator(); 100 | } 101 | IEnumerator IEnumerable.GetEnumerator() 102 | { 103 | return GetAllConfigs().GetEnumerator(); 104 | } 105 | } 106 | public static class ConfigContainerExtensions 107 | { 108 | public static T GetOrDefault(this IConfigContainer self, T defaultValue) 109 | { 110 | if (self.TryGet(out T value)) 111 | { 112 | return value; 113 | } 114 | return defaultValue; 115 | } 116 | public static EcsWorldConfig GetWorldConfigOrDefault(this IConfigContainer self) 117 | { 118 | return self.GetOrDefault(EcsWorldConfig.Default); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/Utils/IConfigContainer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8df433b2b6b0f2b4e83130a3d1c0cdd3 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/ITemplateNode.cs: -------------------------------------------------------------------------------- 1 | #if DISABLE_DEBUG 2 | #undef DEBUG 3 | #endif 4 | 5 | namespace DCFApixels.DragonECS 6 | { 7 | public interface ITemplateNode 8 | { 9 | void Apply(short worldID, int entityID); 10 | } 11 | public static class ITemplateNodeExtensions 12 | { 13 | public static int ApplyAndReturn(this ITemplateNode self, short worldID, int entityID) 14 | { 15 | self.Apply(worldID, entityID); 16 | return entityID; 17 | } 18 | public static entlong ApplyAndReturnLong(this ITemplateNode self, short worldID, int entityID) 19 | { 20 | self.Apply(worldID, entityID); 21 | return (EcsWorld.GetWorld(worldID), entityID); 22 | } 23 | public static void Apply(this ITemplateNode self, EcsWorld world, int entityID) 24 | { 25 | self.Apply(world.ID, entityID); 26 | } 27 | public static int ApplyAndReturn(this ITemplateNode self, EcsWorld world, int entityID) 28 | { 29 | self.Apply(world.ID, entityID); 30 | return entityID; 31 | } 32 | public static entlong ApplyAndReturnLong(this ITemplateNode self, EcsWorld world, int entityID) 33 | { 34 | self.Apply(world.ID, entityID); 35 | return (world, entityID); 36 | } 37 | public static int NewEntity(this EcsWorld world, ITemplateNode template) 38 | { 39 | int e = world.NewEntity(); 40 | template.Apply(world.ID, e); 41 | return e; 42 | } 43 | public static entlong NewEntityLong(this EcsWorld world, ITemplateNode template) 44 | { 45 | entlong e = world.NewEntityLong(); 46 | template.Apply(world.ID, e.ID); 47 | return e; 48 | } 49 | 50 | public static int NewEntity(this EcsWorld world, int entityID, ITemplateNode template) 51 | { 52 | int e = world.NewEntity(entityID); 53 | template.Apply(world.ID, e); 54 | return e; 55 | } 56 | public static entlong NewEntityLong(this EcsWorld world, int entityID, ITemplateNode template) 57 | { 58 | entlong e = world.NewEntityLong(entityID); 59 | template.Apply(world.ID, e.ID); 60 | return e; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/Utils/ITemplateNode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e78883b886f4c2b4f929a100b7b6684f 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/LayersMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace DCFApixels.DragonECS.Core 6 | { 7 | using VertexID = DependencyGraphVertextID; 8 | public class LayersMap : IDependencyGraph 9 | { 10 | #region IDependencyGraph 11 | VertexID IDependencyGraph.AddVertex(string vertex, bool isLocked) { return _graph.AddVertex(vertex, isLocked); } 12 | bool IDependencyGraph.ContainsVertex(string vertex) { return _graph.ContainsVertex(vertex); } 13 | VertexID IDependencyGraph.GetVertexID(string vertex) { return _graph.GetVertexID(vertex); } 14 | string IDependencyGraph.GetVertexFromID(VertexID vertexID) { return _graph.GetVertexFromID(vertexID); } 15 | bool IDependencyGraph.RemoveVertex(string vertex) { return _graph.RemoveVertex(vertex); } 16 | void IDependencyGraph.AddDependency(VertexID fromID, VertexID toID, bool moveToRight) { _graph.AddDependency(fromID, toID, moveToRight); } 17 | string[] IDependencyGraph.Sort() { return _graph.Sort(); } 18 | #endregion 19 | 20 | private readonly IDependencyGraph _graph; 21 | private readonly EcsPipeline.Builder _pipelineBuilder; 22 | private readonly string _preBeginLayer; 23 | 24 | #region Properties 25 | public EcsPipeline.Builder Back 26 | { 27 | get { return _pipelineBuilder; } 28 | } 29 | public int Count 30 | { 31 | get { return _graph.Count; } 32 | } 33 | public ReadonlyDependenciesCollection Dependencies 34 | { 35 | get { return _graph.Dependencies; } 36 | } 37 | #endregion 38 | 39 | #region Constructors 40 | public LayersMap(IDependencyGraph graph, EcsPipeline.Builder pipelineBuilder) 41 | { 42 | _graph = graph; 43 | _pipelineBuilder = pipelineBuilder; 44 | } 45 | public LayersMap(IDependencyGraph graph, EcsPipeline.Builder pipelineBuilder, string preBeginlayer, string beginlayer, string basicLayer, string endLayer, string postEndLayer) 46 | { 47 | _graph = graph; 48 | _pipelineBuilder = pipelineBuilder; 49 | 50 | graph.AddVertex(preBeginlayer, true); 51 | graph.AddVertex(beginlayer, true); 52 | graph.AddVertex(basicLayer, true); 53 | graph.AddVertex(endLayer, true); 54 | graph.AddVertex(postEndLayer, true); 55 | 56 | Move(preBeginlayer); 57 | //.Before(beginlayer); 58 | Move(beginlayer) 59 | //.Before(basicLayer) 60 | .After(preBeginlayer); 61 | Move(basicLayer) 62 | //.Before(endLayer) 63 | .After(beginlayer); 64 | Move(endLayer) 65 | //.Before(postEndLayer) 66 | .After(basicLayer); 67 | Move(postEndLayer) 68 | .After(endLayer); 69 | } 70 | #endregion 71 | 72 | #region Add 73 | public MoveHandler Add(string layer) 74 | { 75 | VertexID id = _graph.AddVertex(layer, false); 76 | return new MoveHandler(_graph, _pipelineBuilder, id); 77 | } 78 | public MoveHandler Add(params string[] layers) 79 | { 80 | return Add(layersRange: layers); 81 | } 82 | public MoveHandler Add(IEnumerable layersRange) 83 | { 84 | foreach (var layer in layersRange) 85 | { 86 | Add(layer); 87 | } 88 | return new MoveHandler(_graph, _pipelineBuilder, layersRange); 89 | } 90 | #endregion 91 | 92 | #region Move 93 | public MoveHandler Move(string layer) 94 | { 95 | VertexID id = _graph.GetVertexID(layer); 96 | return new MoveHandler(_graph, _pipelineBuilder, id); 97 | } 98 | public MoveHandler Move(params string[] layers) 99 | { 100 | return new MoveHandler(_graph, _pipelineBuilder, layers); 101 | } 102 | public MoveHandler Move(IEnumerable layersRange) 103 | { 104 | return new MoveHandler(_graph, _pipelineBuilder, layersRange); 105 | } 106 | #endregion 107 | 108 | #region MoveHandler 109 | public struct MoveHandler 110 | { 111 | private readonly IDependencyGraph _graph; 112 | private readonly EcsPipeline.Builder _pipelineBuilder; 113 | private readonly VertexID _layerID; 114 | private readonly IEnumerable _layersRange; 115 | 116 | #region Properties 117 | public EcsPipeline.Builder Back 118 | { 119 | get { return _pipelineBuilder; } 120 | } 121 | #endregion 122 | 123 | #region Constructors 124 | public MoveHandler(IDependencyGraph graph, EcsPipeline.Builder pipelineBuilder, VertexID id) 125 | { 126 | _graph = graph; 127 | _pipelineBuilder = pipelineBuilder; 128 | _layerID = id; 129 | _layersRange = null; 130 | } 131 | public MoveHandler(IDependencyGraph graph, EcsPipeline.Builder pipelineBuilder, IEnumerable layersRange) 132 | { 133 | _graph = graph; 134 | _pipelineBuilder = pipelineBuilder; 135 | _layerID = VertexID.NULL; 136 | _layersRange = layersRange; 137 | } 138 | #endregion 139 | 140 | #region Before 141 | public MoveHandler Before(params string[] targets) 142 | { 143 | return Before(targetsRange: targets); 144 | } 145 | public MoveHandler Before(IEnumerable targetsRange) 146 | { 147 | foreach (var target in targetsRange) 148 | { 149 | Before(target); 150 | } 151 | return this; 152 | } 153 | public MoveHandler Before(string targetLayer) 154 | { 155 | if (_layerID != VertexID.NULL) 156 | { 157 | _graph.AddDependency(_layerID, _graph.GetVertexID(targetLayer), true); 158 | } 159 | if (_layersRange != null) 160 | { 161 | foreach (var layer in _layersRange) 162 | { 163 | _graph.AddDependency(_graph.GetVertexID(layer), _graph.GetVertexID(targetLayer), true); 164 | } 165 | } 166 | return this; 167 | } 168 | #endregion 169 | 170 | #region After 171 | public MoveHandler After(params string[] targets) 172 | { 173 | return After(targetsRange: targets); 174 | } 175 | public MoveHandler After(IEnumerable targetsRange) 176 | { 177 | foreach (var target in targetsRange) 178 | { 179 | After(target); 180 | } 181 | return this; 182 | } 183 | public MoveHandler After(string targetLayer) 184 | { 185 | if (_layerID != VertexID.NULL) 186 | { 187 | _graph.AddDependency(_graph.GetVertexID(targetLayer), _layerID, false); 188 | } 189 | if (_layersRange != null) 190 | { 191 | foreach (var layer in _layersRange) 192 | { 193 | _graph.AddDependency(_graph.GetVertexID(targetLayer), _graph.GetVertexID(layer), false); 194 | } 195 | } 196 | return this; 197 | } 198 | #endregion 199 | } 200 | #endregion 201 | 202 | #region MergeWith 203 | public void MergeWith(IDependencyGraph other) 204 | { 205 | _graph.MergeWith(other); 206 | } 207 | //[Obsolete("Use MergeWith(LayersMap)")] 208 | public void MergeWith(IReadOnlyList other) 209 | { 210 | var enumerator = other.GetEnumerator(); 211 | string prev = null; 212 | if (_preBeginLayer != null) 213 | { 214 | while (enumerator.MoveNext()) 215 | { 216 | var layer = enumerator.Current; 217 | if (layer == _preBeginLayer) { break; } 218 | 219 | Add(layer); 220 | if (prev != null) 221 | { 222 | Move(prev).Before(layer); 223 | } 224 | prev = layer; 225 | } 226 | } 227 | while (enumerator.MoveNext()) 228 | { 229 | var layer = enumerator.Current; 230 | Add(layer); 231 | if (prev != null) 232 | { 233 | Move(layer).After(prev); 234 | } 235 | prev = layer; 236 | } 237 | } 238 | #endregion; 239 | 240 | #region Other 241 | public bool Contains(string layer) 242 | { 243 | return _graph.ContainsVertex(layer); 244 | } 245 | public IEnumerator GetEnumerator() { return _graph.GetEnumerator(); } 246 | IEnumerator IEnumerable.GetEnumerator() { return _graph.GetEnumerator(); } 247 | #endregion 248 | 249 | #region Build 250 | public string[] Build() 251 | { 252 | return _graph.Sort(); 253 | } 254 | #endregion 255 | 256 | #region Obsolete 257 | [Obsolete("Use " + nameof(LayersMap) + ".Add(layer).Before(targetLayer).Back;")] 258 | public EcsPipeline.Builder Insert(string targetLayer, string newLayer) 259 | { 260 | Add(newLayer).Before(targetLayer); 261 | return _pipelineBuilder; 262 | } 263 | [Obsolete("Use " + nameof(LayersMap) + ".Add(layer).After(targetLayer).Back;")] 264 | public EcsPipeline.Builder InsertAfter(string targetLayer, string newLayer) 265 | { 266 | Add(newLayer).After(targetLayer); 267 | return _pipelineBuilder; 268 | } 269 | [Obsolete("Use " + nameof(LayersMap) + ".Move(layer).Before(targetLayer).Back;")] 270 | public EcsPipeline.Builder Move(string targetLayer, string newLayer) 271 | { 272 | Move(newLayer).Before(targetLayer); 273 | return _pipelineBuilder; 274 | } 275 | [Obsolete("Use " + nameof(LayersMap) + ".Move(layer).After(targetLayer).Back;")] 276 | public EcsPipeline.Builder MoveAfter(string targetLayer, string newLayer) 277 | { 278 | Move(newLayer).After(targetLayer); 279 | return _pipelineBuilder; 280 | } 281 | [Obsolete("Use " + nameof(LayersMap) + ".Add(layers).Before(targetLayer).Back;")] 282 | public EcsPipeline.Builder Insert(string targetLayer, params string[] newLayers) 283 | { 284 | Add(newLayers).Before(targetLayer); 285 | return _pipelineBuilder; 286 | } 287 | [Obsolete("Use " + nameof(LayersMap) + ".Add(layers).After(targetLayer).Back;")] 288 | public EcsPipeline.Builder InsertAfter(string targetLayer, params string[] newLayers) 289 | { 290 | Add(newLayers).After(targetLayer); 291 | return _pipelineBuilder; 292 | } 293 | [Obsolete("Use " + nameof(LayersMap) + ".Move(layers).Before(targetLayer).Back;")] 294 | public EcsPipeline.Builder Move(string targetLayer, params string[] movingLayers) 295 | { 296 | Move(movingLayers).Before(targetLayer); 297 | return _pipelineBuilder; 298 | } 299 | [Obsolete("Use " + nameof(LayersMap) + ".Move(layers).After(targetLayer).Back;")] 300 | public EcsPipeline.Builder MoveAfter(string targetLayer, params string[] movingLayers) 301 | { 302 | Move(movingLayers).After(targetLayer); 303 | return _pipelineBuilder; 304 | } 305 | 306 | [Obsolete] 307 | public object this[int index] 308 | { 309 | get 310 | { 311 | int i = 0; 312 | foreach (var item in this) 313 | { 314 | if (i == index) 315 | { 316 | return item; 317 | } 318 | i++; 319 | } 320 | return null; 321 | } 322 | } 323 | #endregion 324 | } 325 | } -------------------------------------------------------------------------------- /src/Utils/LayersMap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb02dc6e42d76c8439e8dc52a6624244 -------------------------------------------------------------------------------- /src/Utils/ReadOnlySpanDummy.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DCFApixels/DragonECS/bd192db22a0e87d7f8a9f6240a639c7d46de4131/src/Utils/ReadOnlySpanDummy.cs -------------------------------------------------------------------------------- /src/Utils/ReadOnlySpanDummy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bfb00ad58c175a84388c316daf9b03ae 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/Uncheked.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5f2e943735300fe40bdbff86b6089dad 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Utils/Uncheked/EntitiesMatrix.cs: -------------------------------------------------------------------------------- 1 | #if DISABLE_DEBUG 2 | #undef DEBUG 3 | #endif 4 | 5 | namespace DCFApixels.DragonECS.UncheckedCore 6 | { 7 | public readonly struct EntitiesMatrix 8 | { 9 | private readonly EcsWorld _world; 10 | public EntitiesMatrix(EcsWorld world) 11 | { 12 | _world = world; 13 | } 14 | public int PoolsCount 15 | { 16 | get { return _world.PoolsCount; } 17 | } 18 | public int EntitesCount 19 | { 20 | get { return _world.Capacity; } 21 | } 22 | public int GetEntityComponentsCount(int entityID) 23 | { 24 | return _world.GetComponentsCount(entityID); 25 | } 26 | public int GetEntityGen(int entityID) 27 | { 28 | return _world.GetGen(entityID); 29 | } 30 | public bool IsEntityUsed(int entityID) 31 | { 32 | return _world.IsUsed(entityID); 33 | } 34 | public bool this[int entityID, int poolID] 35 | { 36 | get 37 | { 38 | int entityStartChunkIndex = entityID << _world._entityComponentMaskLengthBitShift; 39 | var chunkInfo = EcsMaskChunck.FromID(poolID); 40 | return (_world._entityComponentMasks[entityStartChunkIndex + chunkInfo.chunkIndex] & chunkInfo.mask) != 0; 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/Utils/Uncheked/EntitiesMatrix.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 82a4a05728fb81b4b903d9893a85f77f -------------------------------------------------------------------------------- /src/Utils/Uncheked/EntitySlotInfo.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.Runtime.CompilerServices; 8 | using System.Runtime.InteropServices; 9 | 10 | namespace DCFApixels.DragonECS.Core.Unchecked 11 | { 12 | [StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)] 13 | [DebuggerTypeProxy(typeof(EntityDebuggerProxy))] 14 | public struct EntitySlotInfo : IEquatable 15 | { 16 | #if UNITY_EDITOR 17 | [UnityEngine.SerializeField] 18 | #endif 19 | [FieldOffset(0)] 20 | public long full; //Union 21 | [FieldOffset(0), NonSerialized] 22 | public int id; 23 | [FieldOffset(4), NonSerialized] 24 | public short gen; 25 | [FieldOffset(6), NonSerialized] 26 | public short worldID; 27 | 28 | #region Properties 29 | public EcsWorld World { get { return EcsWorld.GetWorld(worldID); } } 30 | public StateFlag State { get { return full == 0 ? StateFlag.Null : World.IsAlive(id, gen) ? StateFlag.Alive : StateFlag.Dead; } } 31 | #endregion 32 | 33 | #region Constructors/Deconstructors 34 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 35 | public EntitySlotInfo(long full) : this() 36 | { 37 | this.full = full; 38 | } 39 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 40 | public EntitySlotInfo(int id, short gen, short world) : this() 41 | { 42 | this.id = id; 43 | this.gen = gen; 44 | worldID = world; 45 | } 46 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 47 | public void Deconstruct(out int id, out int gen, out int worldID) 48 | { 49 | id = this.id; 50 | gen = this.gen; 51 | worldID = this.worldID; 52 | } 53 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 54 | public void Deconstruct(out int id, out int worldID) 55 | { 56 | id = this.id; 57 | worldID = this.worldID; 58 | } 59 | #endregion 60 | 61 | #region Operators 62 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 63 | public static bool operator ==(EntitySlotInfo a, EntitySlotInfo b) { return a.full == b.full; } 64 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 65 | public static bool operator !=(EntitySlotInfo a, EntitySlotInfo b) { return a.full != b.full; } 66 | 67 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 68 | public static explicit operator EntitySlotInfo(entlong a) { return new EntitySlotInfo(a._full); } 69 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 70 | public static explicit operator entlong(EntitySlotInfo a) { return new entlong(a.full); } 71 | #endregion 72 | 73 | #region Other 74 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 75 | public override int GetHashCode() { return unchecked(id ^ gen ^ (worldID * EcsConsts.MAGIC_PRIME)); } 76 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 77 | public override string ToString() { return $"slot(id:{id} g:{gen} w:{worldID} {(State == StateFlag.Null ? "null" : State == StateFlag.Alive ? "alive" : "not alive")})"; } 78 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 79 | public override bool Equals(object obj) { return obj is EntitySlotInfo other && this == other; } 80 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 81 | public bool Equals(EntitySlotInfo other) { return this == other; } 82 | 83 | public enum StateFlag { Null, Dead, Alive, } 84 | #endregion 85 | } 86 | 87 | internal class EntityDebuggerProxy 88 | { 89 | private List _componentsList = new List(); 90 | private EntitySlotInfo _info; 91 | public virtual long full { get { return _info.full; } } 92 | public virtual int id { get { return _info.id; } } 93 | public virtual short gen { get { return _info.gen; } } 94 | public virtual short worldID { get { return _info.worldID; } } 95 | public virtual EntitySlotInfo.StateFlag State { get { return _info.State; } } 96 | public virtual EcsWorld World { get { return _info.World; } } 97 | public virtual IEnumerable Components 98 | { 99 | get 100 | { 101 | if (State == EntitySlotInfo.StateFlag.Alive) 102 | { 103 | World.GetComponentsFor(id, _componentsList); 104 | return _componentsList; 105 | } 106 | return Array.Empty(); 107 | } 108 | set 109 | { 110 | if (State == EntitySlotInfo.StateFlag.Alive) 111 | { 112 | foreach (var component in value) 113 | { 114 | if (component == null) { continue; } 115 | var componentType = component.GetType(); 116 | var world = World; 117 | 118 | if (componentType.IsValueType && world.TryFindPoolInstance(componentType, out IEcsPool pool)) 119 | { 120 | pool.SetRaw(id, component); 121 | } 122 | } 123 | } 124 | } 125 | } 126 | public EntityDebuggerProxy(EntitySlotInfo info) 127 | { 128 | _info = info; 129 | } 130 | public EntityDebuggerProxy(entlong info) 131 | { 132 | _info = (EntitySlotInfo)info; 133 | } 134 | public EntityDebuggerProxy(int entityID, short gen, short worldID) 135 | { 136 | _info = new EntitySlotInfo(entityID, gen, worldID); 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /src/Utils/Uncheked/EntitySlotInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 76b422b663e6c9d488b5eb4fac26de61 -------------------------------------------------------------------------------- /src/Utils/Uncheked/UncheckedUtility.cs: -------------------------------------------------------------------------------- 1 | #if DISABLE_DEBUG 2 | #undef DEBUG 3 | #endif 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Runtime.CompilerServices; 7 | 8 | namespace DCFApixels.DragonECS.UncheckedCore 9 | { 10 | [Obsolete("Use DCFApixels.DragonECS.Core.UncheckedUtility")] 11 | public static class UncheckedCoreUtility 12 | { 13 | #region CreateEntLong 14 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 15 | public static entlong CreateEntLong(int entityID, short gen, short worldID) 16 | { 17 | return new entlong(entityID, gen, worldID); 18 | } 19 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 20 | public static entlong CreateEntLong(long entityGenWorld) 21 | { 22 | return new entlong(entityGenWorld); 23 | } 24 | #endregion 25 | 26 | #region CreateSpan 27 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 28 | public static EcsSpan CreateSpan(short worldID, ReadOnlySpan entitesArray) 29 | { 30 | return new EcsSpan(worldID, entitesArray); 31 | } 32 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 33 | public static EcsSpan CreateSpan(short worldID, int[] entitesArray, int startIndex, int length) 34 | { 35 | return new EcsSpan(worldID, entitesArray, startIndex, length); 36 | } 37 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 38 | public static EcsSpan CreateSpan(short worldID, int[] entitesArray, int length) 39 | { 40 | return new EcsSpan(worldID, entitesArray, length); 41 | } 42 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 43 | public static EcsSpan CreateSpan(short worldID, int[] entitesArray) 44 | { 45 | return new EcsSpan(worldID, entitesArray); 46 | } 47 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 48 | public static EcsSpan CreateEmptySpan(short worldID) 49 | { 50 | return new EcsSpan(worldID, Array.Empty()); 51 | } 52 | public static bool CheckSpanValideDebug(EcsSpan span) 53 | { 54 | HashSet set = new HashSet(); 55 | foreach (var e in span) 56 | { 57 | if (set.Add(e) == false) 58 | { 59 | return false; 60 | } 61 | } 62 | return true; 63 | } 64 | #endregion 65 | 66 | #region EcsGroup 67 | public static EcsGroup GetSourceInstance(EcsReadonlyGroup group) 68 | { 69 | return group.GetSource_Internal(); 70 | } 71 | #endregion 72 | } 73 | } 74 | 75 | namespace DCFApixels.DragonECS.Core.Unchecked 76 | { 77 | public static class UncheckedUtility 78 | { 79 | #region CreateEntLong 80 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 81 | public static entlong CreateEntLong(int entityID, short gen, short worldID) 82 | { 83 | return new entlong(entityID, gen, worldID); 84 | } 85 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 86 | public static entlong CreateEntLong(long entityGenWorld) 87 | { 88 | return new entlong(entityGenWorld); 89 | } 90 | #endregion 91 | 92 | #region CreateSpan 93 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 94 | public static EcsSpan CreateSpan(short worldID, ReadOnlySpan entitesArray) 95 | { 96 | return new EcsSpan(worldID, entitesArray); 97 | } 98 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 99 | public static EcsSpan CreateSpan(short worldID, int[] entitesArray, int startIndex, int length) 100 | { 101 | return new EcsSpan(worldID, entitesArray, startIndex, length); 102 | } 103 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 104 | public static EcsSpan CreateSpan(short worldID, int[] entitesArray, int length) 105 | { 106 | return new EcsSpan(worldID, entitesArray, length); 107 | } 108 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 109 | public static EcsSpan CreateSpan(short worldID, int[] entitesArray) 110 | { 111 | return new EcsSpan(worldID, entitesArray); 112 | } 113 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 114 | public static EcsSpan CreateEmptySpan(short worldID) 115 | { 116 | return new EcsSpan(worldID, Array.Empty()); 117 | } 118 | public static bool CheckSpanValideDebug(EcsSpan span) 119 | { 120 | HashSet set = new HashSet(); 121 | foreach (var e in span) 122 | { 123 | if (set.Add(e) == false) 124 | { 125 | return false; 126 | } 127 | } 128 | return true; 129 | } 130 | #endregion 131 | 132 | #region EcsGroup 133 | public static EcsGroup GetSourceInstance(EcsReadonlyGroup group) 134 | { 135 | return group.GetSource_Internal(); 136 | } 137 | #endregion 138 | } 139 | } -------------------------------------------------------------------------------- /src/Utils/Uncheked/UncheckedUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d505e05a1757344fa2237b4b9be4409 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/entlong.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30b110ce8ab345842beda6ebfcc53e4e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | --------------------------------------------------------------------------------