-
Notifications
You must be signed in to change notification settings - Fork 2
Injectable
Magicolo edited this page Jan 31, 2019
·
12 revisions
An injectable is an encapsulation of a subset of the world operations that can guarantee a certain usage of those operations. They are automatically injected in a system's public
fields and are used for thread safety analysis. Using the most specific injectables in systems, allows thread safety analysis to be most useful to prevent data races.
using Entia;
using Entia.Injectables;
using Entia.Queryables;
using Entia.Systems;
namespace Components
{
public struct Invincibility : IComponent { public float Time; }
public struct Health : IComponent { public float Current, Maximum; }
}
namespace Messages
{
public struct DoDamage : IMessage { public float Amount; }
public struct OnDeath : IMessage { }
}
namespace Resources
{
public struct Game : IResource
{
public bool WillQuit;
public bool IsPaused;
}
}
namespace Systems
{
// A system that is not registered to any execution system interface.
public struct Kill : ISystem
{
// There are many implemented injectables. These are some of them.
// See the 'Entia.Injectables' namespace to discover all of them.
public readonly Components<Components.Health> Healths;
// Notice that more specific injectables may be nested inside a more
// general one.
public readonly Components<Components.Invincibility>.Read Invincibilities;
public readonly Receiver<Messages.DoDamage> DoDamage;
public readonly Emitter<Messages.OnDeath> OnDeath;
public readonly Resource<Resources.Game>.Read Game;
public readonly Group<Read<Components.Health>> Group;
// The world is a valid injectable but will prevent thread safety analysis
// since is statically unpredictable.
public readonly World World;
}
}
It is possible to define how an injectable should be constructed by specifying a default implementation of an Injector<T>
and linking it using the generic interface IInjectable<T>
.
using System.Reflection;
using Entia;
using Entia.Core;
using Entia.Injectables;
using Entia.Injectors;
using Entia.Modules;
namespace Injectables
{
// An injectable that gives only access to destroy operations.
public readonly struct Destroyer : IInjectable<Injectors.Destroyer>
{
readonly Entities _entities;
public Destroyer(Entities entities) { _entities = entities; }
public bool Destroy(Entity entity) => _entities.Destroy(entity);
public bool DestroyAll() => _entities.Clear();
}
}
namespace Injectors
{
public sealed class Destroyer : Injector<Injectables.Destroyer>
{
public override Result<Injectables.Destroyer> Inject(
MemberInfo member,
World world) =>
new Injectables.Destroyer(world.Entities());
}
}