Created
April 14, 2019 09:23
-
-
Save quabug/9668699c43dc90c5a555e5f144291a85 to your computer and use it in GitHub Desktop.
Create Unity ECS systems by zenject way which automaticly inject necessary instances into constructor of system.
This file contains hidden or 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
class MainInstaller : MonoInstaller<MainInstaller> | |
{ | |
public override void InstallBindings() { | |
Container.BindInstance(World.Active); | |
Container.Bind<WorldSystemCreatorFactory>().AsSingle().WithArguments(Container); | |
Container.Bind<SomeService>().ToSelf().AsSingle(); | |
Container.Bind<Example>().ToSelf().AsSingle().NonLazy(); | |
} | |
} | |
class SomeService {} | |
class SomeSystem : ComponentSystem | |
{ | |
public SomeSystem(SomeService service) {} | |
protected override void OnUpdate() {} | |
} | |
class Example | |
{ | |
public Example(WorldSystemCreatorFactory creatorFactory, World world) { | |
var creator = creatorFactory(world); | |
var someSystem = creator(typeof(SomeSystem)); | |
} | |
} |
This file contains hidden or 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
#if !DISABLE_ZENJECT | |
using System; | |
using Unity.Entities; | |
using Zenject; | |
using Zenject.Internal; | |
namespace FortyTwo | |
{ | |
public class WorldSystemCreatorFactory | |
{ | |
private readonly DiContainer _container; | |
public WorldSystemCreatorFactory(DiContainer container) | |
{ | |
_container = container; | |
} | |
public Func<Type, ComponentSystemBase> MakeCreator(World world) | |
{ | |
var subContainer = _container.CreateSubContainer(); | |
subContainer.BindInstance(world); | |
subContainer.BindInstance(world.EntityManager); | |
return systemType => | |
{ | |
var typeInfo = TypeAnalyzer.GetInfo(systemType); | |
var paramValues = ZenPools.SpawnArray<object>(typeInfo.InjectConstructor.Parameters.Length); | |
var extraArgs = ListPool<TypeValuePair>.Instance.Spawn(); | |
var concreteType = systemType; | |
var context = new InjectContext(subContainer, concreteType, null); | |
try | |
{ | |
for (int i = 0; i < typeInfo.InjectConstructor.Parameters.Length; i++) | |
{ | |
var injectInfo = typeInfo.InjectConstructor.Parameters[i]; | |
if (!InjectUtil.PopValueWithType( | |
extraArgs, injectInfo.MemberType, out var value)) | |
{ | |
using (var subContext = ZenPools.SpawnInjectContext( | |
subContainer, injectInfo, context, null, concreteType, null)) | |
{ | |
value = subContainer.Resolve(subContext); | |
} | |
} | |
paramValues[i] = value; | |
} | |
return world.CreateSystem(systemType, paramValues); | |
} | |
finally | |
{ | |
ListPool<TypeValuePair>.Instance.Despawn(extraArgs); | |
ZenPools.DespawnArray(paramValues); | |
} | |
}; | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment