Last active
April 9, 2020 09:29
-
-
Save dasannikov/c3c0c88091a3004108cf5d701a0ef0b2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using Leopotam.Ecs; | |
using UnityEngine; | |
//----------------------------------------------------------------------------- | |
// Attributes | |
//----------------------------------------------------------------------------- | |
class EcsInjectToStatic : Attribute { } | |
class EcsRequireFilters : Attribute { } | |
//----------------------------------------------------------------------------- | |
// Inject EcsWorld and EcsFilters to all classes with attribute [EcsInjectToStatic] | |
//----------------------------------------------------------------------------- | |
sealed class RequireAndInjectEcsSystem : IEcsInitSystem, IEcsDestroySystem { | |
EcsWorld _world = null; | |
readonly Type _filterType = typeof(EcsFilter); | |
readonly Type _worldType = typeof(EcsWorld); | |
readonly Type _attributeInjectType = typeof(EcsInjectToStatic); | |
readonly Type _attributeRequireType = typeof(EcsRequireFilters); | |
void IEcsInitSystem.Init() => ScanAllTypesAndInject(false); | |
void IEcsDestroySystem.Destroy() => ScanAllTypesAndInject(true); | |
void ScanAllTypesAndInject(bool isDestroy) { | |
var assemblies = AppDomain.CurrentDomain.GetAssemblies(); | |
foreach(var assembly in assemblies) | |
foreach(var type in assembly.GetTypes()) { | |
if(Attribute.IsDefined(type, _attributeInjectType)) | |
Inject(type, isDestroy); | |
if(!isDestroy && Attribute.IsDefined(type, _attributeRequireType)) | |
RequireFilter(type); | |
} | |
} | |
void RequireFilter(Type type) { | |
foreach(var f in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { | |
if(f.FieldType.IsSubclassOf(_filterType)) | |
_world.GetFilter(f.FieldType); | |
} | |
} | |
void Inject(Type type, bool isDestroy) { | |
foreach(var f in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) { | |
// Inject filters | |
if(f.FieldType.IsSubclassOf(_filterType)) | |
f.SetValue(type, isDestroy ? null : _world.GetFilter(f.FieldType)); | |
// Inject world | |
if(f.FieldType == _worldType) | |
f.SetValue(type, isDestroy ? null : _world); | |
// Additional inject? | |
// ... | |
} | |
} | |
} | |
//----------------------------------------------------------------------------- | |
// Inject usage example. Inject to static members. | |
//----------------------------------------------------------------------------- | |
[EcsInjectToStatic] | |
class TestEcsStatic : MonoBehaviour { | |
static readonly EcsWorld _world = default; | |
static readonly EcsFilter<Item> _itemFilter = default; | |
void Start() { | |
Debug.Log(_itemFilter.IsEmpty()); | |
Debug.Log(_world.GetStats().Filters); | |
} | |
} | |
//----------------------------------------------------------------------------- | |
// Require usage example. | |
//----------------------------------------------------------------------------- | |
[EcsRequireFilters] | |
class TestEcs : MonoBehaviour { | |
EcsFilter<Item> _itemFilter = default; | |
void Start() { | |
// You need EcsWorld to get filter | |
_itemFilter = EcsWorld.GetFilter(typeof(EcsFilter<Item>)) as EcsFilter<Item>; | |
Debug.Log(_itemFilter?.IsEmpty()); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment