diff --git a/src/Bevy.cs b/src/Bevy.cs index 23bee6f..b328611 100644 --- a/src/Bevy.cs +++ b/src/Bevy.cs @@ -395,10 +395,7 @@ public class Query : SystemParam, IIntoSystemPa { private readonly Query _query; - internal Query(Query query) - { - _query = query; - } + internal Query(Query query) =>_query = query; public static ISystemParam Generate(World arg) { @@ -418,9 +415,8 @@ public static ISystemParam Generate(World arg) public TQueryData Get(EcsID id) { var enumerator = TQueryData.CreateIterator(_query.Iter(id)); - // TODO: handle the success var success = enumerator.MoveNext(); - return enumerator; + return success ? enumerator : default; } public TQueryData Single() @@ -436,6 +432,76 @@ public int Count() => _query.Count(); } +public class Single : Single, IIntoSystemParam + where TQueryData : struct, IData, IQueryIterator, allows ref struct +{ + internal Single(Query query) : base(query) { } + + public new static ISystemParam Generate(World arg) + { + if (arg.Entity>>().Has>>()) + return arg.Entity>>().Get>>().Value; + + var builder = arg.QueryBuilder(); + TQueryData.Build(builder); + var q = new Single(builder.Build()); + arg.Entity>>().Set(new Placeholder>() { Value = q }); + return q; + } +} + +public class Single : SystemParam, IIntoSystemParam + where TQueryData : struct, IData, IQueryIterator, allows ref struct + where TQueryFilter : struct, IFilter, allows ref struct +{ + private readonly Query _query; + + internal Single(Query query) => _query = query; + + public static ISystemParam Generate(World arg) + { + if (arg.Entity>>().Has>>()) + return arg.Entity>>().Get>>().Value; + + var builder = arg.QueryBuilder(); + TQueryData.Build(builder); + TQueryFilter.Build(builder); + var q = new Single(builder.Build()); + arg.Entity>>().Set(new Placeholder>() { Value = q }); + return q; + } + + public TQueryData Get() + { + EcsAssert.Panic(_query.Count() == 1, "'Single' must match one and only one entity."); + var enumerator = TQueryData.CreateIterator(_query.Iter()); + var ok = enumerator.MoveNext(); + EcsAssert.Panic(ok, "'Single' is not matching any entity."); + return enumerator; + } + + public bool TryGet(out TQueryData data) + { + if (_query.Count() == 1) + { + var enumerator = TQueryData.CreateIterator(_query.Iter()); + var ok = enumerator.MoveNext(); + if (ok) + { + data = enumerator; + return true; + } + } + + data = default; + return false; + } + + public int Count() + => _query.Count(); +} + + public sealed class Res : SystemParam, IIntoSystemParam where T : notnull { private T? _t;