Initial Commit

This commit is contained in:
2026-03-16 14:38:46 +02:00
commit b8f7327a21
2327 changed files with 253610 additions and 0 deletions
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: cc112bf254895114bb60868a302a3cf7
folderAsset: yes
timeCreated: 1521266917
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 610ec45090eac884ba824be81ada42fb
folderAsset: yes
timeCreated: 1521277428
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,67 @@
using System;
using ModestTree;
namespace Zenject
{
public class BindSignalFromBinder<TObject, TSignal>
{
readonly BindStatement _bindStatement;
readonly Func<TObject, Action<TSignal>> _methodGetter;
readonly DiContainer _container;
readonly SignalBindingBindInfo _signalBindInfo;
public BindSignalFromBinder(
SignalBindingBindInfo signalBindInfo, BindStatement bindStatement, Func<TObject, Action<TSignal>> methodGetter,
DiContainer container)
{
_signalBindInfo = signalBindInfo;
_bindStatement = bindStatement;
_methodGetter = methodGetter;
_container = container;
}
public SignalCopyBinder FromResolve()
{
return From(x => x.FromResolve().AsCached());
}
public SignalCopyBinder FromResolveAll()
{
return From(x => x.FromResolveAll().AsCached());
}
public SignalCopyBinder FromNew()
{
return From(x => x.FromNew().AsCached());
}
public SignalCopyBinder From(Action<ConcreteBinderGeneric<TObject>> objectBindCallback)
{
Assert.That(!_bindStatement.HasFinalizer);
_bindStatement.SetFinalizer(new NullBindingFinalizer());
var objectLookupId = Guid.NewGuid();
// Very important here that we use NoFlush otherwise the main binding will be finalized early
var objectBinder = _container.BindNoFlush<TObject>().WithId(objectLookupId);
objectBindCallback(objectBinder);
// We need to do this to make sure SignalCallbackWithLookupWrapper does not have
// generic types to avoid AOT issues
Func<object, Action<object>> methodGetterMapper =
obj => s => _methodGetter((TObject)obj)((TSignal)s);
var wrapperBinder = _container.Bind<IDisposable>()
.To<SignalCallbackWithLookupWrapper>()
.AsCached()
.WithArguments(_signalBindInfo, typeof(TObject), objectLookupId, methodGetterMapper)
.NonLazy();
var copyBinder = new SignalCopyBinder( wrapperBinder.BindInfo);
// Make sure if they use one of the Copy/Move methods that it applies to both bindings
copyBinder.AddCopyBindInfo(objectBinder.BindInfo);
return copyBinder;
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: c779f758eaadfd54fb9c66f7acc75716
timeCreated: 1521288279
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
using System;
using ModestTree;
namespace Zenject
{
public class BindSignalIdToBinder<TSignal> : BindSignalToBinder<TSignal>
{
public BindSignalIdToBinder(DiContainer container, SignalBindingBindInfo signalBindInfo)
: base(container, signalBindInfo)
{
}
public BindSignalToBinder<TSignal> WithId(object identifier)
{
SignalBindInfo.Identifier = identifier;
return this;
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: ecce6d44c178e564c8937125741f3c8c
timeCreated: 1538401230
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,64 @@
using System;
using ModestTree;
namespace Zenject
{
public class BindSignalToBinder<TSignal>
{
DiContainer _container;
BindStatement _bindStatement;
SignalBindingBindInfo _signalBindInfo;
public BindSignalToBinder(DiContainer container, SignalBindingBindInfo signalBindInfo)
{
_container = container;
_signalBindInfo = signalBindInfo;
// This will ensure that they finish the binding
_bindStatement = container.StartBinding();
}
protected SignalBindingBindInfo SignalBindInfo
{
get { return _signalBindInfo; }
}
public SignalCopyBinder ToMethod(Action<TSignal> callback)
{
Assert.That(!_bindStatement.HasFinalizer);
_bindStatement.SetFinalizer(new NullBindingFinalizer());
var bindInfo = _container.Bind<IDisposable>()
.To<SignalCallbackWrapper>()
.AsCached()
// Note that there's a reason we don't just make SignalCallbackWrapper have a generic
// argument for signal type - because when using struct type signals it throws
// exceptions on AOT platforms
.WithArguments(_signalBindInfo, (Action<object>)(o => callback((TSignal)o)))
.NonLazy().BindInfo;
return new SignalCopyBinder(bindInfo);
}
public SignalCopyBinder ToMethod(Action callback)
{
return ToMethod(signal => callback());
}
public BindSignalFromBinder<TObject, TSignal> ToMethod<TObject>(Action<TObject, TSignal> handler)
{
return ToMethod<TObject>(x => (Action<TSignal>)(s => handler(x, s)));
}
public BindSignalFromBinder<TObject, TSignal> ToMethod<TObject>(Func<TObject, Action> handlerGetter)
{
return ToMethod<TObject>(x => (Action<TSignal>)(s => handlerGetter(x)()));
}
public BindSignalFromBinder<TObject, TSignal> ToMethod<TObject>(Func<TObject, Action<TSignal>> handlerGetter)
{
return new BindSignalFromBinder<TObject, TSignal>(
_signalBindInfo, _bindStatement, handlerGetter, _container);
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 6df1bca64a984074fb4af41dc1d42a07
timeCreated: 1521288279
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,53 @@
using System;
namespace Zenject
{
// Note that there's a reason we don't just have a generic
// argument for signal type - because when using struct type signals it throws
// exceptions on AOT platforms
public class SignalCallbackWithLookupWrapper : IDisposable
{
readonly DiContainer _container;
readonly SignalBus _signalBus;
readonly Guid _lookupId;
readonly Func<object, Action<object>> _methodGetter;
readonly Type _objectType;
readonly Type _signalType;
readonly object _identifier;
public SignalCallbackWithLookupWrapper(
SignalBindingBindInfo signalBindInfo,
Type objectType,
Guid lookupId,
Func<object, Action<object>> methodGetter,
SignalBus signalBus,
DiContainer container)
{
_objectType = objectType;
_signalType = signalBindInfo.SignalType;
_identifier = signalBindInfo.Identifier;
_container = container;
_methodGetter = methodGetter;
_signalBus = signalBus;
_lookupId = lookupId;
signalBus.SubscribeId(signalBindInfo.SignalType, _identifier, OnSignalFired);
}
void OnSignalFired(object signal)
{
var objects = _container.ResolveIdAll(_objectType, _lookupId);
for (int i = 0; i < objects.Count; i++)
{
_methodGetter(objects[i])(signal);
}
}
public void Dispose()
{
_signalBus.UnsubscribeId(_signalType, _identifier, OnSignalFired);
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 2b11a635fa1263c4f9a9a0d70d7efcf2
timeCreated: 1521293791
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,38 @@
using System;
namespace Zenject
{
// Note that there's a reason we don't just have a generic
// argument for signal type - because when using struct type signals it throws
// exceptions on AOT platforms
public class SignalCallbackWrapper : IDisposable
{
readonly SignalBus _signalBus;
readonly Action<object> _action;
readonly Type _signalType;
readonly object _identifier;
public SignalCallbackWrapper(
SignalBindingBindInfo bindInfo,
Action<object> action,
SignalBus signalBus)
{
_signalType = bindInfo.SignalType;
_identifier = bindInfo.Identifier;
_signalBus = signalBus;
_action = action;
signalBus.SubscribeId(bindInfo.SignalType, _identifier, OnSignalFired);
}
void OnSignalFired(object signal)
{
_action(signal);
}
public void Dispose()
{
_signalBus.UnsubscribeId(_signalType, _identifier, OnSignalFired);
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 9a8599dbdf9033e468671e40de134ccf
timeCreated: 1521289018
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7fe74811bfda2ef4ca9791eab479b27a
folderAsset: yes
timeCreated: 1521277428
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,24 @@
namespace Zenject
{
[NoReflectionBaking]
public class DeclareSignalAsyncTickPriorityCopyBinder : SignalTickPriorityCopyBinder
{
public DeclareSignalAsyncTickPriorityCopyBinder(SignalDeclarationBindInfo signalBindInfo)
: base(signalBindInfo)
{
}
public SignalTickPriorityCopyBinder RunAsync()
{
SignalBindInfo.RunAsync = true;
return this;
}
public SignalCopyBinder RunSync()
{
SignalBindInfo.RunAsync = false;
return this;
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: b81f91889a4f58f45a186d306ec19a76
timeCreated: 1529046908
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
namespace Zenject
{
[NoReflectionBaking]
public class DeclareSignalIdRequireHandlerAsyncTickPriorityCopyBinder : DeclareSignalRequireHandlerAsyncTickPriorityCopyBinder
{
public DeclareSignalIdRequireHandlerAsyncTickPriorityCopyBinder(
SignalDeclarationBindInfo signalBindInfo)
: base(signalBindInfo)
{
}
public DeclareSignalRequireHandlerAsyncTickPriorityCopyBinder WithId(object identifier)
{
SignalBindInfo.Identifier = identifier;
return this;
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 183994f131b561a43a9967cceb7c949d
timeCreated: 1538037476
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
namespace Zenject
{
[NoReflectionBaking]
public class DeclareSignalRequireHandlerAsyncTickPriorityCopyBinder : DeclareSignalAsyncTickPriorityCopyBinder
{
public DeclareSignalRequireHandlerAsyncTickPriorityCopyBinder(
SignalDeclarationBindInfo signalBindInfo)
: base(signalBindInfo)
{
}
public DeclareSignalAsyncTickPriorityCopyBinder RequireSubscriber()
{
SignalBindInfo.MissingHandlerResponse = SignalMissingHandlerResponses.Throw;
return this;
}
public DeclareSignalAsyncTickPriorityCopyBinder OptionalSubscriber()
{
SignalBindInfo.MissingHandlerResponse = SignalMissingHandlerResponses.Ignore;
return this;
}
public DeclareSignalAsyncTickPriorityCopyBinder OptionalSubscriberWithWarning()
{
SignalBindInfo.MissingHandlerResponse = SignalMissingHandlerResponses.Warn;
return this;
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 7cc67ec88be096e4a89e01987d671cb9
timeCreated: 1529046908
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,24 @@
using System;
namespace Zenject
{
[NoReflectionBaking]
public class SignalBindingBindInfo
{
public SignalBindingBindInfo(Type signalType)
{
SignalType = signalType;
}
public object Identifier
{
get; set;
}
public Type SignalType
{
get; private set;
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 054ec2c1e404fd04f99dcab4d9012db2
timeCreated: 1538401117
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,38 @@
using System;
namespace Zenject
{
[NoReflectionBaking]
public class SignalDeclarationBindInfo
{
public SignalDeclarationBindInfo(Type signalType)
{
SignalType = signalType;
}
public object Identifier
{
get; set;
}
public Type SignalType
{
get; private set;
}
public bool RunAsync
{
get; set;
}
public int TickPriority
{
get; set;
}
public SignalMissingHandlerResponses MissingHandlerResponse
{
get; set;
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 1e83db91ff836874fb4fcf3ae4e16f0b
timeCreated: 1521277428
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,61 @@
using System.Collections.Generic;
namespace Zenject
{
[NoReflectionBaking]
public class SignalCopyBinder
{
readonly List<BindInfo> _bindInfos;
public SignalCopyBinder()
{
_bindInfos = new List<BindInfo>();
}
public SignalCopyBinder(BindInfo bindInfo)
{
_bindInfos = new List<BindInfo>
{
bindInfo
};
}
// This is used in cases where you have multiple bindings that depend on each other so should
// be inherited together
public void AddCopyBindInfo(BindInfo bindInfo)
{
_bindInfos.Add(bindInfo);
}
public void CopyIntoAllSubContainers()
{
SetInheritanceMethod(BindingInheritanceMethods.CopyIntoAll);
}
// Only copy the binding into children and not grandchildren
public void CopyIntoDirectSubContainers()
{
SetInheritanceMethod(BindingInheritanceMethods.CopyDirectOnly);
}
// Do not apply the binding on the current container
public void MoveIntoAllSubContainers()
{
SetInheritanceMethod(BindingInheritanceMethods.MoveIntoAll);
}
// Do not apply the binding on the current container
public void MoveIntoDirectSubContainers()
{
SetInheritanceMethod(BindingInheritanceMethods.MoveDirectOnly);
}
void SetInheritanceMethod(BindingInheritanceMethods method)
{
for (int i = 0; i < _bindInfos.Count; i++)
{
_bindInfos[i].BindingInheritanceMethod = method;
}
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 604fe2d23cc79c7498be851b6970af1b
timeCreated: 1521266917
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
using System;
namespace Zenject
{
public static class SignalExtensions
{
public static SignalDeclarationBindInfo CreateDefaultSignalDeclarationBindInfo(DiContainer container, Type signalType)
{
return new SignalDeclarationBindInfo(signalType)
{
RunAsync = container.Settings.Signals.DefaultSyncMode == SignalDefaultSyncModes.Asynchronous,
MissingHandlerResponse = container.Settings.Signals.MissingHandlerDefaultResponse,
TickPriority = container.Settings.Signals.DefaultAsyncTickPriority
};
}
public static DeclareSignalIdRequireHandlerAsyncTickPriorityCopyBinder DeclareSignal(this DiContainer container, Type type)
{
var signalBindInfo = CreateDefaultSignalDeclarationBindInfo(container, type);
var bindInfo = container.Bind<SignalDeclaration>().AsCached()
.WithArguments(signalBindInfo).WhenInjectedInto(typeof(SignalBus), typeof(SignalDeclarationAsyncInitializer)).BindInfo;
var signalBinder = new DeclareSignalIdRequireHandlerAsyncTickPriorityCopyBinder(signalBindInfo);
signalBinder.AddCopyBindInfo(bindInfo);
return signalBinder;
}
public static DeclareSignalIdRequireHandlerAsyncTickPriorityCopyBinder DeclareSignal<TSignal>(this DiContainer container)
{
return container.DeclareSignal(typeof(TSignal));
}
public static DeclareSignalIdRequireHandlerAsyncTickPriorityCopyBinder DeclareSignalWithInterfaces<TSignal>(this DiContainer container)
{
Type type = typeof(TSignal);
var declaration = container.DeclareSignal(type);
Type[] interfaces = type.GetInterfaces();
int numOfInterfaces = interfaces.Length;
for (int i = 0; i < numOfInterfaces; i++)
{
container.DeclareSignal(interfaces[i]);
}
return declaration;
}
public static BindSignalIdToBinder<TSignal> BindSignal<TSignal>(this DiContainer container)
{
var signalBindInfo = new SignalBindingBindInfo(typeof(TSignal));
return new BindSignalIdToBinder<TSignal>(container, signalBindInfo);
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: ca6f0ad40fd1abc4a8fb5e8a50134aa4
timeCreated: 1521266917
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,25 @@
namespace Zenject
{
[NoReflectionBaking]
public class SignalTickPriorityCopyBinder : SignalCopyBinder
{
public SignalTickPriorityCopyBinder(
SignalDeclarationBindInfo signalBindInfo)
{
SignalBindInfo = signalBindInfo;
}
protected SignalDeclarationBindInfo SignalBindInfo
{
get; private set;
}
public SignalCopyBinder WithTickPriority(int priority)
{
SignalBindInfo.TickPriority = priority;
SignalBindInfo.RunAsync = true;
return this;
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: fb1dbf2ad8637f340a532132f4555abd
timeCreated: 1529046908
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using ModestTree;
#if ZEN_SIGNALS_ADD_UNIRX
using UniRx;
#endif
namespace Zenject
{
public class SignalDeclaration : ITickable, IDisposable
{
readonly List<SignalSubscription> _subscriptions = new List<SignalSubscription>();
readonly List<object> _asyncQueue = new List<object>();
readonly BindingId _bindingId;
readonly SignalMissingHandlerResponses _missingHandlerResponses;
readonly bool _isAsync;
readonly ZenjectSettings.SignalSettings _settings;
#if ZEN_SIGNALS_ADD_UNIRX
readonly Subject<object> _stream = new Subject<object>();
#endif
public SignalDeclaration(
SignalDeclarationBindInfo bindInfo,
[InjectOptional]
ZenjectSettings zenjectSettings)
{
zenjectSettings = zenjectSettings ?? ZenjectSettings.Default;
_settings = zenjectSettings.Signals ?? ZenjectSettings.SignalSettings.Default;
_bindingId = new BindingId(bindInfo.SignalType, bindInfo.Identifier);
_missingHandlerResponses = bindInfo.MissingHandlerResponse;
_isAsync = bindInfo.RunAsync;
TickPriority = bindInfo.TickPriority;
}
#if ZEN_SIGNALS_ADD_UNIRX
public IObservable<object> Stream
{
get { return _stream; }
}
#endif
public List<SignalSubscription> Subscriptions => _subscriptions;
public int TickPriority
{
get; private set;
}
public bool IsAsync
{
get { return _isAsync; }
}
public BindingId BindingId
{
get { return _bindingId; }
}
public void Dispose()
{
if (_settings.RequireStrictUnsubscribe)
{
Assert.That(_subscriptions.IsEmpty(),
"Found {0} signal handlers still added to declaration {1}", _subscriptions.Count, _bindingId);
}
else
{
// We can't rely entirely on the destruction order in Unity because of
// the fact that OnDestroy is completely unpredictable.
// So if you have a GameObjectContext at the root level in your scene, then it
// might be destroyed AFTER the SceneContext. So if you have some signal declarations
// in the scene context, they might get disposed before some of the subscriptions
// so in this case you need to disconnect from the subscription so that it doesn't
// try to remove itself after the declaration has been destroyed
for (int i = 0; i < _subscriptions.Count; i++)
{
_subscriptions[i].OnDeclarationDespawned();
}
}
}
public void Fire(object signal)
{
Assert.That(signal.GetType().DerivesFromOrEqual(_bindingId.Type));
if (_isAsync)
{
_asyncQueue.Add(signal);
}
else
{
// Cache the callback list to allow handlers to be added from within callbacks
using (var block = DisposeBlock.Spawn())
{
var subscriptions = block.SpawnList<SignalSubscription>();
subscriptions.AddRange(_subscriptions);
FireInternal(subscriptions, signal);
}
}
}
void FireInternal(List<SignalSubscription> subscriptions, object signal)
{
if (subscriptions.IsEmpty()
#if ZEN_SIGNALS_ADD_UNIRX
&& !_stream.HasObservers
#endif
)
{
if (_missingHandlerResponses == SignalMissingHandlerResponses.Warn)
{
Log.Warn("Fired signal '{0}' but no subscriptions found! If this is intentional then either add OptionalSubscriber() to the binding or change the default in ZenjectSettings", signal.GetType());
}
else if (_missingHandlerResponses == SignalMissingHandlerResponses.Throw)
{
throw Assert.CreateException(
"Fired signal '{0}' but no subscriptions found! If this is intentional then either add OptionalSubscriber() to the binding or change the default in ZenjectSettings", signal.GetType());
}
}
for (int i = 0; i < subscriptions.Count; i++)
{
var subscription = subscriptions[i];
// This is a weird check for the very rare case where an Unsubscribe is called
// from within the same callback (see TestSignalsAdvanced.TestSubscribeUnsubscribeInsideHandler)
if (_subscriptions.Contains(subscription))
{
subscription.Invoke(signal);
}
}
#if ZEN_SIGNALS_ADD_UNIRX
_stream.OnNext(signal);
#endif
}
public void Tick()
{
Assert.That(_isAsync);
if (!_asyncQueue.IsEmpty())
{
// Cache the callback list to allow handlers to be added from within callbacks
using (var block = DisposeBlock.Spawn())
{
var subscriptions = block.SpawnList<SignalSubscription>();
subscriptions.AddRange(_subscriptions);
// Cache the signals so that if the signal is fired again inside the handler that it
// is not executed until next frame
var signals = block.SpawnList<object>();
signals.AddRange(_asyncQueue);
_asyncQueue.Clear();
for (int i = 0; i < signals.Count; i++)
{
FireInternal(subscriptions, signals[i]);
}
}
}
}
public void Add(SignalSubscription subscription)
{
Assert.That(!_subscriptions.Contains(subscription));
_subscriptions.Add(subscription);
}
public void Remove(SignalSubscription subscription)
{
_subscriptions.RemoveWithConfirm(subscription);
}
public class Factory : PlaceholderFactory<SignalDeclarationBindInfo, SignalDeclaration>
{
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 1246007cc9cfbc04cb83b9bde4c34995
timeCreated: 1521266917
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,82 @@
using System;
using System.Linq;
using ModestTree;
namespace Zenject
{
public class SignalSubscription : IDisposable, IPoolable<Action<object>, SignalDeclaration>
{
readonly Pool _pool;
Action<object> _callback;
SignalDeclaration _declaration;
BindingId _signalId;
public SignalSubscription(Pool pool)
{
_pool = pool;
SetDefaults();
}
public BindingId SignalId
{
get { return _signalId; }
}
public void OnSpawned(
Action<object> callback, SignalDeclaration declaration)
{
Assert.IsNull(_callback);
_callback = callback;
_declaration = declaration;
// Cache this in case OnDeclarationDespawned is called
_signalId = declaration.BindingId;
declaration.Add(this);
}
public void OnDespawned()
{
if (_declaration != null)
{
_declaration.Remove(this);
}
SetDefaults();
}
void SetDefaults()
{
_callback = null;
_declaration = null;
_signalId = new BindingId();
}
public void Dispose()
{
// Allow calling this twice since signals automatically unsubscribe in SignalBus.LateDispose
// and so this causes issues if users also unsubscribe in a MonoBehaviour OnDestroy on a
// root game object
if (!_pool.InactiveItems.Contains(this))
{
_pool.Despawn(this);
}
}
// See comment in SignalDeclaration for why this exists
public void OnDeclarationDespawned()
{
_declaration = null;
}
public void Invoke(object signal)
{
_callback(signal);
}
public class Pool : PoolableMemoryPool<Action<object>, SignalDeclaration, SignalSubscription>
{
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 26affab6a482d904580cce7f9f1a94f4
timeCreated: 1521266917
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,65 @@
using System;
using System.Diagnostics;
namespace Zenject
{
[DebuggerStepThrough]
public struct SignalSubscriptionId : IEquatable<SignalSubscriptionId>
{
BindingId _signalId;
object _callback;
public SignalSubscriptionId(BindingId signalId, object callback)
{
_signalId = signalId;
_callback = callback;
}
public BindingId SignalId
{
get { return _signalId; }
}
public object Callback
{
get { return _callback; }
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 29 + _signalId.GetHashCode();
hash = hash * 29 + _callback.GetHashCode();
return hash;
}
}
public override bool Equals(object that)
{
if (that is SignalSubscriptionId)
{
return Equals((SignalSubscriptionId)that);
}
return false;
}
public bool Equals(SignalSubscriptionId that)
{
return Equals(_signalId, that._signalId)
&& Equals(Callback, that.Callback);
}
public static bool operator == (SignalSubscriptionId left, SignalSubscriptionId right)
{
return left.Equals(right);
}
public static bool operator != (SignalSubscriptionId left, SignalSubscriptionId right)
{
return !left.Equals(right);
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 2ebf6df7998e59b4393ef46553665ba2
timeCreated: 1521266917
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: