Skip to content

Commit 3bfd208

Browse files
committed
Single<TData, TFilter>
1 parent 48db59f commit 3bfd208

File tree

1 file changed

+72
-6
lines changed

1 file changed

+72
-6
lines changed

src/Bevy.cs

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -395,10 +395,7 @@ public class Query<TQueryData, TQueryFilter> : SystemParam<World>, IIntoSystemPa
395395
{
396396
private readonly Query _query;
397397

398-
internal Query(Query query)
399-
{
400-
_query = query;
401-
}
398+
internal Query(Query query) =>_query = query;
402399

403400
public static ISystemParam<World> Generate(World arg)
404401
{
@@ -418,9 +415,8 @@ public static ISystemParam<World> Generate(World arg)
418415
public TQueryData Get(EcsID id)
419416
{
420417
var enumerator = TQueryData.CreateIterator(_query.Iter(id));
421-
// TODO: handle the success
422418
var success = enumerator.MoveNext();
423-
return enumerator;
419+
return success ? enumerator : default;
424420
}
425421

426422
public TQueryData Single()
@@ -436,6 +432,76 @@ public int Count()
436432
=> _query.Count();
437433
}
438434

435+
public class Single<TQueryData> : Single<TQueryData, Empty>, IIntoSystemParam<World>
436+
where TQueryData : struct, IData<TQueryData>, IQueryIterator<TQueryData>, allows ref struct
437+
{
438+
internal Single(Query query) : base(query) { }
439+
440+
public new static ISystemParam<World> Generate(World arg)
441+
{
442+
if (arg.Entity<Placeholder<Single<TQueryData>>>().Has<Placeholder<Single<TQueryData>>>())
443+
return arg.Entity<Placeholder<Single<TQueryData>>>().Get<Placeholder<Single<TQueryData>>>().Value;
444+
445+
var builder = arg.QueryBuilder();
446+
TQueryData.Build(builder);
447+
var q = new Single<TQueryData>(builder.Build());
448+
arg.Entity<Placeholder<Single<TQueryData>>>().Set(new Placeholder<Single<TQueryData>>() { Value = q });
449+
return q;
450+
}
451+
}
452+
453+
public class Single<TQueryData, TQueryFilter> : SystemParam<World>, IIntoSystemParam<World>
454+
where TQueryData : struct, IData<TQueryData>, IQueryIterator<TQueryData>, allows ref struct
455+
where TQueryFilter : struct, IFilter, allows ref struct
456+
{
457+
private readonly Query _query;
458+
459+
internal Single(Query query) => _query = query;
460+
461+
public static ISystemParam<World> Generate(World arg)
462+
{
463+
if (arg.Entity<Placeholder<Single<TQueryData, TQueryFilter>>>().Has<Placeholder<Single<TQueryData, TQueryFilter>>>())
464+
return arg.Entity<Placeholder<Single<TQueryData, TQueryFilter>>>().Get<Placeholder<Single<TQueryData, TQueryFilter>>>().Value;
465+
466+
var builder = arg.QueryBuilder();
467+
TQueryData.Build(builder);
468+
TQueryFilter.Build(builder);
469+
var q = new Single<TQueryData, TQueryFilter>(builder.Build());
470+
arg.Entity<Placeholder<Single<TQueryData, TQueryFilter>>>().Set(new Placeholder<Single<TQueryData, TQueryFilter>>() { Value = q });
471+
return q;
472+
}
473+
474+
public TQueryData Get()
475+
{
476+
EcsAssert.Panic(_query.Count() == 1, "'Single' must match one and only one entity.");
477+
var enumerator = TQueryData.CreateIterator(_query.Iter());
478+
var ok = enumerator.MoveNext();
479+
EcsAssert.Panic(ok, "'Single' is not matching any entity.");
480+
return enumerator;
481+
}
482+
483+
public bool TryGet(out TQueryData data)
484+
{
485+
if (_query.Count() == 1)
486+
{
487+
var enumerator = TQueryData.CreateIterator(_query.Iter());
488+
var ok = enumerator.MoveNext();
489+
if (ok)
490+
{
491+
data = enumerator;
492+
return true;
493+
}
494+
}
495+
496+
data = default;
497+
return false;
498+
}
499+
500+
public int Count()
501+
=> _query.Count();
502+
}
503+
504+
439505
public sealed class Res<T> : SystemParam<World>, IIntoSystemParam<World> where T : notnull
440506
{
441507
private T? _t;

0 commit comments

Comments
 (0)