mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
* Add support for struct directed events. - Turn transform events into readonly structs * TransformComponent events have readonly fields. * Reduce boxing allocations, add DirectedRegistration readonly struct. * Use typeof in a few places instead of GetType * Add overloads to allow passing directed events by ref. * Raise transform events by ref. * Fix occluder AnchorStateChangedEvent subscription * Fix broadphase subscriptions * Fix bug oops * Fix transform system raising moveevents by value * Don't reflect the test entity systems. * Directed EventBus uses ref everywhere, internally Deduplicates a bunch of code. Whoo! * Add broadcast by-ref events * Fix by-ref events bug using Unsafe, add new tests for sorted by-ref events. * Port broadcast events to by-ref. * Speed, more correctness, reduce generics bloat. * Clean up subscription code some. * Remove bad test. Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
252 lines
8.3 KiB
C#
252 lines
8.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using JetBrains.Annotations;
|
|
|
|
namespace Robust.Shared.GameObjects
|
|
{
|
|
public abstract partial class EntitySystem
|
|
{
|
|
private List<SubBase>? _subscriptions;
|
|
|
|
/// <summary>
|
|
/// A handle to allow subscription on this entity system's behalf.
|
|
/// </summary>
|
|
protected Subscriptions Subs { get; }
|
|
|
|
// NOTE: EntityEventHandler<T> and EntitySessionEventHandler<T> CANNOT BE ORDERED BETWEEN EACH OTHER.
|
|
// EntityEventRefHandler<T> and EntityEventHandler<T> can be, however. They're essentially the same.
|
|
|
|
protected void SubscribeNetworkEvent<T>(
|
|
EntityEventHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
SubEvent(EventSource.Network, handler, before, after);
|
|
}
|
|
|
|
protected void SubscribeLocalEvent<T>(
|
|
EntityEventHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
SubEvent(EventSource.Local, handler, before, after);
|
|
}
|
|
|
|
protected void SubscribeLocalEvent<T>(
|
|
EntityEventRefHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
SubEvent(EventSource.Local, handler, before, after);
|
|
}
|
|
|
|
protected void SubscribeAllEvent<T>(
|
|
EntityEventHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
SubEvent(EventSource.All, handler, before, after);
|
|
}
|
|
|
|
protected void SubscribeNetworkEvent<T>(
|
|
EntitySessionEventHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
SubSessionEvent(EventSource.Network, handler, before, after);
|
|
}
|
|
|
|
protected void SubscribeLocalEvent<T>(
|
|
EntitySessionEventHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
SubSessionEvent(EventSource.Local, handler, before, after);
|
|
}
|
|
|
|
protected void SubscribeAllEvent<T>(
|
|
EntitySessionEventHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
SubSessionEvent(EventSource.All, handler, before, after);
|
|
}
|
|
|
|
private void SubEvent<T>(
|
|
EventSource src,
|
|
EntityEventHandler<T> handler,
|
|
Type[]? before, Type[]? after)
|
|
where T : notnull
|
|
{
|
|
EntityManager.EventBus.SubscribeEvent(src, this, handler, GetType(), before, after);
|
|
|
|
_subscriptions ??= new();
|
|
_subscriptions.Add(new SubBroadcast<T>(src));
|
|
}
|
|
|
|
private void SubEvent<T>(
|
|
EventSource src,
|
|
EntityEventRefHandler<T> handler,
|
|
Type[]? before, Type[]? after)
|
|
where T : notnull
|
|
{
|
|
EntityManager.EventBus.SubscribeEvent(src, this, handler, GetType(), before, after);
|
|
|
|
_subscriptions ??= new();
|
|
_subscriptions.Add(new SubBroadcast<T>(src));
|
|
}
|
|
|
|
private void SubSessionEvent<T>(
|
|
EventSource src,
|
|
EntitySessionEventHandler<T> handler,
|
|
Type[]? before, Type[]? after)
|
|
where T : notnull
|
|
{
|
|
EntityManager.EventBus.SubscribeSessionEvent(src, this, handler, GetType(), before, after);
|
|
|
|
_subscriptions ??= new();
|
|
_subscriptions.Add(new SubBroadcast<EntitySessionMessage<T>>(src));
|
|
}
|
|
|
|
[Obsolete("Unsubscribing of entity system events is now automatic")]
|
|
protected void UnsubscribeNetworkEvent<T>()
|
|
where T : notnull
|
|
{
|
|
EntityManager.EventBus.UnsubscribeEvent<T>(EventSource.Network, this);
|
|
}
|
|
|
|
[Obsolete("Unsubscribing of entity system events is now automatic")]
|
|
protected void UnsubscribeLocalEvent<T>()
|
|
where T : notnull
|
|
{
|
|
EntityManager.EventBus.UnsubscribeEvent<T>(EventSource.Local, this);
|
|
}
|
|
|
|
protected void SubscribeLocalEvent<TComp, TEvent>(
|
|
ComponentEventHandler<TComp, TEvent> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where TComp : IComponent
|
|
where TEvent : notnull
|
|
{
|
|
EntityManager.EventBus.SubscribeLocalEvent(handler, GetType(), before, after);
|
|
|
|
_subscriptions ??= new();
|
|
_subscriptions.Add(new SubLocal<TComp, TEvent>());
|
|
}
|
|
|
|
protected void SubscribeLocalEvent<TComp, TEvent>(
|
|
ComponentEventRefHandler<TComp, TEvent> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where TComp : IComponent
|
|
where TEvent : notnull
|
|
{
|
|
EntityManager.EventBus.SubscribeLocalEvent(handler, GetType(), before, after);
|
|
|
|
_subscriptions ??= new();
|
|
_subscriptions.Add(new SubLocal<TComp, TEvent>());
|
|
}
|
|
|
|
[Obsolete("Unsubscribing of entity system events is now automatic")]
|
|
protected void UnsubscribeLocalEvent<TComp, TEvent>(ComponentEventHandler<TComp, TEvent> handler)
|
|
where TComp : IComponent
|
|
where TEvent : notnull
|
|
{
|
|
EntityManager.EventBus.UnsubscribeLocalEvent<TComp, TEvent>();
|
|
}
|
|
|
|
[Obsolete("Unsubscribing of entity system events is now automatic")]
|
|
protected void UnsubscribeLocalEvent<TComp, TEvent>()
|
|
where TComp : IComponent
|
|
where TEvent : notnull
|
|
{
|
|
EntityManager.EventBus.UnsubscribeLocalEvent<TComp, TEvent>();
|
|
}
|
|
|
|
private void ShutdownSubscriptions()
|
|
{
|
|
if (_subscriptions == null)
|
|
return;
|
|
|
|
foreach (var sub in _subscriptions)
|
|
{
|
|
sub.Unsubscribe(this, EntityManager.EventBus);
|
|
}
|
|
|
|
_subscriptions = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// API class to allow registering on an EntitySystem's behalf.
|
|
/// Intended to support creation of boilerplate-reduction-methods
|
|
/// that need to subscribe stuff on an entity system.
|
|
/// </summary>
|
|
[PublicAPI]
|
|
public sealed class Subscriptions
|
|
{
|
|
public EntitySystem System { get; }
|
|
|
|
internal Subscriptions(EntitySystem system)
|
|
{
|
|
System = system;
|
|
}
|
|
|
|
// Intended for helper methods, so minimal API.
|
|
|
|
public void SubEvent<T>(
|
|
EventSource src,
|
|
EntityEventHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
System.SubEvent(src, handler, before, after);
|
|
}
|
|
|
|
public void SubSessionEvent<T>(
|
|
EventSource src,
|
|
EntitySessionEventHandler<T> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where T : notnull
|
|
{
|
|
System.SubSessionEvent(src, handler, before, after);
|
|
}
|
|
|
|
public void SubscribeLocalEvent<TComp, TEvent>(
|
|
ComponentEventHandler<TComp, TEvent> handler,
|
|
Type[]? before = null, Type[]? after = null)
|
|
where TComp : IComponent
|
|
where TEvent : EntityEventArgs
|
|
{
|
|
System.SubscribeLocalEvent(handler, before, after);
|
|
}
|
|
}
|
|
|
|
private abstract class SubBase
|
|
{
|
|
public abstract void Unsubscribe(EntitySystem sys, IEventBus bus);
|
|
}
|
|
|
|
private sealed class SubBroadcast<T> : SubBase where T : notnull
|
|
{
|
|
private readonly EventSource _source;
|
|
|
|
public SubBroadcast(EventSource source)
|
|
{
|
|
_source = source;
|
|
}
|
|
|
|
public override void Unsubscribe(EntitySystem sys, IEventBus bus)
|
|
{
|
|
bus.UnsubscribeEvent<T>(_source, sys);
|
|
}
|
|
}
|
|
|
|
private sealed class SubLocal<TComp, TBase> : SubBase where TComp : IComponent where TBase : notnull
|
|
{
|
|
public override void Unsubscribe(EntitySystem sys, IEventBus bus)
|
|
{
|
|
bus.UnsubscribeLocalEvent<TComp, TBase>();
|
|
}
|
|
}
|
|
}
|
|
}
|