From e92781c082475bb4b3baa3ae2d8688c05ad23fa4 Mon Sep 17 00:00:00 2001 From: marsermd Date: Sat, 19 Nov 2016 16:16:44 +0300 Subject: [PATCH 01/62] fixed Incomplete assert with unresolved generic dependency #172 --- UnityProject/Assets/Zenject/Source/Main/DiContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index c9b357c70..178088f3b 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -570,7 +570,7 @@ public object Resolve(InjectContext context) } throw Assert.CreateException("Unable to resolve type '{0}'{1}. \nObject graph:\n{2}", - context.MemberType.Name() + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), + context.MemberType + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType.Name())), context.GetObjectGraphString()); } From b4df69634e8fd28ee5cb351ccd1ec66c697ac3fb Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 2 Dec 2016 16:46:52 -0400 Subject: [PATCH 02/62] Tweak to readme --- Documentation/WritingAutomatedTests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/WritingAutomatedTests.md b/Documentation/WritingAutomatedTests.md index 38e72c6e7..4fb395290 100644 --- a/Documentation/WritingAutomatedTests.md +++ b/Documentation/WritingAutomatedTests.md @@ -175,7 +175,7 @@ public class TestLogger : ZenjectUnitTestFixture ### Integration Testss -Integration tests, on the other hand, are executed in a similar environment to the scenes in your project. A `SceneContext` and `ProjectContext` are created, so you can invoke MonoInstallers, ScriptableObjectInstallers, etc. as necessary. +Integration tests, on the other hand, are executed in a similar environment to the scenes in your project. Unlike ZenjectUnitTestFixture, a `SceneContext` and `ProjectContext` are created for each test, so your code will run in similar way that it would normally. For example, any bindings to IInitializable and IDisposable will be executed how you expect. Let's pull from the included sample project and test one of the classes there (AsteroidManager): From a741802ba402df2a55a0afbd5e8b2bb575aa3f18 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 2 Dec 2016 16:50:44 -0400 Subject: [PATCH 03/62] Changed zenject commands to have the command handler seperate from the command itself. This is a lot more flexible. It allows you to declare your commands in a higher level container and handle them in a lower level one. And also allows for multiple handlers of the same command. --- .../CommandsAndSignals/Command/Binders.meta | 9 - .../Command/Binders/CommandBinder0.cs | 75 ------ .../Command/Binders/CommandBinder1.cs | 77 ------ .../Command/Binders/CommandBinder2.cs | 78 ------ .../Command/Binders/CommandBinder3.cs | 79 ------ .../Command/Binders/CommandBinder4.cs | 80 ------ .../Command/Binders/CommandBinder4.cs.meta | 12 - .../Command/Binders/CommandBinder5.cs | 77 ------ .../Command/Binders/CommandBinder5.cs.meta | 12 - .../Command/Binders/CommandBinderBase.cs | 53 ---- .../Command/Binders/CommandBinderBase.cs.meta | 12 - .../Command/Binders/CommandExtensions.cs | 85 ------- .../Command/Binders/Finalizers.meta | 9 - .../Finalizers/CommandBindingFinalizer.cs | 226 ----------------- .../CommandBindingFinalizer.cs.meta | 12 - .../Finalizers/CommandBindingFinalizerBase.cs | 80 ------ .../CommandBindingFinalizerBase.cs.meta | 12 - .../CommandsAndSignals/Command/Command.cs | 153 ++---------- .../Command/Command.cs.meta | 4 +- .../Command/CommandExtensions.cs | 55 +++++ .../{Binders => }/CommandExtensions.cs.meta | 4 +- .../Command/CommandHandlerBase.cs | 42 ++++ ...er3.cs.meta => CommandHandlerBase.cs.meta} | 4 +- .../Command/CommandHandlerBinder.cs | 201 +++++++++++++++ ...1.cs.meta => CommandHandlerBinder.cs.meta} | 4 +- .../Command/CommandManager.cs | 45 ++++ ...Binder0.cs.meta => CommandManager.cs.meta} | 4 +- .../Command/ICommandHandler.cs | 11 + ...inder2.cs.meta => ICommandHandler.cs.meta} | 4 +- .../Command/InstanceMethodCommandHandler.cs | 131 ++++++++++ .../InstanceMethodCommandHandler.cs.meta | 12 + .../Command/StaticMethodCommandHandler.cs | 107 ++++++++ .../StaticMethodCommandHandler.cs.meta | 12 + .../UnitTests/Editor/Commands/TestCommands.cs | 131 ++++++++++ .../Editor/Commands/TestCommands.cs.meta | 12 + .../Editor/Commands/TestCommandsOne.cs | 208 ---------------- .../Editor/Commands/TestCommandsOne.cs.meta | 12 - .../Commands/TestCommandsWithParameters.cs | 178 ++++++++++++++ .../TestCommandsWithParameters.cs.meta | 12 + .../Editor/Commands/TestCommandsZero.cs | 232 ------------------ .../Editor/Commands/TestCommandsZero.cs.meta | 12 - 41 files changed, 986 insertions(+), 1592 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder0.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder1.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder2.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder3.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder4.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder4.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder5.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder5.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinderBase.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinderBase.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandExtensions.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizer.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizer.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizerBase.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizerBase.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs rename UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/{Binders => }/CommandExtensions.cs.meta (75%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs rename UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/{Binders/CommandBinder3.cs.meta => CommandHandlerBase.cs.meta} (75%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs rename UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/{Binders/CommandBinder1.cs.meta => CommandHandlerBinder.cs.meta} (75%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs rename UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/{Binders/CommandBinder0.cs.meta => CommandManager.cs.meta} (75%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs rename UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/{Binders/CommandBinder2.cs.meta => ICommandHandler.cs.meta} (75%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsOne.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsOne.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsZero.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsZero.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders.meta deleted file mode 100644 index 690efc47f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 56b5352d8edead742bd4fe697478af89 -folderAsset: yes -timeCreated: 1455426575 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder0.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder0.cs deleted file mode 100644 index f93b51db5..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder0.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; - -namespace Zenject -{ - // Zero parameters - public class CommandBinder : CommandBinderBase - where TCommand : Command - { - public CommandBinder(string identifier, DiContainer container) - : base(identifier, container) - { - } - - public ScopeArgBinder To(Func methodGetter) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new TransientProvider( - typeof(THandler), container, BindInfo.Arguments, BindInfo.ConcreteIdentifier, BindInfo.ContextInfo)); - - return new ScopeArgBinder(BindInfo); - } - - public ScopeBinder ToResolve(Func methodGetter) - { - return ToResolve(null, methodGetter); - } - - public ScopeBinder ToResolve( - string identifier, Func methodGetter) - { - return ToResolveInternal(identifier, methodGetter, false); - } - - public ScopeBinder ToOptionalResolve(Func methodGetter) - { - return ToOptionalResolve(null, methodGetter); - } - - public ScopeBinder ToOptionalResolve( - string identifier, Func methodGetter) - { - return ToResolveInternal(identifier, methodGetter, true); - } - - public ConditionBinder ToNothing() - { - return ToMethod(() => {}); - } - - // AsSingle / AsCached / etc. don't make sense in this case so just return ConditionBinder - public ConditionBinder ToMethod(Action action) - { - // Create the command class once and re-use it everywhere - Finalizer = new SingleProviderBindingFinalizer( - BindInfo, - (container, _) => new CachedProvider( - new TransientProvider( - typeof(TCommand), container, - InjectUtil.CreateArgListExplicit(action), null, BindInfo.ContextInfo))); - - return new ConditionBinder(BindInfo); - } - - ScopeBinder ToResolveInternal( - string identifier, Func methodGetter, bool optional) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new ResolveProvider(typeof(THandler), container, identifier, optional)); - - return new ScopeBinder(BindInfo); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder1.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder1.cs deleted file mode 100644 index 4eef4046e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder1.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; - -namespace Zenject -{ - // One parameter - public class CommandBinder : CommandBinderBase> - where TCommand : Command - { - public CommandBinder(string identifier, DiContainer container) - : base(identifier, container) - { - } - - public ScopeArgBinder To(Func> methodGetter) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, - methodGetter, - (container) => new TransientProvider( - typeof(THandler), container, BindInfo.Arguments, BindInfo.ConcreteIdentifier, BindInfo.ContextInfo)); - - return new ScopeArgBinder(BindInfo); - } - - public ScopeBinder ToResolve(Func> methodGetter) - { - return ToResolve(null, methodGetter); - } - - public ScopeBinder ToResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, false); - } - - public ScopeBinder ToOptionalResolve(Func> methodGetter) - { - return ToOptionalResolve(null, methodGetter); - } - - public ScopeBinder ToOptionalResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, true); - } - - public ConditionBinder ToNothing() - { - return ToMethod((p1) => {}); - } - - // AsSingle / AsCached / etc. don't make sense in this case so just return ConditionBinder - public ConditionBinder ToMethod(Action action) - { - // Create the command class once and re-use it everywhere - Finalizer = new SingleProviderBindingFinalizer( - BindInfo, - (container, _) => new CachedProvider( - new TransientProvider( - typeof(TCommand), container, - InjectUtil.CreateArgListExplicit(action), null, BindInfo.ContextInfo))); - - return new ConditionBinder(BindInfo); - } - - ScopeBinder ToResolveInternal( - string identifier, Func> methodGetter, bool optional) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new ResolveProvider(typeof(THandler), container, identifier, optional)); - - return new ScopeBinder(BindInfo); - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder2.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder2.cs deleted file mode 100644 index 8a25404d5..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder2.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; - -namespace Zenject -{ - // Two parameters - - public class CommandBinder : CommandBinderBase> - where TCommand : Command - { - public CommandBinder(string identifier, DiContainer container) - : base(identifier, container) - { - } - - public ScopeArgBinder To(Func> methodGetter) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new TransientProvider( - typeof(THandler), container, BindInfo.Arguments, BindInfo.ConcreteIdentifier, BindInfo.ContextInfo)); - - return new ScopeArgBinder(BindInfo); - } - - public ScopeBinder ToResolve(Func> methodGetter) - { - return ToResolve(null, methodGetter); - } - - public ScopeBinder ToResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, false); - } - - public ScopeBinder ToOptionalResolve(Func> methodGetter) - { - return ToOptionalResolve(null, methodGetter); - } - - public ScopeBinder ToOptionalResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, true); - } - - public ConditionBinder ToNothing() - { - return ToMethod((p1, p2) => {}); - } - - // AsSingle / AsCached / etc. don't make sense in this case so just return ConditionBinder - public ConditionBinder ToMethod(Action action) - { - // Create the command class once and re-use it everywhere - Finalizer = new SingleProviderBindingFinalizer( - BindInfo, - (container, _) => new CachedProvider( - new TransientProvider( - typeof(TCommand), container, - InjectUtil.CreateArgListExplicit(action), null, BindInfo.ContextInfo))); - - return new ConditionBinder(BindInfo); - } - - ScopeBinder ToResolveInternal( - string identifier, Func> methodGetter, bool optional) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new ResolveProvider(typeof(THandler), container, identifier, optional)); - - return new ScopeBinder(BindInfo); - } - } -} - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder3.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder3.cs deleted file mode 100644 index ca634ecd9..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder3.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; - -namespace Zenject -{ - // Three parameters - - public class CommandBinder : CommandBinderBase> - where TCommand : Command - { - public CommandBinder(string identifier, DiContainer container) - : base(identifier, container) - { - } - - public ScopeArgBinder To(Func> methodGetter) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new TransientProvider( - typeof(THandler), container, BindInfo.Arguments, BindInfo.ConcreteIdentifier, BindInfo.ContextInfo)); - - return new ScopeArgBinder(BindInfo); - } - - public ScopeBinder ToResolve(Func> methodGetter) - { - return ToResolve(null, methodGetter); - } - - public ScopeBinder ToResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, false); - } - - public ScopeBinder ToOptionalResolve(Func> methodGetter) - { - return ToOptionalResolve(null, methodGetter); - } - - public ScopeBinder ToOptionalResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, true); - } - - public ConditionBinder ToNothing() - { - return ToMethod((p1, p2, p3) => {}); - } - - // AsSingle / AsCached / etc. don't make sense in this case so just return ConditionBinder - public ConditionBinder ToMethod(Action action) - { - // Create the command class once and re-use it everywhere - Finalizer = new SingleProviderBindingFinalizer( - BindInfo, - (container, type) => new CachedProvider( - new TransientProvider( - typeof(TCommand), container, - InjectUtil.CreateArgListExplicit(action), null, BindInfo.ContextInfo))); - - return new ConditionBinder(BindInfo); - } - - ScopeBinder ToResolveInternal( - string identifier, Func> methodGetter, bool optional) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new ResolveProvider(typeof(THandler), container, identifier, optional)); - - return new ScopeBinder(BindInfo); - } - } -} - - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder4.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder4.cs deleted file mode 100644 index af449689a..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder4.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; - -namespace Zenject -{ - // Four parameters - - public class CommandBinder : CommandBinderBase> - where TCommand : Command - { - public CommandBinder(string identifier, DiContainer container) - : base(identifier, container) - { - } - - public ScopeArgBinder To(Func> methodGetter) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new TransientProvider( - typeof(THandler), container, BindInfo.Arguments, BindInfo.ConcreteIdentifier, BindInfo.ContextInfo)); - - return new ScopeArgBinder(BindInfo); - } - - public ScopeBinder ToResolve(Func> methodGetter) - { - return ToResolve(null, methodGetter); - } - - public ScopeBinder ToResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, false); - } - - public ScopeBinder ToOptionalResolve(Func> methodGetter) - { - return ToOptionalResolve(null, methodGetter); - } - - public ScopeBinder ToOptionalResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, true); - } - - public ConditionBinder ToNothing() - { - return ToMethod((p1, p2, p3, p4) => {}); - } - - // AsSingle / AsCached / etc. don't make sense in this case so just return ConditionBinder - public ConditionBinder ToMethod(Action action) - { - // Create the command class once and re-use it everywhere - Finalizer = new SingleProviderBindingFinalizer( - BindInfo, - (container, _) => new CachedProvider( - new TransientProvider( - typeof(TCommand), container, - InjectUtil.CreateArgListExplicit(action), null, BindInfo.ContextInfo))); - - return new ConditionBinder(BindInfo); - } - - ScopeBinder ToResolveInternal( - string identifier, Func> methodGetter, bool optional) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new ResolveProvider(typeof(THandler), container, identifier, optional)); - - return new ScopeBinder(BindInfo); - } - } -} - - - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder4.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder4.cs.meta deleted file mode 100644 index 54580f9a6..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder4.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 0d739cc2c990fff4db4d5e7368c34328 -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder5.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder5.cs deleted file mode 100644 index b54bdfb9d..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder5.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; - -namespace Zenject -{ - // Five parameters - - public class CommandBinder : CommandBinderBase> - where TCommand : Command - { - public CommandBinder(string identifier, DiContainer container) - : base(identifier, container) - { - } - - public ScopeArgBinder To(Func> methodGetter) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new TransientProvider( - typeof(THandler), container, BindInfo.Arguments, BindInfo.ConcreteIdentifier, BindInfo.ContextInfo)); - - return new ScopeArgBinder(BindInfo); - } - - public ScopeBinder ToResolve(Func> methodGetter) - { - return ToResolve(null, methodGetter); - } - - public ScopeBinder ToResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, false); - } - - public ScopeBinder ToOptionalResolve(Func> methodGetter) - { - return ToOptionalResolve(null, methodGetter); - } - - public ScopeBinder ToOptionalResolve( - string identifier, Func> methodGetter) - { - return ToResolveInternal(identifier, methodGetter, true); - } - - public ConditionBinder ToNothing() - { - return ToMethod((p1, p2, p3, p4, p5) => {}); - } - - // AsSingle / AsCached / etc. don't make sense in this case so just return ConditionBinder - public ConditionBinder ToMethod(ModestTree.Util.Action action) - { - // Create the command class once and re-use it everywhere - Finalizer = new SingleProviderBindingFinalizer( - BindInfo, - (container, _) => new CachedProvider( - new TransientProvider( - typeof(TCommand), container, - InjectUtil.CreateArgListExplicit(action), null, BindInfo.ContextInfo))); - - return new ConditionBinder(BindInfo); - } - - ScopeBinder ToResolveInternal( - string identifier, Func> methodGetter, bool optional) - { - Finalizer = new CommandBindingFinalizer( - BindInfo, methodGetter, - (container) => new ResolveProvider(typeof(THandler), container, identifier, optional)); - - return new ScopeBinder(BindInfo); - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder5.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder5.cs.meta deleted file mode 100644 index 0dabf869c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder5.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: af7bad27ce6b3a247b407a9c99350116 -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinderBase.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinderBase.cs deleted file mode 100644 index 02c3ba694..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinderBase.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Zenject -{ - public class CommandBinderBase - where TCommand : ICommand - where TAction : class - { - readonly DiContainer _container; - readonly BindFinalizerWrapper _finalizerWrapper; - readonly BindInfo _bindInfo; - - public CommandBinderBase(string identifier, DiContainer container) - { - _container = container; - - _bindInfo = new BindInfo(); - _bindInfo.Identifier = identifier; - _bindInfo.ContractTypes = new List() - { - typeof(TCommand), - }; - - _finalizerWrapper = container.StartBinding(); - } - - protected BindInfo BindInfo - { - get - { - return _bindInfo; - } - } - - protected IBindingFinalizer Finalizer - { - set - { - _finalizerWrapper.SubFinalizer = value; - } - } - - protected DiContainer Container - { - get - { - return _container; - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinderBase.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinderBase.cs.meta deleted file mode 100644 index a38887a08..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinderBase.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: ab01da3d5a2fe474eb3d1310dd02c99e -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandExtensions.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandExtensions.cs deleted file mode 100644 index 7fa1e2d7e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandExtensions.cs +++ /dev/null @@ -1,85 +0,0 @@ -namespace Zenject -{ - public static class CommandExtensions - { - // Zero parameters - public static CommandBinder BindCommand(this DiContainer container, string identifier) - where TCommand : Command - { - return new CommandBinder(identifier, container); - } - - public static CommandBinder BindCommand(this DiContainer container) - where TCommand : Command - { - return BindCommand(container, null); - } - - // One parameter - public static CommandBinder BindCommand(this DiContainer container, string identifier) - where TCommand : Command - { - return new CommandBinder(identifier, container); - } - - public static CommandBinder BindCommand(this DiContainer container) - where TCommand : Command - { - return BindCommand(container, null); - } - - // Two parameters - - public static CommandBinder BindCommand(this DiContainer container, string identifier) - where TCommand : Command - { - return new CommandBinder(identifier, container); - } - - public static CommandBinder BindCommand(this DiContainer container) - where TCommand : Command - { - return BindCommand(container, null); - } - - // Three parameters - public static CommandBinder BindCommand(this DiContainer container, string identifier) - where TCommand : Command - { - return new CommandBinder(identifier, container); - } - - public static CommandBinder BindCommand(this DiContainer container) - where TCommand : Command - { - return BindCommand(container, null); - } - - // Four parameters - public static CommandBinder BindCommand(this DiContainer container, string identifier) - where TCommand : Command - { - return new CommandBinder(identifier, container); - } - - public static CommandBinder BindCommand(this DiContainer container) - where TCommand : Command - { - return BindCommand(container, null); - } - - // Five parameters - public static CommandBinder BindCommand(this DiContainer container, string identifier) - where TCommand : Command - { - return new CommandBinder(identifier, container); - } - - public static CommandBinder BindCommand(this DiContainer container) - where TCommand : Command - { - return BindCommand(container, null); - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers.meta deleted file mode 100644 index 14edc0b0e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 10c9d62384e4d0b468def569fbf016e5 -folderAsset: yes -timeCreated: 1461712383 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizer.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizer.cs deleted file mode 100644 index 4557c21b4..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizer.cs +++ /dev/null @@ -1,226 +0,0 @@ -using System; - -namespace Zenject -{ - // Zero parameter - - public class CommandBindingFinalizer - : CommandBindingFinalizerBase - where TCommand : Command - { - readonly Func _methodGetter; - - public CommandBindingFinalizer( - BindInfo bindInfo, - Func methodGetter, Func handlerProviderFactory) - : base(bindInfo, handlerProviderFactory) - { - _methodGetter = methodGetter; - } - - // The returned delegate is executed every time the command is executed - protected override Action GetCommandAction( - IProvider handlerProvider, InjectContext handlerInjectContext) - { - // Here we lazily create/get the handler instance when the command is called - // If using AsSingle this might re-use an existing instance - // If using AsTransient this will create a new instance - return () => - { - var handler = handlerProvider.TryGetInstance(handlerInjectContext); - - // Null check is necessary when using ToOptionalResolve - if (handler != null && !(handler is ValidationMarker)) - { - _methodGetter((THandler)handler)(); - } - }; - } - } - - // One parameter - - public class CommandBindingFinalizer - : CommandBindingFinalizerBase> - where TCommand : Command - { - readonly Func> _methodGetter; - - public CommandBindingFinalizer( - BindInfo bindInfo, - Func> methodGetter, - Func handlerProviderFactory) - : base(bindInfo, handlerProviderFactory) - { - _methodGetter = methodGetter; - } - - // The returned delegate is executed every time the command is executed - protected override Action GetCommandAction( - IProvider handlerProvider, InjectContext handlerInjectContext) - { - // Here we lazily create/get the handler instance when the command is called - // If using AsSingle this might re-use an existing instance - // If using AsTransient this will create a new instance - return (p1) => - { - var handler = handlerProvider.TryGetInstance(handlerInjectContext); - - // Null check is necessary when using ToOptionalResolve - if (handler != null && !(handler is ValidationMarker)) - { - _methodGetter((THandler)handler)(p1); - } - }; - } - } - - // Two parameters - - public class CommandBindingFinalizer - : CommandBindingFinalizerBase> - where TCommand : Command - { - readonly Func> _methodGetter; - - public CommandBindingFinalizer( - BindInfo bindInfo, - Func> methodGetter, - Func handlerProviderFactory) - : base(bindInfo, handlerProviderFactory) - { - _methodGetter = methodGetter; - } - - // The returned delegate is executed every time the command is executed - protected override Action GetCommandAction( - IProvider handlerProvider, InjectContext handlerInjectContext) - { - // Here we lazily create/get the handler instance when the command is called - // If using AsSingle this might re-use an existing instance - // If using AsTransient this will create a new instance - return (p1, p2) => - { - var handler = handlerProvider.TryGetInstance(handlerInjectContext); - - // Null check is necessary when using ToOptionalResolve - if (handler != null && !(handler is ValidationMarker)) - { - _methodGetter((THandler)handler)(p1, p2); - } - }; - } - } - - // Three parameters - - public class CommandBindingFinalizer - : CommandBindingFinalizerBase> - where TCommand : Command - { - readonly Func> _methodGetter; - - public CommandBindingFinalizer( - BindInfo bindInfo, - Func> methodGetter, - Func handlerProviderFactory) - : base(bindInfo, handlerProviderFactory) - { - _methodGetter = methodGetter; - } - - // The returned delegate is executed every time the command is executed - protected override Action GetCommandAction( - IProvider handlerProvider, InjectContext handlerInjectContext) - { - // Here we lazily create/get the handler instance when the command is called - // If using AsSingle this might re-use an existing instance - // If using AsTransient this will create a new instance - return (p1, p2, p3) => - { - var handler = handlerProvider.TryGetInstance(handlerInjectContext); - - // Null check is necessary when using ToOptionalResolve - if (handler != null && !(handler is ValidationMarker)) - { - _methodGetter((THandler)handler)(p1, p2, p3); - } - }; - } - } - - // Four parameters - - public class CommandBindingFinalizer - : CommandBindingFinalizerBase> - where TCommand : Command - { - readonly Func> _methodGetter; - - public CommandBindingFinalizer( - BindInfo bindInfo, - Func> methodGetter, - Func handlerProviderFactory) - : base(bindInfo, handlerProviderFactory) - { - _methodGetter = methodGetter; - } - - // The returned delegate is executed every time the command is executed - protected override Action GetCommandAction( - IProvider handlerProvider, InjectContext handlerInjectContext) - { - // Here we lazily create/get the handler instance when the command is called - // If using AsSingle this might re-use an existing instance - // If using AsTransient this will create a new instance - return (p1, p2, p3, p4) => - { - var handler = handlerProvider.TryGetInstance(handlerInjectContext); - - // Null check is necessary when using ToOptionalResolve - if (handler != null && !(handler is ValidationMarker)) - { - _methodGetter((THandler)handler)(p1, p2, p3, p4); - } - }; - } - } - - // Five parameters - - public class CommandBindingFinalizer - : CommandBindingFinalizerBase> - where TCommand : Command - { - readonly Func> _methodGetter; - - public CommandBindingFinalizer( - BindInfo bindInfo, - Func> methodGetter, - Func handlerProviderFactory) - : base(bindInfo, handlerProviderFactory) - { - _methodGetter = methodGetter; - } - - // The returned delegate is executed every time the command is executed - protected override ModestTree.Util.Action GetCommandAction( - IProvider handlerProvider, InjectContext handlerInjectContext) - { - // Here we lazily create/get the handler instance when the command is called - // If using AsSingle this might re-use an existing instance - // If using AsTransient this will create a new instance - return (p1, p2, p3, p4, p5) => - { - var handler = handlerProvider.TryGetInstance(handlerInjectContext); - - // Null check is necessary when using ToOptionalResolve - if (handler != null && !(handler is ValidationMarker)) - { - _methodGetter((THandler)handler)(p1, p2, p3, p4, p5); - } - }; - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizer.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizer.cs.meta deleted file mode 100644 index 6d27d5cf2..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizer.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 12f73727464cfc24da2970ad2d2188d6 -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizerBase.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizerBase.cs deleted file mode 100644 index b215c3263..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizerBase.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using ModestTree; -using System.Linq; - -namespace Zenject -{ - // Zero Parameters - - public abstract class CommandBindingFinalizerBase - : ProviderBindingFinalizer - where TCommand : ICommand - { - readonly Func _handlerProviderFactory; - - public CommandBindingFinalizerBase( - BindInfo bindInfo, - Func handlerProviderFactory) - : base(bindInfo) - { - _handlerProviderFactory = handlerProviderFactory; - } - - protected override void OnFinalizeBinding(DiContainer container) - { - Assert.That(BindInfo.ContractTypes.IsLength(1)); - Assert.IsEqual(BindInfo.ContractTypes.Single(), typeof(TCommand)); - - // Note that the singleton here applies to the handler, not the command class - // The command itself is always cached - RegisterProvider( - container, - new CachedProvider( - new TransientProvider( - typeof(TCommand), container, - InjectUtil.CreateArgListExplicit(GetCommandAction(container)), null, BindInfo.ContextInfo))); - } - - // The returned delegate is executed every time the command is executed - TAction GetCommandAction(DiContainer container) - { - var handlerProvider = GetHandlerProvider(container); - var handlerInjectContext = new InjectContext(container, typeof(THandler)); - - return GetCommandAction(handlerProvider, handlerInjectContext); - } - - IProvider GetHandlerProvider(DiContainer container) - { - switch (BindInfo.Scope) - { - case ScopeTypes.Singleton: - { - return container.SingletonProviderCreator.CreateProviderStandard( - new StandardSingletonDeclaration( - typeof(THandler), - BindInfo.ConcreteIdentifier, - BindInfo.Arguments, - SingletonTypes.To, - null), - (_, type) => _handlerProviderFactory(container)); - } - case ScopeTypes.Transient: - { - return _handlerProviderFactory(container); - } - case ScopeTypes.Cached: - { - return new CachedProvider( - _handlerProviderFactory(container)); - } - } - - throw Assert.CreateException(); - } - - protected abstract TAction GetCommandAction( - IProvider handlerProvider, InjectContext handlerContext); - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizerBase.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizerBase.cs.meta deleted file mode 100644 index 05acb612a..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/Finalizers/CommandBindingFinalizerBase.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: efc03bfd8035da84cac351da71754730 -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs index 2c512b036..53b65ba97 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using ModestTree; namespace Zenject @@ -7,171 +8,67 @@ public interface ICommand { } - // Zero params - [ZenjectAllowDuringValidationAttribute] - public abstract class Command : ICommand + public abstract class CommandBase : ICommand { - Action _handler; + CommandManager _manager; [Inject] - public void Construct(Action handler, DiContainer container) + void Construct(CommandManager manager) { - _handler = handler; - - if (container.IsValidating) - // During validation, we want to instantiate whatever class we're calling immediately - { - handler(); - } + _manager = manager; } - public void Execute() + protected CommandManager Manager { - _handler(); + get { return _manager; } } - } - - // One param - [ZenjectAllowDuringValidationAttribute] - public abstract class Command : ICommand - { - Action _handler; - [Inject] - public void Construct(Action handler, DiContainer container) + public bool HasHandler { - _handler = handler; - - if (container.IsValidating) - // During validation, we want to instantiate whatever class we're calling immediately + get { - handler(default(TParam1)); + return _manager.IsHandlerRegistered(this.GetType()); } } - - public void Execute(TParam1 param1) - { - _handler(param1); - } } - // Two params - [ZenjectAllowDuringValidationAttribute] - public abstract class Command : ICommand + public abstract class Command : CommandBase { - Action _handler; - - [Inject] - public void Construct(Action handler, DiContainer container) - { - _handler = handler; - - if (container.IsValidating) - // During validation, we want to instantiate whatever class we're calling immediately - { - handler(default(TParam1), default(TParam2)); - } - } - - public void Execute(TParam1 param1, TParam2 param2) + public void Execute() { - _handler(param1, param2); + Manager.Trigger(this.GetType(), new object[0]); } } - // Three params - [ZenjectAllowDuringValidationAttribute] - public abstract class Command : ICommand + public abstract class Command : CommandBase { - Action _handler; - - [Inject] - public void Construct(Action handler, DiContainer container) - { - _handler = handler; - - if (container.IsValidating) - // During validation, we want to instantiate whatever class we're calling immediately - { - handler(default(TParam1), default(TParam2), default(TParam3)); - } - } - - public void Execute(TParam1 param1, TParam2 param2, TParam3 param3) + public void Execute(TParam1 param1) { - _handler(param1, param2, param3); + Manager.Trigger(this.GetType(), new object[] { param1 }); } } - // Four params - [ZenjectAllowDuringValidationAttribute] - public abstract class Command : ICommand + public abstract class Command : CommandBase { - Action _handler; - - [Inject] - public void Construct(Action handler, DiContainer container) - { - _handler = handler; - - if (container.IsValidating) - // During validation, we want to instantiate whatever class we're calling immediately - { - handler(default(TParam1), default(TParam2), default(TParam3), default(TParam4)); - } - } - - public void Execute(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) + public void Execute(TParam1 param1, TParam2 param2) { - _handler(param1, param2, param3, param4); + Manager.Trigger(this.GetType(), new object[] { param1, param2 }); } } - // Five params - [ZenjectAllowDuringValidationAttribute] - public abstract class Command : ICommand + public abstract class Command : CommandBase { - ModestTree.Util.Action _handler; - - [Inject] - public void Construct(ModestTree.Util.Action handler, DiContainer container) - { - _handler = handler; - - if (container.IsValidating) - // During validation, we want to instantiate whatever class we're calling immediately - { - handler(default(TParam1), default(TParam2), default(TParam3), default(TParam4), default(TParam5)); - } - } - - public void Execute(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5) + public void Execute(TParam1 param1, TParam2 param2, TParam3 param3) { - _handler(param1, param2, param3, param4, param5); + Manager.Trigger(this.GetType(), new object[] { param1, param2, param3 }); } } - // Six params - [ZenjectAllowDuringValidationAttribute] - public abstract class Command : ICommand + public abstract class Command : CommandBase { - ModestTree.Util.Action _handler; - - [Inject] - public void Construct(ModestTree.Util.Action handler, DiContainer container) - { - _handler = handler; - - if (container.IsValidating) - // During validation, we want to instantiate whatever class we're calling immediately - { - handler(default(TParam1), default(TParam2), default(TParam3), default(TParam4), default(TParam5), default(TParam6)); - } - } - - public void Execute(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5, TParam6 param6) + public void Execute(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) { - _handler(param1, param2, param3, param4, param5, param6); + Manager.Trigger(this.GetType(), new object[] { param1, param2, param3, param4 }); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs.meta index be1152463..17c6139a5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 2fd2a32a7cb36664cb3a6f05b1ba9bca -timeCreated: 1455426578 +guid: 81019001810e20b4e87aa6761a4700c2 +timeCreated: 1480006190 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs new file mode 100644 index 000000000..9820b2074 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public static class CommandExtensions + { + public static ConditionBinder DeclareCommand(this DiContainer container) + where T : ICommand + { + return container.Bind().AsSingle(); + } + + public static CommandHandlerBinder ImplementCommand(this DiContainer container) + where TCommand : Command + { + var binder = container.StartBinding(); + return new CommandHandlerBinder( + container, typeof(TCommand), binder); + } + + public static CommandHandlerBinder ImplementCommand(this DiContainer container) + where TCommand : Command + { + var binder = container.StartBinding(); + return new CommandHandlerBinder( + container, typeof(TCommand), binder); + } + + public static CommandHandlerBinder ImplementCommand(this DiContainer container) + where TCommand : Command + { + var binder = container.StartBinding(); + return new CommandHandlerBinder( + container, typeof(TCommand), binder); + } + + public static CommandHandlerBinder ImplementCommand(this DiContainer container) + where TCommand : Command + { + var binder = container.StartBinding(); + return new CommandHandlerBinder( + container, typeof(TCommand), binder); + } + + public static CommandHandlerBinder ImplementCommand(this DiContainer container) + where TCommand : Command + { + var binder = container.StartBinding(); + return new CommandHandlerBinder( + container, typeof(TCommand), binder); + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandExtensions.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs.meta similarity index 75% rename from UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandExtensions.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs.meta index e918719cc..08e616c24 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandExtensions.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 91be634054ede394caf00c38b4e1eee8 -timeCreated: 1455426579 +guid: 02d0b8e2a54788f45ab48bcbd031228c +timeCreated: 1480012313 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs new file mode 100644 index 000000000..f592dde56 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public abstract class CommandHandlerBase : ICommandHandler, IDisposable + { + readonly CommandManager _manager; + readonly Type _commandType; + + public CommandHandlerBase( + Type commandType, CommandManager manager) + { + _manager = manager; + _commandType = commandType; + + manager.Register(commandType, this); + } + + public void Dispose() + { + _manager.Unregister(_commandType); + } + + protected void ValidateParameter(object value) + { + if (value == null) + { + Assert.That(!typeof(T).IsValueType); + } + else + { + Assert.That(value.GetType().DerivesFromOrEqual()); + } + } + + public abstract void Execute(object[] args); + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder3.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs.meta similarity index 75% rename from UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder3.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs.meta index 751a87382..f3ebdb39f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder3.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 7ab250966963d2046935d31e38f6e35c -timeCreated: 1461712384 +guid: 4cd8e640deda28641b1bb9a9f523256a +timeCreated: 1480706613 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs new file mode 100644 index 000000000..3eaf923b0 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs @@ -0,0 +1,201 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class CommandHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _commandType; + readonly DiContainer _container; + + public CommandHandlerBinder( + DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _commandType = commandType; + _finalizerWrapper = finalizerWrapper; + } + + public FromBinder By(Func methodGetter) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, methodGetter, lazyLookup); + + return _container.Bind().WithId(lookupId).To(); + } + + public void ByMethod(Action method) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IDisposable)).To().AsCached() + .WithArguments(_commandType, method); + } + } + + public class CommandHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _commandType; + readonly DiContainer _container; + + public CommandHandlerBinder( + DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _commandType = commandType; + _finalizerWrapper = finalizerWrapper; + } + + public FromBinder By(Func> methodGetter) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); + + return _container.Bind().WithId(lookupId).To(); + } + + public void ByMethod(Action method) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, method); + } + } + + public class CommandHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _commandType; + readonly DiContainer _container; + + public CommandHandlerBinder( + DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _commandType = commandType; + _finalizerWrapper = finalizerWrapper; + } + + public FromBinder By(Func> methodGetter) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); + + return _container.Bind().WithId(lookupId).To(); + } + + public void ByMethod(Action method) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, method); + } + } + + public class CommandHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _commandType; + readonly DiContainer _container; + + public CommandHandlerBinder( + DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _commandType = commandType; + _finalizerWrapper = finalizerWrapper; + } + + public FromBinder By(Func> methodGetter) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); + + return _container.Bind().WithId(lookupId).To(); + } + + public void ByMethod(Action method) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, method); + } + } + + public class CommandHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _commandType; + readonly DiContainer _container; + + public CommandHandlerBinder( + DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _commandType = commandType; + _finalizerWrapper = finalizerWrapper; + } + + public FromBinder By(Func> methodGetter) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); + + return _container.Bind().WithId(lookupId).To(); + } + + public void ByMethod(Action method) + { + // This is just to ensure they don't stop at ImplementCommand + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IDisposable)).To>().AsCached() + .WithArguments(_commandType, method); + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs.meta similarity index 75% rename from UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder1.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs.meta index f78dc1af5..c785adb29 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder1.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 593c8d8bf1f74c74b8ec53e1ed8ed499 -timeCreated: 1461712384 +guid: 17b540f4075a55d44889601f66821dc2 +timeCreated: 1480710172 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs new file mode 100644 index 000000000..2c84fb335 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class CommandManager : ILateDisposable + { + readonly Dictionary _commandHandlers = new Dictionary(); + + public bool IsHandlerRegistered(Type commandType) + { + return _commandHandlers.ContainsKey(commandType); + } + + public void Register(Type commandType, ICommandHandler handler) + { + _commandHandlers.Add(commandType, handler); + } + + public void Unregister(Type commandType) + { + _commandHandlers.RemoveWithConfirm(commandType); + } + + public void LateDispose() + { + Assert.That(_commandHandlers.IsEmpty()); + } + + public void Trigger(Type commandType, object[] args) + { + ICommandHandler handler; + + if (!_commandHandlers.TryGetValue(commandType, out handler)) + { + Log.Warn("Fired command '{0}' but no handler was registered!", commandType); + return; + } + + handler.Execute(args); + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs.meta similarity index 75% rename from UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder0.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs.meta index c6064ab88..ef0769175 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder0.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 90a643e82584c584793fdb9dcfc3108c -timeCreated: 1455426579 +guid: 18b734cfb9aee23448ab1e049882b546 +timeCreated: 1480012314 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs new file mode 100644 index 000000000..086b0bf54 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public interface ICommandHandler + { + void Execute(object[] args); + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder2.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs.meta similarity index 75% rename from UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder2.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs.meta index 2dc57e15e..0a70117d6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Binders/CommandBinder2.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: ff31b272f5da4014a835ead31ec7a640 -timeCreated: 1461712384 +guid: 42eaebfe8b6a42f4295b971b28e3e8e7 +timeCreated: 1480012314 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs new file mode 100644 index 000000000..0343a1033 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public abstract class InstanceMethodCommandHandlerBase : CommandHandlerBase + { + readonly Lazy _handler; + + public InstanceMethodCommandHandlerBase( + Type commandType, CommandManager manager, + Lazy handler) + : base(commandType, manager) + { + _handler = handler; + } + + public override void Execute(object[] args) + { + InternalExecute(_handler.Value, args); + } + + protected abstract void InternalExecute(THandler handler, object[] args); + } + + public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase + { + readonly Func _methodGetter; + + public InstanceMethodCommandHandler( + Type commandType, CommandManager manager, Lazy handler, + Func methodGetter) + : base(commandType, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsEmpty()); + _methodGetter(handler)(); + } + } + + public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase + { + readonly Func> _methodGetter; + + public InstanceMethodCommandHandler( + Type commandType, CommandManager manager, Lazy handler, + Func> methodGetter) + : base(commandType, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + _methodGetter(handler)((TParam1)args[0]); + } + } + + public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase + { + readonly Func> _methodGetter; + + public InstanceMethodCommandHandler( + Type commandType, CommandManager manager, Lazy handler, + Func> methodGetter) + : base(commandType, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsLength(2)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + _methodGetter(handler)((TParam1)args[0], (TParam2)args[1]); + } + } + + public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase + { + readonly Func> _methodGetter; + + public InstanceMethodCommandHandler( + Type commandType, CommandManager manager, Lazy handler, + Func> methodGetter) + : base(commandType, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsLength(3)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + ValidateParameter(args[2]); + _methodGetter(handler)((TParam1)args[0], (TParam2)args[1], (TParam3)args[2]); + } + } + + public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase + { + readonly Func> _methodGetter; + + public InstanceMethodCommandHandler( + Type commandType, CommandManager manager, Lazy handler, + Func> methodGetter) + : base(commandType, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsLength(4)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + ValidateParameter(args[2]); + ValidateParameter(args[3]); + _methodGetter(handler)((TParam1)args[0], (TParam2)args[1], (TParam3)args[2], (TParam4)args[3]); + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs.meta new file mode 100644 index 000000000..ca25c09f0 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bfd160dc5b2a55749a48efad7ce2f5f5 +timeCreated: 1480706613 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs new file mode 100644 index 000000000..bbfe5aee1 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class StaticMethodCommandHandler : CommandHandlerBase + { + readonly Action _method; + + public StaticMethodCommandHandler( + Type commandType, CommandManager manager, Action method) + : base(commandType, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsEmpty()); + _method(); + } + } + + public class StaticMethodCommandHandler : CommandHandlerBase + { + readonly Action _method; + + public StaticMethodCommandHandler( + Type commandType, CommandManager manager, Action method) + : base(commandType, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + _method((TParam1)args[0]); + } + } + + public class StaticMethodCommandHandler : CommandHandlerBase + { + readonly Action _method; + + public StaticMethodCommandHandler( + Type commandType, CommandManager manager, Action method) + : base(commandType, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + _method((TParam1)args[0], (TParam2)args[1]); + } + } + + public class StaticMethodCommandHandler : CommandHandlerBase + { + readonly Action _method; + + public StaticMethodCommandHandler( + Type commandType, CommandManager manager, Action method) + : base(commandType, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + ValidateParameter(args[2]); + _method((TParam1)args[0], (TParam2)args[1], (TParam3)args[2]); + } + } + + public class StaticMethodCommandHandler : CommandHandlerBase + { + readonly Action _method; + + public StaticMethodCommandHandler( + Type commandType, CommandManager manager, Action method) + : base(commandType, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + ValidateParameter(args[2]); + ValidateParameter(args[3]); + _method((TParam1)args[0], (TParam2)args[1], (TParam3)args[2], (TParam4)args[3]); + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs.meta new file mode 100644 index 000000000..5221de578 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 580e348b9ad6fb547b573960c6eda204 +timeCreated: 1480706613 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs new file mode 100644 index 000000000..afbfa7986 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace Zenject.Tests +{ + [TestFixture] + public class TestCommands : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindAllInterfacesAndSelf().To().AsSingle(); + } + + [Test] + public void TestToSingle1() + { + Bar.WasTriggered = false; + Bar.InstanceCount = 0; + + Container.Bind().AsSingle(); + + Container.DeclareCommand(); + Container.ImplementCommand() + .By(x => x.Execute).AsSingle(); + + Initialize(); + + Container.Resolve(); + var cmd = Container.Resolve(); + + Assert.IsEqual(Bar.InstanceCount, 1); + Assert.That(!Bar.WasTriggered); + + cmd.Execute(); + + Assert.That(Bar.WasTriggered); + Assert.IsEqual(Bar.InstanceCount, 1); + } + + [Test] + public void TestToCached1() + { + Bar.WasTriggered = false; + Bar.InstanceCount = 0; + + Container.Bind().AsCached(); + + Container.DeclareCommand(); + Container.ImplementCommand() + .By(x => x.Execute).AsCached(); + + Initialize(); + + Container.Resolve(); + var cmd = Container.Resolve(); + + Assert.IsEqual(Bar.InstanceCount, 1); + Assert.That(!Bar.WasTriggered); + + cmd.Execute(); + + Assert.That(Bar.WasTriggered); + Assert.IsEqual(Bar.InstanceCount, 2); + + cmd.Execute(); + Assert.IsEqual(Bar.InstanceCount, 2); + } + + [Test] + public void TestToNothingHandler() + { + Container.DeclareCommand(); + + Initialize(); + + var cmd = Container.Resolve(); + cmd.Execute(); + } + + [Test] + public void TestToMethod() + { + bool wasCalled = false; + + Container.DeclareCommand(); + Container.ImplementCommand() + .ByMethod(() => wasCalled = true); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.That(!wasCalled); + cmd.Execute(); + Assert.That(wasCalled); + } + + public class DoSomethingCommand : Command + { + } + + public class Bar + { + public static int InstanceCount = 0; + + public Bar() + { + InstanceCount ++; + } + + public static bool WasTriggered + { + get; + set; + } + + public void Execute() + { + WasTriggered = true; + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs.meta new file mode 100644 index 000000000..59dcb0e05 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: be0ac5028ebaac948a2cc3c1b0c556fe +timeCreated: 1480710679 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsOne.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsOne.cs deleted file mode 100644 index 0dbaea43f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsOne.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestCommandsOne : ZenjectUnitTestFixture - { - [Test] - public void TestToSingle1() - { - Bar.Value = null; - Bar.InstanceCount = 0; - - Container.Bind().AsSingle(); - - Container.BindCommand() - .To(x => x.Execute).AsSingle(); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.IsEqual(Bar.InstanceCount, 1); - Assert.IsNull(Bar.Value); - - cmd.Execute("asdf"); - - Assert.IsEqual(Bar.Value, "asdf"); - Assert.IsEqual(Bar.InstanceCount, 1); - } - - [Test] - public void TestToTransient1() - { - Bar.Value = null; - Bar.InstanceCount = 0; - - Container.BindCommand() - .To(x => x.Execute).AsTransient(); - - var cmd = Container.Resolve(); - - Assert.IsEqual(Bar.InstanceCount, 0); - Assert.IsNull(Bar.Value); - - cmd.Execute("asdf"); - - Assert.IsEqual(Bar.Value, "asdf"); - Assert.IsEqual(Bar.InstanceCount, 1); - - Bar.Value = null; - - cmd.Execute("zxcv"); - - Assert.IsEqual(Bar.InstanceCount, 2); - Assert.IsEqual(Bar.Value, "zxcv"); - } - - [Test] - public void TestToCached1() - { - Bar.Value = null; - Bar.InstanceCount = 0; - - Container.Bind().AsCached(); - - Container.BindCommand() - .To(x => x.Execute).AsCached(); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.IsEqual(Bar.InstanceCount, 1); - Assert.IsNull(Bar.Value); - - cmd.Execute("asdf"); - - Assert.IsEqual(Bar.Value, "asdf"); - Assert.IsEqual(Bar.InstanceCount, 2); - - Bar.Value = null; - cmd.Execute("zxcv"); - - Assert.IsEqual(Bar.Value, "zxcv"); - Assert.IsEqual(Bar.InstanceCount, 2); - } - - [Test] - public void TestToResolveMethod() - { - Bar.Value = null; - Bar.InstanceCount = 0; - - Container.Bind().AsSingle(); - - Container.BindCommand() - .ToResolve(x => x.Execute); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.IsNull(Bar.Value); - - cmd.Execute("asdf"); - - Assert.IsEqual(Bar.Value, "asdf"); - Assert.IsEqual(Bar.InstanceCount, 1); - } - - [Test] - public void TestToOptionalResolveMethod1() - { - Bar.Value = null; - Bar.InstanceCount = 0; - - Container.Bind().AsSingle(); - - Container.BindCommand() - .ToOptionalResolve(x => x.Execute); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.IsNull(Bar.Value); - - cmd.Execute("asdf"); - - Assert.IsEqual(Bar.Value, "asdf"); - Assert.IsEqual(Bar.InstanceCount, 1); - } - - [Test] - public void TestToOptionalResolveMethod2() - { - Bar.Value = null; - Bar.InstanceCount = 0; - - Container.BindCommand() - .ToOptionalResolve(x => x.Execute); - - var cmd = Container.Resolve(); - - Assert.IsNull(Bar.Value); - - cmd.Execute("asdf"); - - Assert.IsNull(Bar.Value); - Assert.IsEqual(Bar.InstanceCount, 0); - } - - [Test] - public void TestToNothingHandler() - { - Container.BindCommand().ToNothing(); - - var cmd = Container.Resolve(); - cmd.Execute("asdf"); - } - - [Test] - public void TestToMethod() - { - string receivedValue = null; - - Container.BindCommand() - .ToMethod((value) => receivedValue = value); - - var cmd = Container.Resolve(); - - Assert.IsNull(receivedValue); - cmd.Execute("asdf"); - Assert.IsEqual(receivedValue, "asdf"); - } - - public class DoSomethingCommand : Command - { - } - - public class Bar - { - public static int InstanceCount = 0; - - public Bar() - { - InstanceCount ++; - } - - public static string Value - { - get; - set; - } - - public void Execute(string value) - { - Value = value; - } - } - } -} - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsOne.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsOne.cs.meta deleted file mode 100644 index 5565a2a26..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsOne.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 1840a09437cda48438cad0396b571fe7 -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs new file mode 100644 index 000000000..e7501fdab --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace Zenject.Tests +{ + [TestFixture] + public class TestCommandsWithParameters : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindAllInterfacesAndSelf().To().AsSingle(); + } + + [Test] + public void TestParameters1() + { + Bar1.Value = null; + + Container.DeclareCommand(); + Container.ImplementCommand() + .By(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.IsNull(Bar1.Value); + + cmd.Execute("asdf"); + + Assert.IsEqual(Bar1.Value, "asdf"); + } + + [Test] + public void TestParameters2() + { + Bar2.Value1 = null; + Bar2.Value2 = 0; + + Container.DeclareCommand(); + Container.ImplementCommand() + .By(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.IsNull(Bar2.Value1); + Assert.IsEqual(Bar2.Value2, 0); + + cmd.Execute("asdf", 4); + + Assert.IsEqual(Bar2.Value1, "asdf"); + Assert.IsEqual(Bar2.Value2, 4); + } + + [Test] + public void TestParameters3() + { + Bar3.Value1 = null; + Bar3.Value2 = 0; + Bar3.Value3 = 0.0f; + + Container.DeclareCommand(); + Container.ImplementCommand() + .By(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.IsNull(Bar3.Value1); + Assert.IsEqual(Bar3.Value2, 0); + Assert.IsEqual(Bar3.Value3, 0.0f); + + cmd.Execute("asdf", 4, 7.2f); + + Assert.IsEqual(Bar3.Value1, "asdf"); + Assert.IsEqual(Bar3.Value2, 4); + Assert.IsEqual(Bar3.Value3, 7.2f); + } + + [Test] + public void TestParameters4() + { + Bar4.Value1 = null; + Bar4.Value2 = 0; + Bar4.Value3 = 0.0f; + Bar4.Value4 = '0'; + + Container.DeclareCommand(); + Container.ImplementCommand() + .By(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.IsNull(Bar4.Value1); + Assert.IsEqual(Bar4.Value2, 0); + Assert.IsEqual(Bar4.Value3, 0.0f); + Assert.IsEqual(Bar4.Value4, '0'); + + cmd.Execute("asdf", 4, 7.2f, 'z'); + + Assert.IsEqual(Bar4.Value1, "asdf"); + Assert.IsEqual(Bar4.Value2, 4); + Assert.IsEqual(Bar4.Value3, 7.2f); + Assert.IsEqual(Bar4.Value4, 'z'); + } + + public class DoSomethingCommand1 : Command { } + public class DoSomethingCommand2 : Command { } + public class DoSomethingCommand3 : Command { } + public class DoSomethingCommand4 : Command { } + + public class Bar1 + { + public static string Value; + + public void Execute(string value) + { + Value = value; + } + } + + public class Bar2 + { + public static string Value1; + public static int Value2; + + public void Execute(string value1, int value2) + { + Value1 = value1; + Value2 = value2; + } + } + + public class Bar3 + { + public static string Value1; + public static int Value2; + public static float Value3; + + public void Execute(string value1, int value2, float value3) + { + Value1 = value1; + Value2 = value2; + Value3 = value3; + } + } + + public class Bar4 + { + public static string Value1; + public static int Value2; + public static float Value3; + public static char Value4; + + public void Execute(string value1, int value2, float value3, char value4) + { + Value1 = value1; + Value2 = value2; + Value3 = value3; + Value4 = value4; + } + } + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs.meta new file mode 100644 index 000000000..91901e0dc --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 54d58f70a70c295479aaf30f1c27529a +timeCreated: 1480710679 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsZero.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsZero.cs deleted file mode 100644 index fb17d8255..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsZero.cs +++ /dev/null @@ -1,232 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestCommandsZero : ZenjectUnitTestFixture - { - [Test] - public void TestToSingle1() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.Bind().AsSingle(); - - Container.BindCommand() - .To(x => x.Execute).AsSingle(); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.IsEqual(Bar.InstanceCount, 1); - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 1); - } - - [Test] - public void TestToTransient1() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.BindCommand() - .To(x => x.Execute).AsTransient(); - - var cmd = Container.Resolve(); - - Assert.IsEqual(Bar.InstanceCount, 0); - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 1); - - Bar.WasTriggered = false; - - cmd.Execute(); - - Assert.IsEqual(Bar.InstanceCount, 2); - Assert.That(Bar.WasTriggered); - } - - [Test] - public void TestToCached1() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.Bind().AsCached(); - - Container.BindCommand() - .To(x => x.Execute).AsCached(); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.IsEqual(Bar.InstanceCount, 1); - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 2); - - cmd.Execute(); - Assert.IsEqual(Bar.InstanceCount, 2); - } - - [Test] - public void TestToResolveTransientMethod() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.Bind().AsTransient(); - - Container.BindCommand() - .ToResolve(x => x.Execute).AsTransient(); - - var cmd = Container.Resolve(); - - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 1); - - cmd.Execute(); - - Assert.IsEqual(Bar.InstanceCount, 2); - } - - [Test] - public void TestToResolveCachedMethod() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.Bind().AsTransient(); - - Container.BindCommand() - .ToResolve(x => x.Execute).AsCached(); - - var cmd = Container.Resolve(); - - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 1); - - cmd.Execute(); - - Assert.IsEqual(Bar.InstanceCount, 1); - } - - [Test] - public void TestToOptionalResolveMethod1() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.Bind().AsSingle(); - - Container.BindCommand() - .ToOptionalResolve(x => x.Execute); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 1); - } - - [Test] - public void TestToOptionalResolveMethod2() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.BindCommand() - .ToOptionalResolve(x => x.Execute); - - var cmd = Container.Resolve(); - - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(!Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 0); - } - - [Test] - public void TestToNothingHandler() - { - Container.BindCommand().ToNothing(); - - var cmd = Container.Resolve(); - cmd.Execute(); - } - - [Test] - public void TestToMethod() - { - bool wasCalled = false; - - Container.BindCommand() - .ToMethod(() => wasCalled = true); - - var cmd = Container.Resolve(); - - Assert.That(!wasCalled); - cmd.Execute(); - Assert.That(wasCalled); - } - - public class DoSomethingCommand : Command - { - } - - public class Bar - { - public static int InstanceCount = 0; - - public Bar() - { - InstanceCount ++; - } - - public static bool WasTriggered - { - get; - set; - } - - public void Execute() - { - WasTriggered = true; - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsZero.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsZero.cs.meta deleted file mode 100644 index 3a5df30cc..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsZero.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: c61da57b93068c546a60c588270d54be -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 76d66a73b6620337adcb78484e63060e209034ef Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 2 Dec 2016 23:37:03 -0400 Subject: [PATCH 04/62] More tweaks to commands: - Added tests - Added ability to add multiple handlers - Added ability to limit number of handlers - Fixed compile error on WSA platforms --- .../CommandsAndSignals/Command/Command.cs | 25 ++++-- .../Command/CommandBinder.cs | 30 +++++++ .../Command/CommandBinder.cs.meta | 12 +++ .../Command/CommandExtensions.cs | 17 ++-- .../Command/CommandHandlerBase.cs | 4 +- .../Command/CommandHandlerBinder.cs | 55 +++++++----- .../Command/CommandManager.cs | 63 +++++++++++--- .../UnitTests/Editor/Commands/TestCommands.cs | 86 +++++++++++++++++-- .../Commands/TestCommandsWithParameters.cs | 16 ++-- .../Editor/Conditions/TestConditionsBasic.cs | 14 +++ .../Source/Binding/Binders/ConditionBinder.cs | 12 +-- .../Assets/Zenject/Source/Internal/Assert.cs | 8 ++ .../Assets/Zenject/Source/Main/DiContainer.cs | 8 +- 13 files changed, 278 insertions(+), 72 deletions(-) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs index 53b65ba97..8d0eca4d0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs @@ -8,14 +8,27 @@ public interface ICommand { } + public class CommandSettings + { + public int MinHandlers = 0; + public int MaxHandlers = int.MaxValue; + } + public abstract class CommandBase : ICommand { CommandManager _manager; [Inject] - void Construct(CommandManager manager) + void Construct(CommandManager manager, CommandSettings settings) { _manager = manager; + Settings = settings; + } + + protected CommandSettings Settings + { + get; + private set; } protected CommandManager Manager @@ -36,7 +49,7 @@ public abstract class Command : CommandBase { public void Execute() { - Manager.Trigger(this.GetType(), new object[0]); + Manager.Trigger(this.GetType(), Settings, new object[0]); } } @@ -44,7 +57,7 @@ public abstract class Command : CommandBase { public void Execute(TParam1 param1) { - Manager.Trigger(this.GetType(), new object[] { param1 }); + Manager.Trigger(this.GetType(), Settings, new object[] { param1 }); } } @@ -52,7 +65,7 @@ public abstract class Command : CommandBase { public void Execute(TParam1 param1, TParam2 param2) { - Manager.Trigger(this.GetType(), new object[] { param1, param2 }); + Manager.Trigger(this.GetType(), Settings, new object[] { param1, param2 }); } } @@ -60,7 +73,7 @@ public abstract class Command : CommandBase { public void Execute(TParam1 param1, TParam2 param2, TParam3 param3) { - Manager.Trigger(this.GetType(), new object[] { param1, param2, param3 }); + Manager.Trigger(this.GetType(), Settings, new object[] { param1, param2, param3 }); } } @@ -68,7 +81,7 @@ public abstract class Command : CommandBase { public void Execute(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) { - Manager.Trigger(this.GetType(), new object[] { param1, param2, param3, param4 }); + Manager.Trigger(this.GetType(), Settings, new object[] { param1, param2, param3, param4 }); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs new file mode 100644 index 000000000..7ff868ade --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace Zenject +{ + public class CommandBinder : ConditionBinder + { + readonly CommandSettings _commandSettings; + + public CommandBinder( + BindInfo bindInfo, CommandSettings commandSettings) + : base(bindInfo) + { + _commandSettings = commandSettings; + } + + public ConditionBinder RequireHandler() + { + _commandSettings.MinHandlers = 1; + return this; + } + + public ConditionBinder RequireSingleHandler() + { + _commandSettings.MinHandlers = 1; + _commandSettings.MaxHandlers = 1; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs.meta new file mode 100644 index 000000000..6f293a8a0 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 97866341f87495a428ecbcd9c1079daa +timeCreated: 1480716061 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs index 9820b2074..770f0c266 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs @@ -6,13 +6,16 @@ namespace Zenject { public static class CommandExtensions { - public static ConditionBinder DeclareCommand(this DiContainer container) + public static CommandBinder DeclareCommand(this DiContainer container) where T : ICommand { - return container.Bind().AsSingle(); + var info = new BindInfo(typeof(T)); + var commandSettings = new CommandSettings(); + container.Bind(info).AsSingle().WithArguments(commandSettings); + return new CommandBinder(info, commandSettings); } - public static CommandHandlerBinder ImplementCommand(this DiContainer container) + public static CommandHandlerBinder HandleCommand(this DiContainer container) where TCommand : Command { var binder = container.StartBinding(); @@ -20,7 +23,7 @@ public static CommandHandlerBinder ImplementCommand(this DiContainer c container, typeof(TCommand), binder); } - public static CommandHandlerBinder ImplementCommand(this DiContainer container) + public static CommandHandlerBinder HandleCommand(this DiContainer container) where TCommand : Command { var binder = container.StartBinding(); @@ -28,7 +31,7 @@ public static CommandHandlerBinder ImplementCommand( container, typeof(TCommand), binder); } - public static CommandHandlerBinder ImplementCommand(this DiContainer container) + public static CommandHandlerBinder HandleCommand(this DiContainer container) where TCommand : Command { var binder = container.StartBinding(); @@ -36,7 +39,7 @@ public static CommandHandlerBinder ImplementCommand ImplementCommand(this DiContainer container) + public static CommandHandlerBinder HandleCommand(this DiContainer container) where TCommand : Command { var binder = container.StartBinding(); @@ -44,7 +47,7 @@ public static CommandHandlerBinder ImplementCommand ImplementCommand(this DiContainer container) + public static CommandHandlerBinder HandleCommand(this DiContainer container) where TCommand : Command { var binder = container.StartBinding(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs index f592dde56..8857073a6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs @@ -20,14 +20,14 @@ public CommandHandlerBase( public void Dispose() { - _manager.Unregister(_commandType); + _manager.Unregister(_commandType, this); } protected void ValidateParameter(object value) { if (value == null) { - Assert.That(!typeof(T).IsValueType); + Assert.That(!typeof(T).IsValueType()); } else { diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs index 3eaf923b0..2a470c1aa 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs @@ -18,9 +18,9 @@ public CommandHandlerBinder( _finalizerWrapper = finalizerWrapper; } - public FromBinder By(Func methodGetter) + public FromBinder With(Func methodGetter) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); var lookupId = Guid.NewGuid(); @@ -30,12 +30,15 @@ public FromBinder By(Func methodGetter) _container.Bind(typeof(IDisposable)).To>().AsCached() .WithArguments(_commandType, methodGetter, lazyLookup); + // By returning FromBinder, it means they can add conditions, and also + // do things like CopyIntoAllSubContainers, and NonLazy, all of which + // make no sense for command handlers, but whatever return _container.Bind().WithId(lookupId).To(); } - public void ByMethod(Action method) + public void WithMethod(Action method) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); _container.Bind(typeof(IDisposable)).To().AsCached() @@ -57,9 +60,9 @@ public CommandHandlerBinder( _finalizerWrapper = finalizerWrapper; } - public FromBinder By(Func> methodGetter) + public FromBinder With(Func> methodGetter) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); var lookupId = Guid.NewGuid(); @@ -69,12 +72,15 @@ public FromBinder By(Func> methodGetter) _container.Bind(typeof(IDisposable)).To>().AsCached() .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); + // By returning FromBinder, it means they can add conditions, and also + // do things like CopyIntoAllSubContainers, and NonLazy, all of which + // make no sense for command handlers, but whatever return _container.Bind().WithId(lookupId).To(); } - public void ByMethod(Action method) + public void WithMethod(Action method) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); _container.Bind(typeof(IDisposable)).To>().AsCached() @@ -96,9 +102,9 @@ public CommandHandlerBinder( _finalizerWrapper = finalizerWrapper; } - public FromBinder By(Func> methodGetter) + public FromBinder With(Func> methodGetter) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); var lookupId = Guid.NewGuid(); @@ -108,12 +114,15 @@ public FromBinder By(Func> methodGe _container.Bind(typeof(IDisposable)).To>().AsCached() .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); + // By returning FromBinder, it means they can add conditions, and also + // do things like CopyIntoAllSubContainers, and NonLazy, all of which + // make no sense for command handlers, but whatever return _container.Bind().WithId(lookupId).To(); } - public void ByMethod(Action method) + public void WithMethod(Action method) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); _container.Bind(typeof(IDisposable)).To>().AsCached() @@ -135,9 +144,9 @@ public CommandHandlerBinder( _finalizerWrapper = finalizerWrapper; } - public FromBinder By(Func> methodGetter) + public FromBinder With(Func> methodGetter) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); var lookupId = Guid.NewGuid(); @@ -147,12 +156,15 @@ public FromBinder By(Func> _container.Bind(typeof(IDisposable)).To>().AsCached() .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); + // By returning FromBinder, it means they can add conditions, and also + // do things like CopyIntoAllSubContainers, and NonLazy, all of which + // make no sense for command handlers, but whatever return _container.Bind().WithId(lookupId).To(); } - public void ByMethod(Action method) + public void WithMethod(Action method) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); _container.Bind(typeof(IDisposable)).To>().AsCached() @@ -174,9 +186,9 @@ public CommandHandlerBinder( _finalizerWrapper = finalizerWrapper; } - public FromBinder By(Func> methodGetter) + public FromBinder With(Func> methodGetter) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); var lookupId = Guid.NewGuid(); @@ -186,12 +198,15 @@ public FromBinder By(Func>().AsCached() .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); + // By returning FromBinder, it means they can add conditions, and also + // do things like CopyIntoAllSubContainers, and NonLazy, all of which + // make no sense for command handlers, but whatever return _container.Bind().WithId(lookupId).To(); } - public void ByMethod(Action method) + public void WithMethod(Action method) { - // This is just to ensure they don't stop at ImplementCommand + // This is just to ensure they don't stop at HandleCommand _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); _container.Bind(typeof(IDisposable)).To>().AsCached() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs index 2c84fb335..b6a4bda8b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs @@ -1,44 +1,83 @@ using System; using System.Collections.Generic; using ModestTree; +using System.Linq; namespace Zenject { public class CommandManager : ILateDisposable { - readonly Dictionary _commandHandlers = new Dictionary(); + readonly Dictionary> _commandHandlers = new Dictionary>(); public bool IsHandlerRegistered(Type commandType) { - return _commandHandlers.ContainsKey(commandType); + return !GetList(commandType).IsEmpty(); + } + + List GetList(Type commandType) + { + List handlers; + + if (!_commandHandlers.TryGetValue(commandType, out handlers)) + { + handlers = new List(); + _commandHandlers.Add(commandType, handlers); + } + + return handlers; } public void Register(Type commandType, ICommandHandler handler) { - _commandHandlers.Add(commandType, handler); + GetList(commandType).Add(handler); } - public void Unregister(Type commandType) + public void Unregister(Type commandType, ICommandHandler handler) { - _commandHandlers.RemoveWithConfirm(commandType); + GetList(commandType).RemoveWithConfirm(handler); } public void LateDispose() { - Assert.That(_commandHandlers.IsEmpty()); + Assert.Warn(_commandHandlers.Values.SelectMany(x => x).IsEmpty(), + "Found commands still registered on CommandManager"); } - public void Trigger(Type commandType, object[] args) + public void Trigger( + Type commandType, CommandSettings settings, object[] args) { - ICommandHandler handler; + var handlers = GetList(commandType); - if (!_commandHandlers.TryGetValue(commandType, out handler)) + if (handlers.Count < settings.MinHandlers) { - Log.Warn("Fired command '{0}' but no handler was registered!", commandType); - return; + if (settings.MinHandlers == 0) + { + throw Assert.CreateException( + "Fired command '{0}' but no handler was registered! Command requires at least one handler.", commandType); + } + + throw Assert.CreateException( + "Command '{0}' was fired but only had {1} handlers attached (requires at least {2}).", + commandType, handlers.Count, settings.MinHandlers); } - handler.Execute(args); + if (handlers.Count > settings.MaxHandlers) + { + if (settings.MaxHandlers == 1) + { + throw Assert.CreateException( + "Found multiple handlers for command '{0}'. Was expecting only one.", commandType); + } + + throw Assert.CreateException( + "Found '{0}' handlers for command '{1}' but was expecting a max of '{2}'", + handlers.Count, commandType, settings.MaxHandlers); + } + + foreach (var handler in handlers) + { + handler.Execute(args); + } } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs index afbfa7986..19c8e0754 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs @@ -27,8 +27,8 @@ public void TestToSingle1() Container.Bind().AsSingle(); Container.DeclareCommand(); - Container.ImplementCommand() - .By(x => x.Execute).AsSingle(); + Container.HandleCommand() + .With(x => x.Execute).AsSingle(); Initialize(); @@ -53,8 +53,8 @@ public void TestToCached1() Container.Bind().AsCached(); Container.DeclareCommand(); - Container.ImplementCommand() - .By(x => x.Execute).AsCached(); + Container.HandleCommand() + .With(x => x.Execute).AsCached(); Initialize(); @@ -74,7 +74,7 @@ public void TestToCached1() } [Test] - public void TestToNothingHandler() + public void TestNoHandlerDefault() { Container.DeclareCommand(); @@ -84,14 +84,39 @@ public void TestToNothingHandler() cmd.Execute(); } + [Test] + public void TestNoHandlerRequiredFailure() + { + Container.DeclareCommand().RequireHandler(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.Throws(() => cmd.Execute()); + } + + [Test] + public void TestNoHandlerRequiredSuccess() + { + Container.DeclareCommand().RequireHandler(); + Container.HandleCommand() + .With(x => x.Execute).AsCached(); + + Initialize(); + + var cmd = Container.Resolve(); + cmd.Execute(); + } + [Test] public void TestToMethod() { bool wasCalled = false; Container.DeclareCommand(); - Container.ImplementCommand() - .ByMethod(() => wasCalled = true); + Container.HandleCommand() + .WithMethod(() => wasCalled = true); Initialize(); @@ -102,6 +127,53 @@ public void TestToMethod() Assert.That(wasCalled); } + [Test] + public void TestMultipleHandlers() + { + bool wasCalled1 = false; + bool wasCalled2 = false; + + Container.DeclareCommand(); + Container.HandleCommand() + .WithMethod(() => wasCalled1 = true); + Container.HandleCommand() + .WithMethod(() => wasCalled2 = true); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.That(!wasCalled1); + Assert.That(!wasCalled2); + cmd.Execute(); + Assert.That(wasCalled1); + Assert.That(wasCalled2); + } + + public void TestMultipleHandlersError() + { + bool wasCalled1 = false; + bool wasCalled2 = false; + + Container.DeclareCommand() + .RequireSingleHandler(); + + Container.HandleCommand() + .WithMethod(() => wasCalled1 = true); + Container.HandleCommand() + .WithMethod(() => wasCalled2 = true); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.That(!wasCalled1); + Assert.That(!wasCalled2); + cmd.Execute(); + Assert.That(wasCalled1); + Assert.That(wasCalled2); + } + public class DoSomethingCommand : Command { } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs index e7501fdab..50cf3a01f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs @@ -24,8 +24,8 @@ public void TestParameters1() Bar1.Value = null; Container.DeclareCommand(); - Container.ImplementCommand() - .By(x => x.Execute).AsSingle(); + Container.HandleCommand() + .With(x => x.Execute).AsSingle(); Initialize(); @@ -45,8 +45,8 @@ public void TestParameters2() Bar2.Value2 = 0; Container.DeclareCommand(); - Container.ImplementCommand() - .By(x => x.Execute).AsSingle(); + Container.HandleCommand() + .With(x => x.Execute).AsSingle(); Initialize(); @@ -69,8 +69,8 @@ public void TestParameters3() Bar3.Value3 = 0.0f; Container.DeclareCommand(); - Container.ImplementCommand() - .By(x => x.Execute).AsSingle(); + Container.HandleCommand() + .With(x => x.Execute).AsSingle(); Initialize(); @@ -96,8 +96,8 @@ public void TestParameters4() Bar4.Value4 = '0'; Container.DeclareCommand(); - Container.ImplementCommand() - .By(x => x.Execute).AsSingle(); + Container.HandleCommand() + .With(x => x.Execute).AsSingle(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsBasic.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsBasic.cs index fd806bae7..1a6d4ebf1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsBasic.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsBasic.cs @@ -56,6 +56,20 @@ public void Test1() Assert.IsNotEqual( Container.Resolve().Foo, Container.Resolve().Foo); } + + [Test] + public void Test2() + { + Container.Bind().AsSingle().NonLazy(); + Container.Bind().AsSingle().NonLazy(); + Container.Bind().To().AsSingle().NonLazy(); + Container.Bind().To().AsSingle().WhenNotInjectedInto().NonLazy(); + + Container.Validate(); + + Assert.IsNotEqual( + Container.Resolve().Foo, Container.Resolve().Foo); + } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs index 768831cd6..0482a925e 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs @@ -19,26 +19,22 @@ public CopyIntoSubContainersBinder When(BindingCondition condition) public CopyIntoSubContainersBinder WhenInjectedIntoInstance(object instance) { - BindInfo.Condition = r => ReferenceEquals(r.ObjectInstance, instance); - return this; + return When(r => ReferenceEquals(r.ObjectInstance, instance)); } public CopyIntoSubContainersBinder WhenInjectedInto(params Type[] targets) { - BindInfo.Condition = r => targets.Where(x => r.ObjectType != null && r.ObjectType.DerivesFromOrEqual(x)).Any(); - return this; + return When(r => targets.Where(x => r.ObjectType != null && r.ObjectType.DerivesFromOrEqual(x)).Any()); } public CopyIntoSubContainersBinder WhenInjectedInto() { - BindInfo.Condition = r => r.ObjectType != null && r.ObjectType.DerivesFromOrEqual(typeof(T)); - return this; + return When(r => r.ObjectType != null && r.ObjectType.DerivesFromOrEqual(typeof(T))); } public CopyIntoSubContainersBinder WhenNotInjectedInto() { - BindInfo.Condition = r => r.ObjectType == null || !r.ObjectType.DerivesFromOrEqual(typeof(T)); - return this; + return When(r => r.ObjectType == null || !r.ObjectType.DerivesFromOrEqual(typeof(T))); } } } diff --git a/UnityProject/Assets/Zenject/Source/Internal/Assert.cs b/UnityProject/Assets/Zenject/Source/Internal/Assert.cs index 9b09088df..1c75660cf 100644 --- a/UnityProject/Assets/Zenject/Source/Internal/Assert.cs +++ b/UnityProject/Assets/Zenject/Source/Internal/Assert.cs @@ -242,6 +242,14 @@ public static void Warn(bool condition) } } + public static void Warn(bool condition, string message, params object[] parameters) + { + if (!condition) + { + Log.Warn("Warning Assert hit! " + FormatString(message, parameters)); + } + } + public static void Warn(bool condition, Func messageGenerator) { if (!condition) diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index a228e3ebb..c62748e97 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -1814,12 +1814,16 @@ public ConcreteBinderGeneric Rebind(object identifier) // Map the given type to a way of obtaining it // Note that this can include open generic types as well such as List<> public ConcreteIdBinderGeneric Bind() + { + return Bind( + new BindInfo(typeof(TContract))); + } + + public ConcreteIdBinderGeneric Bind(BindInfo bindInfo) { Assert.That(!typeof(TContract).DerivesFrom(), "You should not use Container.Bind for factory classes. Use Container.BindFactory instead."); - var bindInfo = new BindInfo(typeof(TContract)); - return new ConcreteIdBinderGeneric( bindInfo, StartBinding()); } From 073662002b049bceeadc1f417479c27dffb5546f Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 4 Dec 2016 22:39:33 -0400 Subject: [PATCH 05/62] Removed GameDecoratorInstaller re issue #180 --- .../Installers/GameDecoratorInstaller.cs | 42 ------------------- 1 file changed, 42 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs deleted file mode 100644 index 10487fdbd..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs +++ /dev/null @@ -1,42 +0,0 @@ -using UnityEngine; -using System.Collections; -using Zenject; -using ModestTree; - -namespace Zenject.Asteroids -{ - // This scene is an example of how decorators work - // We override move settings to make the ship much slower and add a hotkey to manually spawn asteroids - // Decorators are really useful in particular for running different test configurations - public class GameDecoratorInstaller : MonoInstaller - { - public ShipStateMoving.Settings OverrideMoveSettings; - - // If you are injecting into an installer then you will need to put the binding in PreInstall - public override void InstallBindings() - { - Container.Bind().To().AsSingle(); - // Do not spawn asteroids automatically - Container.BindInstance(false).WhenInjectedInto(); - } - } - - public class TestHotKeysAdder : ITickable - { - readonly AsteroidManager _asteroidManager; - - public TestHotKeysAdder(AsteroidManager asteroidManager) - { - _asteroidManager = asteroidManager; - } - - public void Tick() - { - if (Input.GetKeyDown(KeyCode.F4)) - { - _asteroidManager.SpawnNext(); - Log.Info("Spawned new asteroid!"); - } - } - } -} From 9a8e3f42d25b6476a59a9dadadae9c568c238b06 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Thu, 8 Dec 2016 22:54:38 -0400 Subject: [PATCH 06/62] Added another game to readme --- README.md | 1 + .../Scripts/Installers/GameDecoratorInstaller.cs.meta | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta diff --git a/README.md b/README.md index bf7d01b9c..60eaf6688 100644 --- a/README.md +++ b/README.md @@ -2124,6 +2124,7 @@ Something else to note is that the rate at which the ITickable.Tick method gets * [NOVA Black Holes](https://itunes.apple.com/us/app/nova-black-holes/id1114574985?mt=8) (iOS) * [Farm Away!](http://www.farmawaygame.com/) (iOS and Android) * [Build Away!](http://www.buildawaygame.com/) (iOS and Android) + * Stick Soccer 2 ([iOS](https://itunes.apple.com/gb/app/stick-soccer-2/id1104214157?mt=8) and [Android](https://play.google.com/store/apps/details?id=com.sticksports.soccer2&hl=en_GB)) Libraries diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta deleted file mode 100644 index 6ebbc9ba2..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f5efd89f29bfcd141907dd60701bc741 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: From 07589214f987693d0d0e6a3fee46aad3429355a3 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 2 Jan 2017 22:17:15 -0400 Subject: [PATCH 07/62] - Bug fix - Fixed an extremely rare bug where zenject would get in an infinite loop when using complex subcontainer setups - Added menu option "Validate All Active Scenes" --- .../Zenject/Source/Editor/ZenMenuItems.cs | 28 ++++++++-- .../Source/Editor/ZenUnityEditorUtil.cs | 15 ++++++ .../Assets/Zenject/Source/Main/DiContainer.cs | 54 +++++++++++-------- 3 files changed, 71 insertions(+), 26 deletions(-) diff --git a/UnityProject/Assets/Zenject/Source/Editor/ZenMenuItems.cs b/UnityProject/Assets/Zenject/Source/Editor/ZenMenuItems.cs index b13a0ddba..29f267421 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/ZenMenuItems.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/ZenMenuItems.cs @@ -16,13 +16,13 @@ public static class ZenMenuItems [MenuItem("Edit/Zenject/Validate Current Scenes #%v")] public static void ValidateCurrentScene() { - ValidateInternal(); + ValidateCurrentSceneInternal(); } [MenuItem("Edit/Zenject/Validate Then Run #%r")] public static void ValidateCurrentSceneThenRun() { - if (ValidateInternal()) + if (ValidateCurrentSceneInternal()) { EditorApplication.isPlaying = true; } @@ -276,7 +276,17 @@ static void AddCSharpClassTemplate( Selection.activeObject = AssetDatabase.LoadAssetAtPath(assetPath); } - static bool ValidateInternal() + [MenuItem("Edit/Zenject/Validate All Active Scenes #%v")] + public static void ValidateAllActiveScenes() + { + ValidateWrapper(() => + { + var numValidated = ZenUnityEditorUtil.ValidateAllActiveScenes(); + Log.Info("Validated all '{0}' active scenes successfully", numValidated); + }); + } + + static bool ValidateWrapper(Action action) { if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { @@ -284,8 +294,7 @@ static bool ValidateInternal() try { - ZenUnityEditorUtil.ValidateCurrentSceneSetup(); - Log.Info("All scenes validated successfully"); + action(); return true; } catch (Exception e) @@ -304,6 +313,15 @@ static bool ValidateInternal() return false; } } + + static bool ValidateCurrentSceneInternal() + { + return ValidateWrapper(() => + { + ZenUnityEditorUtil.ValidateCurrentSceneSetup(); + Log.Info("All scenes validated successfully"); + }); + } } } #endif diff --git a/UnityProject/Assets/Zenject/Source/Editor/ZenUnityEditorUtil.cs b/UnityProject/Assets/Zenject/Source/Editor/ZenUnityEditorUtil.cs index f2ea862db..c300651cd 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/ZenUnityEditorUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/ZenUnityEditorUtil.cs @@ -35,6 +35,21 @@ public static void ValidateCurrentSceneSetup() } } + // Don't use this + public static int ValidateAllActiveScenes() + { + var activeScenePaths = UnityEditor.EditorBuildSettings.scenes.Where(x => x.enabled) + .Select(x => x.path).ToList(); + + foreach (var scenePath in activeScenePaths) + { + EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); + ValidateCurrentSceneSetup(); + } + + return activeScenePaths.Count; + } + // Don't use this public static void RunCurrentSceneSetup() { diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 2b816d5e4..59812b863 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -426,7 +426,7 @@ public IList ResolveAll(InjectContext context) if (matches.Any()) { - var instances = matches.SelectMany(x => SafeGetInstances(x.ProviderInfo.Provider, context)).ToArray(); + var instances = matches.SelectMany(x => SafeGetInstances(x, context)).ToArray(); if (IsValidating) { @@ -499,7 +499,7 @@ public Type ResolveType(InjectContext context) { Assert.IsNotNull(context); - IProvider provider; + ProviderPair provider; FlushBindings(); @@ -521,7 +521,7 @@ public Type ResolveType(InjectContext context) } Assert.IsNotNull(provider); - return provider.GetInstanceType(context); + return provider.ProviderInfo.Provider.GetInstanceType(context); } public List ResolveTypeAll(Type type) @@ -549,8 +549,8 @@ public List ResolveTypeAll(InjectContext context) // Try looking up a single provider for a given context // Note that this method should not throw zenject exceptions - internal ProviderLookupResult TryGetUniqueProvider( - InjectContext context, out IProvider provider) + ProviderLookupResult TryGetUniqueProvider( + InjectContext context, out ProviderPair providerPair) { Assert.IsNotNull(context); @@ -559,7 +559,7 @@ internal ProviderLookupResult TryGetUniqueProvider( if (providers.IsEmpty()) { - provider = null; + providerPair = null; return ProviderLookupResult.None; } @@ -579,15 +579,15 @@ internal ProviderLookupResult TryGetUniqueProvider( if (sortedProviders.Count == 1) { // We have one match that is the closest - provider = sortedProviders[0].Pair.ProviderInfo.Provider; + providerPair = sortedProviders[0].Pair; } else { // Try choosing the one with a condition before giving up and throwing an exception // This is nice because it allows us to bind a default and then override with conditions - provider = sortedProviders.Where(x => x.Pair.ProviderInfo.Condition != null).Select(x => x.Pair.ProviderInfo.Provider).OnlyOrDefault(); + providerPair = sortedProviders.Where(x => x.Pair.ProviderInfo.Condition != null).Select(x => x.Pair).OnlyOrDefault(); - if (provider == null) + if (providerPair == null) { return ProviderLookupResult.Multiple; } @@ -595,10 +595,10 @@ internal ProviderLookupResult TryGetUniqueProvider( } else { - provider = providers.Single().ProviderInfo.Provider; + providerPair = providers.Single(); } - Assert.IsNotNull(provider); + Assert.IsNotNull(providerPair); return ProviderLookupResult.Success; } @@ -606,12 +606,12 @@ public object Resolve(InjectContext context) { Assert.IsNotNull(context); - IProvider provider; + ProviderPair providerPair; FlushBindings(); CheckForInstallWarning(context); - var result = TryGetUniqueProvider(context, out provider); + var result = TryGetUniqueProvider(context, out providerPair); Assert.That(result != ProviderLookupResult.Multiple, "Found multiple matches when only one was expected for type '{0}'{1}. \nObject graph:\n {2}", @@ -638,15 +638,15 @@ public object Resolve(InjectContext context) } throw Assert.CreateException("Unable to resolve type '{0}'{1}. \nObject graph:\n{2}", - context.MemberType + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), + context.MemberType.Name() + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType.Name())), context.GetObjectGraphString()); } Assert.That(result == ProviderLookupResult.Success); - Assert.IsNotNull(provider); + Assert.IsNotNull(providerPair); - var instances = SafeGetInstances(provider, context); + var instances = SafeGetInstances(providerPair, context); Assert.That(!instances.IsEmpty(), "Provider returned zero instances when one was expected!"); Assert.That(instances.Count() == 1, "Provider returned multiple instances when one was expected!"); @@ -654,27 +654,39 @@ public object Resolve(InjectContext context) return instances.First(); } - IEnumerable SafeGetInstances(IProvider provider, InjectContext context) + IEnumerable SafeGetInstances(ProviderPair providerPair, InjectContext context) { Assert.IsNotNull(context); + var provider = providerPair.ProviderInfo.Provider; + if (ChecksForCircularDependencies) { var lookupId = new LookupId(provider, context.GetBindingId()); + // Use the container associated with the provider to address some rare cases + // which would otherwise result in an infinite loop. Like this: + // Container.Bind().FromPrefab(Prefab).AsTransient() + // With the prefab being a GameObjectContext containing a script that has a + // ICharacter dependency. In this case, we would otherwise use the _resolvesInProgress + // associated with the GameObjectContext container, which will allow the recursive + // lookup, which will trigger another GameObjectContext and container (since it is + // transient) and the process continues indefinitely + + var providerContainer = providerPair.Container; // Allow one before giving up so that you can do circular dependencies via postinject or fields - Assert.That(_resolvesInProgress.Where(x => x.Equals(lookupId)).Count() <= 1, + Assert.That(providerContainer._resolvesInProgress.Where(x => x.Equals(lookupId)).Count() <= 1, "Circular dependency detected! \nObject graph:\n {0}", context.GetObjectGraphString()); - _resolvesInProgress.Push(lookupId); + providerContainer._resolvesInProgress.Push(lookupId); try { return provider.GetAllInstances(context); } finally { - Assert.That(_resolvesInProgress.Peek().Equals(lookupId)); - _resolvesInProgress.Pop(); + Assert.That(providerContainer._resolvesInProgress.Peek().Equals(lookupId)); + providerContainer._resolvesInProgress.Pop(); } } else From 82cf02523fadc9ef3b58ac5ca8e4fa77feb60750 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 7 Jan 2017 13:08:37 -0400 Subject: [PATCH 08/62] Bug fix to tests to allow adding nunit test case attributes --- Build/python/mtm/zen/CreateRelease.py | 2 +- Documentation/WritingAutomatedTests.md | 2 +- .../Editor/Testing/ZenjectIntegrationTestFixture.cs | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Build/python/mtm/zen/CreateRelease.py b/Build/python/mtm/zen/CreateRelease.py index d8a3a56f3..2f9b5e39e 100644 --- a/Build/python/mtm/zen/CreateRelease.py +++ b/Build/python/mtm/zen/CreateRelease.py @@ -151,7 +151,7 @@ def installBindings(): config = { 'PathVars': { - 'UnityExePath': 'C:/Utils/Unity/Unity5.4.1f1/Editor/Unity.exe', + 'UnityExePath': 'C:/Utils/Unity/PrimaryLink/Editor/Unity.exe', 'LogPath': os.path.join(BuildDir, 'Log.txt'), 'MsBuildExePath': 'C:/Windows/Microsoft.NET/Framework/v4.0.30319/msbuild.exe' }, diff --git a/Documentation/WritingAutomatedTests.md b/Documentation/WritingAutomatedTests.md index 4fb395290..cefaf944e 100644 --- a/Documentation/WritingAutomatedTests.md +++ b/Documentation/WritingAutomatedTests.md @@ -233,7 +233,7 @@ We want to test the AsteroidManager class here, but it has a few dependencies th When you start running a test through Unity's EditorTestRunner window, Unity will open up a new empty scene and run the tests there, and then Unity will re-open your previously open scenes once the tests complete. This is great because any new game objects you create will not affect any currently open scenes (more details here.) -Before each one of your test methods are run, ZenjectIntegrationTestFixture will create a new SceneContext in this empty scene. The Container that you reference in your tests refers to the container used by this new temporary SceneContext. After you have finished installing all your bindings on the Container, either by using [SetUp] methods or from within your test method, you need to call ZenjectIntegrationTestFixture.Initialize(). This will resolve all the NonLazy bindings and also trigger IInitializable.Initialize for all classes that are bound to IInitializable. If you have common fields on your test marked with [Inject] then these fields are also filled in at this time. Alternatively, you can diretcly call `Container.Resolve<>` from within your test methods to get the classes you want to run tests on. +Before each one of your test methods are run, ZenjectIntegrationTestFixture will create a new SceneContext in this empty scene. The Container that you reference in your tests refers to the container used by this new temporary SceneContext. After you have finished installing all your bindings on the Container, either by using [SetUp] methods or from within your test method, you need to call ZenjectIntegrationTestFixture.Initialize(). This will resolve all the NonLazy bindings and also trigger IInitializable.Initialize for all classes that are bound to IInitializable. If you have common fields on your test marked with [Inject] then these fields are also filled in at this time. Alternatively, you can directly call `Container.Resolve<>` from within your test methods to get the classes you want to run tests on. You can also run zenject validation on your test by adding a `[ValidateOnly]` attribute above your test method (as shown in example above). This will cause the test to not instantiate any of your bindings and instead just verify that the configuration of your Container is valid. However, you could also just as easily rely on configuration errors to be caught when running normal tests too, so it probably has limited use for you. diff --git a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs index e6a073488..5284eb99c 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs @@ -87,6 +87,14 @@ bool CurrentTestHasAttribute() var fullMethodName = TestContext.CurrentContext.Test.FullName; var name = fullMethodName.Substring(fullMethodName.LastIndexOf(".")+1); + // Remove all characters after the first open bracket if there is one + int openBracketIndex = name.IndexOf("("); + + if (openBracketIndex != -1) + { + name = name.Substring(0, openBracketIndex); + } + return this.GetType().GetMethod(name).GetCustomAttributes(true) .Cast().OfType().Any(); } From dc1e84361b3b3c8400c0b8d4431c9d5481cb4595 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 7 Jan 2017 16:32:59 -0400 Subject: [PATCH 09/62] Moved commands and signals packages into a seperate repo --- Build/python/mtm/zen/CreateRelease.py | 2 - Documentation/CommandsAndSignals.md | 210 ------ NonUnityBuild/Zenject.sln | 8 +- .../OptionalExtras/CommandsAndSignals.meta | 9 - .../CommandsAndSignals/Command.meta | 9 - .../CommandsAndSignals/Command/Command.cs | 87 --- .../Command/CommandBinder.cs | 30 - .../Command/CommandBinder.cs.meta | 12 - .../Command/CommandExtensions.cs | 58 -- .../Command/CommandExtensions.cs.meta | 12 - .../Command/CommandHandlerBase.cs | 42 -- .../Command/CommandHandlerBase.cs.meta | 12 - .../Command/CommandHandlerBinder.cs | 216 ------- .../Command/CommandHandlerBinder.cs.meta | 12 - .../Command/CommandManager.cs | 84 --- .../Command/CommandManager.cs.meta | 12 - .../Command/ICommandHandler.cs | 11 - .../Command/ICommandHandler.cs.meta | 12 - .../Command/InstanceMethodCommandHandler.cs | 131 ---- .../InstanceMethodCommandHandler.cs.meta | 12 - .../Command/StaticMethodCommandHandler.cs | 107 --- .../StaticMethodCommandHandler.cs.meta | 12 - .../CommandsAndSignals/Signal.meta | 9 - .../CommandsAndSignals/Signal/ISignal.cs | 12 - .../CommandsAndSignals/Signal/Signal0.cs | 80 --- .../CommandsAndSignals/Signal/Signal1.cs | 80 --- .../CommandsAndSignals/Signal/Signal1.cs.meta | 12 - .../CommandsAndSignals/Signal/Signal2.cs | 80 --- .../CommandsAndSignals/Signal/Signal2.cs.meta | 12 - .../CommandsAndSignals/Signal/Signal3.cs | 79 --- .../CommandsAndSignals/Signal/Signal3.cs.meta | 12 - .../CommandsAndSignals/Signal/Signal4.cs | 67 -- .../CommandsAndSignals/Signal/Signal4.cs.meta | 12 - .../CommandsAndSignals/Signal/Signal5.cs | 67 -- .../CommandsAndSignals/Signal/Signal5.cs.meta | 12 - .../CommandsAndSignals/Signal/Signal6.cs | 68 -- .../CommandsAndSignals/Signal/Signal6.cs.meta | 12 - .../Signal/SignalExtensions.cs | 27 - .../Signal/SignalExtensions.cs.meta | 12 - .../Zenject.Commands.csproj | 81 --- .../Zenject.Commands.csproj.meta | 8 - .../Zenject.Commands.csproj.user.meta | 8 - .../SampleGame1 (Beginner)/Asteroids.unity | 436 ++++--------- .../Prefabs/Asteroid.prefab | 22 +- .../Prefabs/Explosion.prefab | 42 +- .../Prefabs/Ship.prefab | 179 ++--- .../Prefabs/ShipBroken.prefab | 116 ++-- .../GameSettingsInstaller.asset.meta | 4 +- .../Installers/GameDecoratorInstaller.cs | 42 ++ .../GameDecoratorInstaller.cs.meta} | 6 +- .../Scripts/Installers/GameInstaller.cs | 2 +- .../Scripts/Main/GameController.cs | 10 +- .../Scripts/Main/GameSignals.cs | 11 - .../Scripts/Main/GameSignals.cs.meta | 12 - .../Scripts/Misc/AudioHandler.cs | 10 +- .../Scripts/Misc/GuiHandler.cs | 10 +- .../Scripts/Ship/States/ShipStateDead.cs | 8 +- .../Scripts/Util/GameEvents.cs | 9 + .../Scripts/Util/GameEvents.cs.meta} | 4 +- .../SampleGame2 (Advanced)/Installers.meta | 4 +- .../GameSettingsInstaller.asset | 0 .../GameSettingsInstaller.asset.meta | 4 +- .../Media/Prefabs/Bullet.prefab | 8 +- .../Media/Prefabs/Enemy.prefab | 13 +- .../Media/Prefabs/Explosion07.prefab | 610 ++---------------- .../Scripts/Enemy/EnemyCollisionDetector.cs | 10 +- .../Scripts/Enemy/EnemyCollisionHandler.cs | 17 +- .../Scripts/Enemy/EnemyHealthWatcher.cs | 8 +- .../Scripts/Enemy/EnemySignals.cs | 12 - .../Scripts/Enemy/EnemySignals.cs.meta | 12 - .../Scripts/Enemy/EnemyStateCommon.cs | 17 +- .../Scripts/Enemy/GameEvents.cs | 12 + .../Scripts/Enemy/GameEvents.cs.meta} | 4 +- .../Scripts/Installers/EnemyInstaller.cs | 2 - .../Scripts/Installers/GameInstaller.cs | 3 +- .../Scripts/Installers/PlayerInstaller.cs | 2 - .../Scripts/Misc/GameRestartHandler.cs | 10 +- .../Scripts/Misc/GameSignals.cs | 16 - .../Scripts/Misc/GameSignals.cs.meta | 12 - .../Scripts/Player/PlayerBulletHitHandler.cs | 10 +- .../Scripts/Player/PlayerCollisionDetector.cs | 8 +- .../Scripts/Player/PlayerHealthDisplay.cs | 20 +- .../Scripts/Player/PlayerHealthWatcher.cs | 8 +- .../Scripts/Player/PlayerSignals.cs | 13 - .../Scripts/Player/PlayerSignals.cs.meta | 12 - .../SampleGame2 (Advanced)/Settings.meta | 9 - .../SampleGame2 (Advanced)/SpaceFighter.unity | 214 +++--- .../UnitTests/Editor/Commands.meta | 9 - .../UnitTests/Editor/Commands/TestCommands.cs | 203 ------ .../Editor/Commands/TestCommands.cs.meta | 12 - .../Commands/TestCommandsWithParameters.cs | 178 ----- .../TestCommandsWithParameters.cs.meta | 12 - .../UnitTests/Editor/Signals.meta | 9 - .../UnitTests/Editor/Signals/TestSignals.cs | 110 ---- .../Editor/Signals/TestSignals.cs.meta | 12 - .../Editor/Signals/TestSignalsOneParam.cs | 88 --- .../Signals/TestSignalsOneParam.cs.meta | 12 - .../Editor/Signals/TestSignalsSixParams.cs | 88 --- .../Signals/TestSignalsSixParams.cs.meta | 12 - .../Signals/TestSignalsWithIdentifiers.cs | 158 ----- .../TestSignalsWithIdentifiers.cs.meta | 12 - .../UnitTests/Editor/Signals/TestTriggers1.cs | 38 -- .../Editor/Signals/TestTriggers1.cs.meta | 12 - .../UnitTests/Editor/Zenject-tests.csproj | 4 - .../Assets/Zenject/Source/Zenject.csproj | 3 + 105 files changed, 613 insertions(+), 4202 deletions(-) delete mode 100644 Documentation/CommandsAndSignals.md delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/ISignal.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal0.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal1.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal1.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal2.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal2.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal3.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal3.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal4.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal4.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal5.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal5.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal6.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal6.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/SignalExtensions.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/SignalExtensions.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj.user.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs rename UnityProject/Assets/Zenject/OptionalExtras/{CommandsAndSignals/Command/Command.cs.meta => SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta} (53%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameSignals.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameSignals.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Util/GameEvents.cs rename UnityProject/Assets/Zenject/OptionalExtras/{CommandsAndSignals/Signal/ISignal.cs.meta => SampleGame1 (Beginner)/Scripts/Util/GameEvents.cs.meta} (76%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/{Settings => Installers}/GameSettingsInstaller.asset (100%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/{Settings => Installers}/GameSettingsInstaller.asset.meta (76%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemySignals.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemySignals.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs rename UnityProject/Assets/Zenject/OptionalExtras/{CommandsAndSignals/Signal/Signal0.cs.meta => SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs.meta} (76%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameSignals.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameSignals.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerSignals.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerSignals.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSixParams.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSixParams.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs.meta diff --git a/Build/python/mtm/zen/CreateRelease.py b/Build/python/mtm/zen/CreateRelease.py index 2f9b5e39e..8bf366b9f 100644 --- a/Build/python/mtm/zen/CreateRelease.py +++ b/Build/python/mtm/zen/CreateRelease.py @@ -97,7 +97,6 @@ def _createNonUnityZip(self, zipPath): self._log.info('Copying Zenject dlls') self._sys.copyFile('{0}/Zenject.dll'.format(binDir), '{0}/Zenject.dll'.format(tempDir)) - self._sys.copyFile('{0}/Zenject.Commands.dll'.format(binDir), '{0}/Zenject.Commands.dll'.format(tempDir)) self._zipHelper.createZipFile(tempDir, zipPath) @@ -129,7 +128,6 @@ def _createCSharpPackage(self, includeSample, outputPath): self._sys.removeFile('[ZenTempDir]/OptionalExtras/AutoMocking.meta') self._sys.removeFile('[ZenTempDir]/Source/Zenject.csproj') - self._sys.removeFile('[ZenTempDir]/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj') if not includeSample: self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/SampleGame1 (Beginner)') diff --git a/Documentation/CommandsAndSignals.md b/Documentation/CommandsAndSignals.md deleted file mode 100644 index 5091b5f66..000000000 --- a/Documentation/CommandsAndSignals.md +++ /dev/null @@ -1,210 +0,0 @@ - -## Signals And Commands - -Zenject also includes an optional extension that allows you to define "Commands" and "Signals". - -A signal can be thought of as a single event, that when triggered will notify a number of listeners. A command is an object with a single method named `Execute`, that will forward the request to a specific handler. - -The advantage of using Signals and Commands is that the result will often be more loosely coupled code. Given two classes A and B that need to communicate, your options are usually: - -1. Directly call a method on B from A. In this case, A is strongly coupled with B. -2. Inverse the dependency by having B observe an event on A. In this case, B is strongly coupled with A. - -Both cases result in the classes being coupled in some way. Now if instead you create a command object, which is called by A and which invokes a method on B, then the result is less coupling. Granted, A is still coupled to the command class, but in some cases that is better than being directly coupled to B. Using signals works similarly, in that you can remove the coupling by having A trigger a signal, which is observed by B. - -## Signals - -Signals are defined like this: - -```csharp -public class PressedButtonSignal : Signal -{ -} -``` - -Then in an Installer: - -```csharp -public override void InstallBindings() -{ - Container.BindSignal(); -} -``` - -Then in the firing class: - -```csharp -public class Bar -{ - readonly PressedButtonSignal _signal; - - public Bar(PressedButtonSignal signal) - { - _signal = signal; - } - - public void DoSomething() - { - _signal.Fire(); - } -} -``` - -And in the listening class: - -```csharp -public class Foo : IInitializable, IDisposable -{ - PressedButtonSignal _signal; - - public Foo1(PressedButtonSignal signal) - { - _signal = signal; - } - - public void Initialize() - { - _signal += OnPressed; - - // You can also do this which is equivalent - // _signal.Listen(OnPressed); - } - - public void Dispose() - { - _signal -= OnPressed; - - // You can also do this which is equivalent - // _signal.Unlisten(OnPressed); - } - - void OnPressed() - { - Debug.Log("Received OnPressed event"); - } -} -``` - -Signals can be especially useful for system-wide events that are not associated with any particular class. - -Something else worth noting is that signals will throw exceptions if all listeners have not properly removed themselves by the time the scene exits. So for example, if we were to remove the line `_signal -= OnPressed` from above, we would see error messages in the log. If this behaviour is too strict for your liking, you might consider commenting out the assert in the Signal.Dispose methods. - -Also note that you can add parameters to your signals by adding the parameter types to the generic arguments of the Signal base class. For example: - -```csharp -public class PressedButtonSignal : Signal -{ -} - -public class Bar -{ - readonly PressedButtonSignal _signal; - - public Bar(PressedButtonSignal signal) - { - _signal = signal; - } - - public void DoSomething() - { - _signal.Fire("some data"); - } -} - -public class Foo : IInitializable, IDisposable -{ - PressedButtonSignal _signal; - - public Foo1(PressedButtonSignal signal) - { - _signal = signal; - } - - public void Initialize() - { - _signal += OnPressed; - } - - public void Dispose() - { - _signal -= OnPressed; - } - - void OnPressed(string data) - { - Debug.Log("Received OnPressed event with data: " + data); - } -} -``` - -## Commands - -Commands are defined like this - -```csharp -public class ResetSceneCommand : Command { } - -public class ResetSceneCommandWithParameter : Command { } -``` - -Unlike with signals, there are several different ways of declaring a command in an installer. Perhaps the simplest way would be the following: - -```csharp -public override void InstallBindings() -{ - ... - Container.BindCommand().To(x => x.Reset).AsSingle(); - ... - Container.BindCommand().To(x => x.Reset).AsSingle(); - ... -} - -public class ResetSceneHandler -{ - public void Reset() - { - ... [reset scene] ... - } -} -``` - -This bind statement will result in an object of type `ResetSceneCommand` being added to the container. Any time a class calls Execute on `ResetSceneCommand`, it will trigger the Reset method on the `ResetSceneHandler` class. For example: - -```csharp -public class Foo : ITickable -{ - readonly ResetSceneCommand _command; - - public Foo(ResetSceneCommand command) - { - _command = command; - } - - public void Tick() - { - ... - _command.Execute(); - ... - } -} -``` - -We might also want to restrict usage of our command to the Foo class only, which we could do with the following - -```csharp -public override void InstallBindings() -{ - ... - Container.BindCommand().To(x => x.Reset).AsSingle().WhenInjectedInto(); - ... -} -``` - -Note that in this case we are using `AsSingle` - this means that the same instance of `ResetSceneHandler` will be used every time the command is executed. Alternatively, you could declare it using `AsTransient<>` which would instantiate a new instance of `ResetSceneHandler` every time Execute() is called. For example: - -```csharp -Container.BindCommand().To(x => x.Reset).AsTransient(); -``` - -This might be useful if the `ResetSceneCommand` class involves some long-running operations that require unique sets of member variables/dependencies. - diff --git a/NonUnityBuild/Zenject.sln b/NonUnityBuild/Zenject.sln index 0f99d8e62..2bd3743fd 100644 --- a/NonUnityBuild/Zenject.sln +++ b/NonUnityBuild/Zenject.sln @@ -1,14 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zenject", "..\UnityProject\Assets\Zenject\Source\Zenject.csproj", "{46F25A62-2E29-48CB-95F3-BDBCB0976DDC}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zenject-tests", "..\UnityProject\Assets\Zenject\OptionalExtras\UnitTests\Editor\Zenject-tests.csproj", "{34E27462-3046-4DC7-A7FA-45E4F4F7D413}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zenject.Commands", "..\UnityProject\Assets\Zenject\OptionalExtras\CommandsAndSignals\Zenject.Commands.csproj", "{B543A0B8-2630-424E-B628-53457BE4884B}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -23,10 +21,6 @@ Global {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Debug|Any CPU.Build.0 = Debug|Any CPU {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Release|Any CPU.ActiveCfg = Release|Any CPU {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Release|Any CPU.Build.0 = Release|Any CPU - {B543A0B8-2630-424E-B628-53457BE4884B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B543A0B8-2630-424E-B628-53457BE4884B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B543A0B8-2630-424E-B628-53457BE4884B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B543A0B8-2630-424E-B628-53457BE4884B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals.meta deleted file mode 100644 index 35de1d2ce..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 3e1f9bf48f02ac54595625114a7fa17d -folderAsset: yes -timeCreated: 1450373896 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command.meta deleted file mode 100644 index f34c93174..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 66354aabb2a96aa4ab8039fe67a6fd26 -folderAsset: yes -timeCreated: 1461712383 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs deleted file mode 100644 index 8d0eca4d0..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - public interface ICommand - { - } - - public class CommandSettings - { - public int MinHandlers = 0; - public int MaxHandlers = int.MaxValue; - } - - public abstract class CommandBase : ICommand - { - CommandManager _manager; - - [Inject] - void Construct(CommandManager manager, CommandSettings settings) - { - _manager = manager; - Settings = settings; - } - - protected CommandSettings Settings - { - get; - private set; - } - - protected CommandManager Manager - { - get { return _manager; } - } - - public bool HasHandler - { - get - { - return _manager.IsHandlerRegistered(this.GetType()); - } - } - } - - public abstract class Command : CommandBase - { - public void Execute() - { - Manager.Trigger(this.GetType(), Settings, new object[0]); - } - } - - public abstract class Command : CommandBase - { - public void Execute(TParam1 param1) - { - Manager.Trigger(this.GetType(), Settings, new object[] { param1 }); - } - } - - public abstract class Command : CommandBase - { - public void Execute(TParam1 param1, TParam2 param2) - { - Manager.Trigger(this.GetType(), Settings, new object[] { param1, param2 }); - } - } - - public abstract class Command : CommandBase - { - public void Execute(TParam1 param1, TParam2 param2, TParam3 param3) - { - Manager.Trigger(this.GetType(), Settings, new object[] { param1, param2, param3 }); - } - } - - public abstract class Command : CommandBase - { - public void Execute(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) - { - Manager.Trigger(this.GetType(), Settings, new object[] { param1, param2, param3, param4 }); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs deleted file mode 100644 index 7ff868ade..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Zenject -{ - public class CommandBinder : ConditionBinder - { - readonly CommandSettings _commandSettings; - - public CommandBinder( - BindInfo bindInfo, CommandSettings commandSettings) - : base(bindInfo) - { - _commandSettings = commandSettings; - } - - public ConditionBinder RequireHandler() - { - _commandSettings.MinHandlers = 1; - return this; - } - - public ConditionBinder RequireSingleHandler() - { - _commandSettings.MinHandlers = 1; - _commandSettings.MaxHandlers = 1; - return this; - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs.meta deleted file mode 100644 index 6f293a8a0..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 97866341f87495a428ecbcd9c1079daa -timeCreated: 1480716061 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs deleted file mode 100644 index 770f0c266..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - public static class CommandExtensions - { - public static CommandBinder DeclareCommand(this DiContainer container) - where T : ICommand - { - var info = new BindInfo(typeof(T)); - var commandSettings = new CommandSettings(); - container.Bind(info).AsSingle().WithArguments(commandSettings); - return new CommandBinder(info, commandSettings); - } - - public static CommandHandlerBinder HandleCommand(this DiContainer container) - where TCommand : Command - { - var binder = container.StartBinding(); - return new CommandHandlerBinder( - container, typeof(TCommand), binder); - } - - public static CommandHandlerBinder HandleCommand(this DiContainer container) - where TCommand : Command - { - var binder = container.StartBinding(); - return new CommandHandlerBinder( - container, typeof(TCommand), binder); - } - - public static CommandHandlerBinder HandleCommand(this DiContainer container) - where TCommand : Command - { - var binder = container.StartBinding(); - return new CommandHandlerBinder( - container, typeof(TCommand), binder); - } - - public static CommandHandlerBinder HandleCommand(this DiContainer container) - where TCommand : Command - { - var binder = container.StartBinding(); - return new CommandHandlerBinder( - container, typeof(TCommand), binder); - } - - public static CommandHandlerBinder HandleCommand(this DiContainer container) - where TCommand : Command - { - var binder = container.StartBinding(); - return new CommandHandlerBinder( - container, typeof(TCommand), binder); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs.meta deleted file mode 100644 index 08e616c24..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandExtensions.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 02d0b8e2a54788f45ab48bcbd031228c -timeCreated: 1480012313 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs deleted file mode 100644 index 8857073a6..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - public abstract class CommandHandlerBase : ICommandHandler, IDisposable - { - readonly CommandManager _manager; - readonly Type _commandType; - - public CommandHandlerBase( - Type commandType, CommandManager manager) - { - _manager = manager; - _commandType = commandType; - - manager.Register(commandType, this); - } - - public void Dispose() - { - _manager.Unregister(_commandType, this); - } - - protected void ValidateParameter(object value) - { - if (value == null) - { - Assert.That(!typeof(T).IsValueType()); - } - else - { - Assert.That(value.GetType().DerivesFromOrEqual()); - } - } - - public abstract void Execute(object[] args); - } -} - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs.meta deleted file mode 100644 index f3ebdb39f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBase.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4cd8e640deda28641b1bb9a9f523256a -timeCreated: 1480706613 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs deleted file mode 100644 index 2a470c1aa..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - public class CommandHandlerBinder - { - readonly BindFinalizerWrapper _finalizerWrapper; - readonly Type _commandType; - readonly DiContainer _container; - - public CommandHandlerBinder( - DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) - { - _container = container; - _commandType = commandType; - _finalizerWrapper = finalizerWrapper; - } - - public FromBinder With(Func methodGetter) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - var lookupId = Guid.NewGuid(); - var lazyLookup = new Lazy( - _container, new InjectContext(_container, typeof(THandler), lookupId)); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, methodGetter, lazyLookup); - - // By returning FromBinder, it means they can add conditions, and also - // do things like CopyIntoAllSubContainers, and NonLazy, all of which - // make no sense for command handlers, but whatever - return _container.Bind().WithId(lookupId).To(); - } - - public void WithMethod(Action method) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - _container.Bind(typeof(IDisposable)).To().AsCached() - .WithArguments(_commandType, method); - } - } - - public class CommandHandlerBinder - { - readonly BindFinalizerWrapper _finalizerWrapper; - readonly Type _commandType; - readonly DiContainer _container; - - public CommandHandlerBinder( - DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) - { - _container = container; - _commandType = commandType; - _finalizerWrapper = finalizerWrapper; - } - - public FromBinder With(Func> methodGetter) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - var lookupId = Guid.NewGuid(); - var lazyLookup = new Lazy( - _container, new InjectContext(_container, typeof(THandler), lookupId)); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); - - // By returning FromBinder, it means they can add conditions, and also - // do things like CopyIntoAllSubContainers, and NonLazy, all of which - // make no sense for command handlers, but whatever - return _container.Bind().WithId(lookupId).To(); - } - - public void WithMethod(Action method) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, method); - } - } - - public class CommandHandlerBinder - { - readonly BindFinalizerWrapper _finalizerWrapper; - readonly Type _commandType; - readonly DiContainer _container; - - public CommandHandlerBinder( - DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) - { - _container = container; - _commandType = commandType; - _finalizerWrapper = finalizerWrapper; - } - - public FromBinder With(Func> methodGetter) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - var lookupId = Guid.NewGuid(); - var lazyLookup = new Lazy( - _container, new InjectContext(_container, typeof(THandler), lookupId)); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); - - // By returning FromBinder, it means they can add conditions, and also - // do things like CopyIntoAllSubContainers, and NonLazy, all of which - // make no sense for command handlers, but whatever - return _container.Bind().WithId(lookupId).To(); - } - - public void WithMethod(Action method) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, method); - } - } - - public class CommandHandlerBinder - { - readonly BindFinalizerWrapper _finalizerWrapper; - readonly Type _commandType; - readonly DiContainer _container; - - public CommandHandlerBinder( - DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) - { - _container = container; - _commandType = commandType; - _finalizerWrapper = finalizerWrapper; - } - - public FromBinder With(Func> methodGetter) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - var lookupId = Guid.NewGuid(); - var lazyLookup = new Lazy( - _container, new InjectContext(_container, typeof(THandler), lookupId)); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); - - // By returning FromBinder, it means they can add conditions, and also - // do things like CopyIntoAllSubContainers, and NonLazy, all of which - // make no sense for command handlers, but whatever - return _container.Bind().WithId(lookupId).To(); - } - - public void WithMethod(Action method) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, method); - } - } - - public class CommandHandlerBinder - { - readonly BindFinalizerWrapper _finalizerWrapper; - readonly Type _commandType; - readonly DiContainer _container; - - public CommandHandlerBinder( - DiContainer container, Type commandType, BindFinalizerWrapper finalizerWrapper) - { - _container = container; - _commandType = commandType; - _finalizerWrapper = finalizerWrapper; - } - - public FromBinder With(Func> methodGetter) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - var lookupId = Guid.NewGuid(); - var lazyLookup = new Lazy( - _container, new InjectContext(_container, typeof(THandler), lookupId)); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, methodGetter, lazyLookup).NonLazy(); - - // By returning FromBinder, it means they can add conditions, and also - // do things like CopyIntoAllSubContainers, and NonLazy, all of which - // make no sense for command handlers, but whatever - return _container.Bind().WithId(lookupId).To(); - } - - public void WithMethod(Action method) - { - // This is just to ensure they don't stop at HandleCommand - _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); - - _container.Bind(typeof(IDisposable)).To>().AsCached() - .WithArguments(_commandType, method); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs.meta deleted file mode 100644 index c785adb29..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandHandlerBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 17b540f4075a55d44889601f66821dc2 -timeCreated: 1480710172 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs deleted file mode 100644 index b6a4bda8b..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; -using System.Linq; - -namespace Zenject -{ - public class CommandManager : ILateDisposable - { - readonly Dictionary> _commandHandlers = new Dictionary>(); - - public bool IsHandlerRegistered(Type commandType) - { - return !GetList(commandType).IsEmpty(); - } - - List GetList(Type commandType) - { - List handlers; - - if (!_commandHandlers.TryGetValue(commandType, out handlers)) - { - handlers = new List(); - _commandHandlers.Add(commandType, handlers); - } - - return handlers; - } - - public void Register(Type commandType, ICommandHandler handler) - { - GetList(commandType).Add(handler); - } - - public void Unregister(Type commandType, ICommandHandler handler) - { - GetList(commandType).RemoveWithConfirm(handler); - } - - public void LateDispose() - { - Assert.Warn(_commandHandlers.Values.SelectMany(x => x).IsEmpty(), - "Found commands still registered on CommandManager"); - } - - public void Trigger( - Type commandType, CommandSettings settings, object[] args) - { - var handlers = GetList(commandType); - - if (handlers.Count < settings.MinHandlers) - { - if (settings.MinHandlers == 0) - { - throw Assert.CreateException( - "Fired command '{0}' but no handler was registered! Command requires at least one handler.", commandType); - } - - throw Assert.CreateException( - "Command '{0}' was fired but only had {1} handlers attached (requires at least {2}).", - commandType, handlers.Count, settings.MinHandlers); - } - - if (handlers.Count > settings.MaxHandlers) - { - if (settings.MaxHandlers == 1) - { - throw Assert.CreateException( - "Found multiple handlers for command '{0}'. Was expecting only one.", commandType); - } - - throw Assert.CreateException( - "Found '{0}' handlers for command '{1}' but was expecting a max of '{2}'", - handlers.Count, commandType, settings.MaxHandlers); - } - - foreach (var handler in handlers) - { - handler.Execute(args); - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs.meta deleted file mode 100644 index ef0769175..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/CommandManager.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 18b734cfb9aee23448ab1e049882b546 -timeCreated: 1480012314 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs deleted file mode 100644 index 086b0bf54..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - public interface ICommandHandler - { - void Execute(object[] args); - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs.meta deleted file mode 100644 index 0a70117d6..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/ICommandHandler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 42eaebfe8b6a42f4295b971b28e3e8e7 -timeCreated: 1480012314 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs deleted file mode 100644 index 0343a1033..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - public abstract class InstanceMethodCommandHandlerBase : CommandHandlerBase - { - readonly Lazy _handler; - - public InstanceMethodCommandHandlerBase( - Type commandType, CommandManager manager, - Lazy handler) - : base(commandType, manager) - { - _handler = handler; - } - - public override void Execute(object[] args) - { - InternalExecute(_handler.Value, args); - } - - protected abstract void InternalExecute(THandler handler, object[] args); - } - - public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase - { - readonly Func _methodGetter; - - public InstanceMethodCommandHandler( - Type commandType, CommandManager manager, Lazy handler, - Func methodGetter) - : base(commandType, manager, handler) - { - _methodGetter = methodGetter; - } - - protected override void InternalExecute(THandler handler, object[] args) - { - Assert.That(args.IsEmpty()); - _methodGetter(handler)(); - } - } - - public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase - { - readonly Func> _methodGetter; - - public InstanceMethodCommandHandler( - Type commandType, CommandManager manager, Lazy handler, - Func> methodGetter) - : base(commandType, manager, handler) - { - _methodGetter = methodGetter; - } - - protected override void InternalExecute(THandler handler, object[] args) - { - Assert.That(args.IsLength(1)); - ValidateParameter(args[0]); - _methodGetter(handler)((TParam1)args[0]); - } - } - - public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase - { - readonly Func> _methodGetter; - - public InstanceMethodCommandHandler( - Type commandType, CommandManager manager, Lazy handler, - Func> methodGetter) - : base(commandType, manager, handler) - { - _methodGetter = methodGetter; - } - - protected override void InternalExecute(THandler handler, object[] args) - { - Assert.That(args.IsLength(2)); - ValidateParameter(args[0]); - ValidateParameter(args[1]); - _methodGetter(handler)((TParam1)args[0], (TParam2)args[1]); - } - } - - public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase - { - readonly Func> _methodGetter; - - public InstanceMethodCommandHandler( - Type commandType, CommandManager manager, Lazy handler, - Func> methodGetter) - : base(commandType, manager, handler) - { - _methodGetter = methodGetter; - } - - protected override void InternalExecute(THandler handler, object[] args) - { - Assert.That(args.IsLength(3)); - ValidateParameter(args[0]); - ValidateParameter(args[1]); - ValidateParameter(args[2]); - _methodGetter(handler)((TParam1)args[0], (TParam2)args[1], (TParam3)args[2]); - } - } - - public class InstanceMethodCommandHandler : InstanceMethodCommandHandlerBase - { - readonly Func> _methodGetter; - - public InstanceMethodCommandHandler( - Type commandType, CommandManager manager, Lazy handler, - Func> methodGetter) - : base(commandType, manager, handler) - { - _methodGetter = methodGetter; - } - - protected override void InternalExecute(THandler handler, object[] args) - { - Assert.That(args.IsLength(4)); - ValidateParameter(args[0]); - ValidateParameter(args[1]); - ValidateParameter(args[2]); - ValidateParameter(args[3]); - _methodGetter(handler)((TParam1)args[0], (TParam2)args[1], (TParam3)args[2], (TParam4)args[3]); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs.meta deleted file mode 100644 index ca25c09f0..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/InstanceMethodCommandHandler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: bfd160dc5b2a55749a48efad7ce2f5f5 -timeCreated: 1480706613 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs deleted file mode 100644 index bbfe5aee1..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - public class StaticMethodCommandHandler : CommandHandlerBase - { - readonly Action _method; - - public StaticMethodCommandHandler( - Type commandType, CommandManager manager, Action method) - : base(commandType, manager) - { - _method = method; - } - - public override void Execute(object[] args) - { - Assert.That(args.IsEmpty()); - _method(); - } - } - - public class StaticMethodCommandHandler : CommandHandlerBase - { - readonly Action _method; - - public StaticMethodCommandHandler( - Type commandType, CommandManager manager, Action method) - : base(commandType, manager) - { - _method = method; - } - - public override void Execute(object[] args) - { - Assert.That(args.IsLength(1)); - ValidateParameter(args[0]); - _method((TParam1)args[0]); - } - } - - public class StaticMethodCommandHandler : CommandHandlerBase - { - readonly Action _method; - - public StaticMethodCommandHandler( - Type commandType, CommandManager manager, Action method) - : base(commandType, manager) - { - _method = method; - } - - public override void Execute(object[] args) - { - Assert.That(args.IsLength(1)); - ValidateParameter(args[0]); - ValidateParameter(args[1]); - _method((TParam1)args[0], (TParam2)args[1]); - } - } - - public class StaticMethodCommandHandler : CommandHandlerBase - { - readonly Action _method; - - public StaticMethodCommandHandler( - Type commandType, CommandManager manager, Action method) - : base(commandType, manager) - { - _method = method; - } - - public override void Execute(object[] args) - { - Assert.That(args.IsLength(1)); - ValidateParameter(args[0]); - ValidateParameter(args[1]); - ValidateParameter(args[2]); - _method((TParam1)args[0], (TParam2)args[1], (TParam3)args[2]); - } - } - - public class StaticMethodCommandHandler : CommandHandlerBase - { - readonly Action _method; - - public StaticMethodCommandHandler( - Type commandType, CommandManager manager, Action method) - : base(commandType, manager) - { - _method = method; - } - - public override void Execute(object[] args) - { - Assert.That(args.IsLength(1)); - ValidateParameter(args[0]); - ValidateParameter(args[1]); - ValidateParameter(args[2]); - ValidateParameter(args[3]); - _method((TParam1)args[0], (TParam2)args[1], (TParam3)args[2], (TParam4)args[3]); - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs.meta deleted file mode 100644 index 5221de578..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/StaticMethodCommandHandler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 580e348b9ad6fb547b573960c6eda204 -timeCreated: 1480706613 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal.meta deleted file mode 100644 index da86fa051..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: de778852ddb6b4f42be3815cba433146 -folderAsset: yes -timeCreated: 1461712383 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/ISignal.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/ISignal.cs deleted file mode 100644 index ed5ff4e78..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/ISignal.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text; -using ModestTree; - -namespace Zenject -{ - public interface ISignal : ILateDisposable - { - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal0.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal0.cs deleted file mode 100644 index 8162dfc4a..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal0.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using ModestTree; -using ModestTree.Util; -//using UniRx; - -namespace Zenject -{ - // Zero Parameters - public abstract class Signal : ISignal - where TDerived : Signal - { - readonly List _listeners = new List(); - //readonly Subject _stream = new Subject(); - - bool _hasDisposed; - - //public IObservableRx Stream - //{ - //get - //{ - //return _stream; - //} - //} - - public void Listen(Action listener) - { - Assert.That(!_listeners.Contains(listener), - () => "Tried to add method '{0}' to signal '{1}' but it has already been added" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - _listeners.Add(listener); - } - - public void Unlisten(Action listener) - { - bool success = _listeners.Remove(listener); - - Assert.That(success, - () => "Tried to remove method '{0}' from signal '{1}' without adding it first" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - } - - void ILateDisposable.LateDispose() - { - Assert.That(!_hasDisposed, "Tried to dispose signal '{0}' twice", this.GetType().Name); - _hasDisposed = true; - - // If you don't want to verify that all event handlers have been removed feel free to comment out this assert or remove - Assert.Warn(_listeners.IsEmpty(), - () => "Found {0} methods still added to signal '{1}'. Methods: {2}" - .Fmt(_listeners.Count, this.GetType().Name, _listeners.Select(x => x.ToDebugString()).Join(", "))); - } - - public static TDerived operator + (Signal signal, Action listener) - { - signal.Listen(listener); - return (TDerived)signal; - } - - public static TDerived operator - (Signal signal, Action listener) - { - signal.Unlisten(listener); - return (TDerived)signal; - } - - public void Fire() - { - // Use ToArray in case they remove in the handler - foreach (var listener in _listeners.ToArray()) - { - listener(); - } - - //_stream.OnNext(); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal1.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal1.cs deleted file mode 100644 index bf3b001fd..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal1.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using ModestTree; -using ModestTree.Util; -//using UniRx; - -namespace Zenject -{ - // One Parameter - public abstract class Signal : ISignal - where TDerived : Signal - { - readonly List> _listeners = new List>(); - //readonly Subject _stream = new Subject(); - - bool _hasDisposed; - - //public IObservableRx Stream - //{ - //get - //{ - //return _stream; - //} - //} - - public void Listen(Action listener) - { - Assert.That(!_listeners.Contains(listener), - () => "Tried to add method '{0}' to signal '{1}' but it has already been added" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - _listeners.Add(listener); - } - - public void Unlisten(Action listener) - { - bool success = _listeners.Remove(listener); - - Assert.That(success, - () => "Tried to remove method '{0}' from signal '{1}' without adding it first" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - } - - void ILateDisposable.LateDispose() - { - Assert.That(!_hasDisposed, "Tried to dispose signal '{0}' twice", this.GetType().Name); - _hasDisposed = true; - - // If you don't want to verify that all event handlers have been removed feel free to comment out this assert or remove - Assert.Warn(_listeners.IsEmpty(), - () => "Found {0} methods still added to signal '{1}'. Methods: {2}" - .Fmt(_listeners.Count, this.GetType().Name, _listeners.Select(x => x.ToDebugString()).Join(", "))); - } - - public static TDerived operator + (Signal signal, Action listener) - { - signal.Listen(listener); - return (TDerived)signal; - } - - public static TDerived operator - (Signal signal, Action listener) - { - signal.Unlisten(listener); - return (TDerived)signal; - } - - public void Fire(TParam1 p1) - { - // Use ToArray in case they remove in the handler - foreach (var listener in _listeners.ToArray()) - { - listener(p1); - } - - //_stream.OnNext(p1); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal1.cs.meta deleted file mode 100644 index a8d6ea209..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal1.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 259983d7c548d5c43858e5cb101d21b8 -timeCreated: 1477950441 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal2.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal2.cs deleted file mode 100644 index 345a359e4..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal2.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using ModestTree; -using ModestTree.Util; -//using UniRx; - -namespace Zenject -{ - // Two Parameters - public abstract class Signal : ISignal - where TDerived : Signal - { - readonly List> _listeners = new List>(); - - //readonly Subject> _stream = new Subject>(); - - bool _hasDisposed; - - //public IObservableRx> Stream - //{ - //get - //{ - //return _stream; - //} - //} - - public void Listen(Action listener) - { - Assert.That(!_listeners.Contains(listener), - () => "Tried to add method '{0}' to signal '{1}' but it has already been added" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - _listeners.Add(listener); - } - - public void Unlisten(Action listener) - { - bool success = _listeners.Remove(listener); - Assert.That(success, - () => "Tried to remove method '{0}' from signal '{1}' without adding it first" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - } - - void ILateDisposable.LateDispose() - { - Assert.That(!_hasDisposed, "Tried to dispose signal '{0}' twice", this.GetType().Name); - _hasDisposed = true; - - // If you don't want to verify that all event handlers have been removed feel free to comment out this assert or remove - Assert.Warn(_listeners.IsEmpty(), - () => "Found {0} methods still added to signal '{1}'. Methods: {2}" - .Fmt(_listeners.Count, this.GetType().Name, _listeners.Select(x => x.ToDebugString()).Join(", "))); - } - - public static TDerived operator + (Signal signal, Action listener) - { - signal.Listen(listener); - return (TDerived)signal; - } - - public static TDerived operator - (Signal signal, Action listener) - { - signal.Unlisten(listener); - return (TDerived)signal; - } - - public void Fire(TParam1 p1, TParam2 p2) - { - // Use ToArray in case they remove in the handler - foreach (var listener in _listeners.ToArray()) - { - listener(p1, p2); - } - - //_stream.OnNext(ValuePair.New(p1, p2)); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal2.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal2.cs.meta deleted file mode 100644 index 597cb515f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal2.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4099eaf9d41d8fb4c803a3a69a11b208 -timeCreated: 1477950441 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal3.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal3.cs deleted file mode 100644 index 5094cee1c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal3.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using ModestTree; -using ModestTree.Util; -//using UniRx; - -namespace Zenject -{ - // Three Parameters - public abstract class Signal : ISignal - where TDerived : Signal - { - readonly List> _listeners = new List>(); - //readonly Subject> _stream = new Subject>(); - - bool _hasDisposed; - - //public IObservableRx> Stream - //{ - //get - //{ - //return _stream; - //} - //} - - public void Listen(Action listener) - { - Assert.That(!_listeners.Contains(listener), - () => "Tried to add method '{0}' to signal '{1}' but it has already been added" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - _listeners.Add(listener); - } - - public void Unlisten(Action listener) - { - bool success = _listeners.Remove(listener); - Assert.That(success, - () => "Tried to remove method '{0}' from signal '{1}' without adding it first" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - } - - void ILateDisposable.LateDispose() - { - Assert.That(!_hasDisposed, "Tried to dispose signal '{0}' twice", this.GetType().Name); - _hasDisposed = true; - - // If you don't want to verify that all event handlers have been removed feel free to comment out this assert or remove - Assert.Warn(_listeners.IsEmpty(), - () => "Found {0} methods still added to signal '{1}'. Methods: {2}" - .Fmt(_listeners.Count, this.GetType().Name, _listeners.Select(x => x.ToDebugString()).Join(", "))); - } - - public static TDerived operator + (Signal signal, Action listener) - { - signal.Listen(listener); - return (TDerived)signal; - } - - public static TDerived operator - (Signal signal, Action listener) - { - signal.Unlisten(listener); - return (TDerived)signal; - } - - public void Fire(TParam1 p1, TParam2 p2, TParam3 p3) - { - // Use ToArray in case they remove in the handler - foreach (var listener in _listeners.ToArray()) - { - listener(p1, p2, p3); - } - - //_stream.OnNext(ValuePair.New(p1, p2, p3)); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal3.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal3.cs.meta deleted file mode 100644 index 8d0c03b0c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal3.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f0804c2320dea0949b4470f9357f15d4 -timeCreated: 1477950441 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal4.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal4.cs deleted file mode 100644 index fb93bf33b..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal4.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using ModestTree; -using ModestTree.Util; - -namespace Zenject -{ - // Four Parameters - public abstract class Signal : ISignal - where TDerived : Signal - { - readonly List> _listeners = new List>(); - - bool _hasDisposed; - - public void Listen(Action listener) - { - Assert.That(!_listeners.Contains(listener), - () => "Tried to add method '{0}' to signal '{1}' but it has already been added" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - _listeners.Add(listener); - } - - public void Unlisten(Action listener) - { - bool success = _listeners.Remove(listener); - Assert.That(success, - () => "Tried to remove method '{0}' from signal '{1}' without adding it first" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - } - - void ILateDisposable.LateDispose() - { - Assert.That(!_hasDisposed, "Tried to dispose signal '{0}' twice", this.GetType().Name); - _hasDisposed = true; - - // If you don't want to verify that all event handlers have been removed feel free to comment out this assert or remove - Assert.Warn(_listeners.IsEmpty(), - () => "Found {0} methods still added to signal '{1}'. Methods: {2}" - .Fmt(_listeners.Count, this.GetType().Name, _listeners.Select(x => x.ToDebugString()).Join(", "))); - } - - public static TDerived operator + (Signal signal, Action listener) - { - signal.Listen(listener); - return (TDerived)signal; - } - - public static TDerived operator - (Signal signal, Action listener) - { - signal.Unlisten(listener); - return (TDerived)signal; - } - - public void Fire(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4) - { - // Use ToArray in case they remove in the handler - foreach (var listener in _listeners.ToArray()) - { - listener(p1, p2, p3, p4); - } - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal4.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal4.cs.meta deleted file mode 100644 index a0904edad..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal4.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: ebbbe23aa5719064f9a897a7fe8346eb -timeCreated: 1477950441 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal5.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal5.cs deleted file mode 100644 index bed3942a3..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal5.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using ModestTree; -using ModestTree.Util; - -namespace Zenject -{ - // Five Parameters - public abstract class Signal : ISignal - where TDerived : Signal - { - readonly List> _listeners = new List>(); - - bool _hasDisposed; - - public void Listen(ModestTree.Util.Action listener) - { - Assert.That(!_listeners.Contains(listener), - () => "Tried to add method '{0}' to signal '{1}' but it has already been added" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - _listeners.Add(listener); - } - - public void Unlisten(ModestTree.Util.Action listener) - { - bool success = _listeners.Remove(listener); - Assert.That(success, - () => "Tried to remove method '{0}' from signal '{1}' without adding it first" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - } - - void ILateDisposable.LateDispose() - { - Assert.That(!_hasDisposed, "Tried to dispose signal '{0}' twice", this.GetType().Name); - _hasDisposed = true; - - // If you don't want to verify that all event handlers have been removed feel free to comment out this assert or remove - Assert.Warn(_listeners.IsEmpty(), - () => "Found {0} methods still added to signal '{1}'. Methods: {2}" - .Fmt(_listeners.Count, this.GetType().Name, _listeners.Select(x => x.ToDebugString()).Join(", "))); - } - - public static TDerived operator + (Signal signal, ModestTree.Util.Action listener) - { - signal.Listen(listener); - return (TDerived)signal; - } - - public static TDerived operator - (Signal signal, ModestTree.Util.Action listener) - { - signal.Unlisten(listener); - return (TDerived)signal; - } - - public void Fire(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TParam5 p5) - { - // Use ToArray in case they remove in the handler - foreach (var listener in _listeners.ToArray()) - { - listener(p1, p2, p3, p4, p5); - } - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal5.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal5.cs.meta deleted file mode 100644 index 6b361bd79..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal5.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 0bf5711a0b4ee3f4e9b088f8214c5d1c -timeCreated: 1477950441 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal6.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal6.cs deleted file mode 100644 index a7a557fae..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal6.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using ModestTree; -using ModestTree.Util; - -namespace Zenject -{ - // Six Parameters - public abstract class Signal : ISignal - where TDerived : Signal - { - readonly List> _listeners = new List>(); - - bool _hasDisposed; - - public void Listen(ModestTree.Util.Action listener) - { - Assert.That(!_listeners.Contains(listener), - () => "Tried to add method '{0}' to signal '{1}' but it has already been added" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - _listeners.Add(listener); - } - - public void Unlisten(ModestTree.Util.Action listener) - { - bool success = _listeners.Remove(listener); - - Assert.That(success, - () => "Tried to remove method '{0}' from signal '{1}' without adding it first" - .Fmt(listener.ToDebugString(), this.GetType().Name)); - } - - void ILateDisposable.LateDispose() - { - Assert.That(!_hasDisposed, "Tried to dispose signal '{0}' twice", this.GetType().Name); - _hasDisposed = true; - - // If you don't want to verify that all event handlers have been removed feel free to comment out this assert or remove - Assert.Warn(_listeners.IsEmpty(), - () => "Found {0} methods still added to signal '{1}'. Methods: {2}" - .Fmt(_listeners.Count, this.GetType().Name, _listeners.Select(x => x.ToDebugString()).Join(", "))); - } - - public static TDerived operator + (Signal signal, ModestTree.Util.Action listener) - { - signal.Listen(listener); - return (TDerived)signal; - } - - public static TDerived operator - (Signal signal, ModestTree.Util.Action listener) - { - signal.Unlisten(listener); - return (TDerived)signal; - } - - public void Fire(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TParam5 p5, TParam6 p6) - { - // Use ToArray in case they remove in the handler - foreach (var listener in _listeners.ToArray()) - { - listener(p1, p2, p3, p4, p5, p6); - } - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal6.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal6.cs.meta deleted file mode 100644 index b429c8fc2..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal6.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3035af34e5d7fef4bbabae05325e90bb -timeCreated: 1477950441 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/SignalExtensions.cs b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/SignalExtensions.cs deleted file mode 100644 index 5e388886d..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/SignalExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace Zenject -{ - public static class SignalExtensions - { - public static void BindSignal(this DiContainer container) - where TSignal : ISignal - { - container.Bind().AsSingle(); - - // Uncomment this if you want to see warnings when the signal is destroyed and - // there are still listeners on it - //container.Bind().To().AsSingle(); - } - - public static void BindSignal(this DiContainer container, string identifier) - where TSignal : ISignal - { - container.Bind().WithId(identifier).AsSingle(identifier); - - // Uncomment this if you want to see warnings when the signal is destroyed and - // there are still listeners on it - //container.Bind().To().FromResolve(identifier); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/SignalExtensions.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/SignalExtensions.cs.meta deleted file mode 100644 index e07b8cbc8..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/SignalExtensions.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: b977e62b9e678de4597b1fdb5d3e25ab -timeCreated: 1477937140 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj deleted file mode 100644 index 1a77a37e1..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj +++ /dev/null @@ -1,81 +0,0 @@ - - - - - Debug - AnyCPU - {B543A0B8-2630-424E-B628-53457BE4884B} - Library - Properties - Zenject - Zenject.Commands - v3.5 - 512 - - - - true - full - false - ..\..\..\..\..\NonUnityBuild\Temp\Debug\ - ..\..\..\..\..\NonUnityBuild\Temp\Debug\ - ..\..\..\..\..\NonUnityBuild\Bin\Debug\ - TRACE;DEBUG;NOT_UNITY3D - prompt - 4 - - - pdbonly - true - ..\..\..\..\..\NonUnityBuild\Temp\Release\ - ..\..\..\..\..\NonUnityBuild\Temp\Release\ - ..\..\..\..\..\NonUnityBuild\Bin\Release\ - TRACE;NOT_UNITY3D - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {46f25a62-2e29-48cb-95f3-bdbcb0976ddc} - Zenject - - - - - \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj.meta deleted file mode 100644 index 34c2580b9..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 46f9bd498d9be824d9781a5ae8426734 -timeCreated: 1461878212 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj.user.meta b/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj.user.meta deleted file mode 100644 index 6cf7ed64c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Zenject.Commands.csproj.user.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: cadb0e866c5788a4ba0aa4f054e8e6e6 -timeCreated: 1478450388 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity index de6ec451f..2057434c7 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity @@ -1,15 +1,15 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!29 &1 -SceneSettings: +OcclusionCullingSettings: m_ObjectHideFlags: 0 - m_PVSData: - m_PVSObjectsArray: [] - m_PVSPortalsArray: [] + serializedVersion: 2 m_OcclusionBakeSettings: smallestOccluder: 5 smallestHole: 0.25 backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} --- !u!104 &2 RenderSettings: m_ObjectHideFlags: 0 @@ -79,25 +79,68 @@ NavMeshSettings: m_ObjectHideFlags: 0 m_BuildSettings: serializedVersion: 2 + agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 agentSlope: 45 agentClimb: 0.4 ledgeDropHeight: 0 maxJumpAcrossDistance: 0 - accuratePlacement: 0 minRegionArea: 2 - cellSize: 0.16666666 manualCellSize: 0 + cellSize: 0.16666666 + accuratePlacement: 0 m_NavMeshData: {fileID: 0} +--- !u!1001 &153561211 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + propertyPath: m_LocalRotation.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + propertyPath: m_LocalRotation.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + propertyPath: m_LocalRotation.z + value: -0.5 + objectReference: {fileID: 0} + - target: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + propertyPath: m_LocalRotation.w + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + propertyPath: m_RootOrder + value: 3 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} + m_IsPrefabParent: 0 --- !u!1 &374077285 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 374077286} + - component: {fileID: 374077286} m_Layer: 0 m_Name: Scene m_TagString: Untagged @@ -114,22 +157,22 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 1907929669} - {fileID: 1495790307} - {fileID: 539277935} m_Father: {fileID: 0} m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &539277933 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 539277935} - - 108: {fileID: 539277934} + - component: {fileID: 539277935} + - component: {fileID: 539277934} m_Layer: 0 m_Name: Directional light m_TagString: Untagged @@ -180,150 +223,20 @@ Transform: m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.10938166, w: 0.8754261} m_LocalPosition: {x: -2.5247688, y: 0.1344086, z: 2.1533628} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 374077286} m_RootOrder: 2 ---- !u!1 &722930540 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 100000, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 - m_Component: - - 4: {fileID: 722930544} - - 15: {fileID: 722930541} - - 12: {fileID: 722930543} - - 26: {fileID: 722930542} - m_Layer: 8 - m_Name: Fire - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!15 &722930541 -EllipsoidParticleEmitter: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 1500000, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, - type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 722930540} - serializedVersion: 2 - m_Enabled: 1 - m_Emit: 1 - minSize: 0.2 - maxSize: 0.4 - minEnergy: 0.2 - maxEnergy: 0.4 - minEmission: 40 - maxEmission: 60 - worldVelocity: {x: 0, y: 0, z: 0} - localVelocity: {x: 0, y: 1.8000001, z: 0} - rndVelocity: {x: 0.120000005, y: 0.6, z: 0.120000005} - emitterVelocityScale: 0.05 - tangentVelocity: {x: 0, y: 0, z: 0} - angularVelocity: 0 - rndAngularVelocity: 100 - rndRotation: 1 - Simulate in Worldspace?: 1 - m_OneShot: 0 - m_Ellipsoid: {x: 0, y: 0, z: 0} - m_MinEmitterRange: 0 ---- !u!26 &722930542 -ParticleRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 2600000, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, - type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 722930540} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 1 - m_Materials: - - {fileID: 2100000, guid: 0babe53ca63bb49209164496ab5e4231, type: 2} - m_SubsetIndices: - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingOrder: 0 - serializedVersion: 2 - m_CameraVelocityScale: 0 - m_StretchParticles: 3 - m_LengthScale: -2 - m_VelocityScale: 0 - m_MaxParticleSize: Infinity - UV Animation: - x Tile: 1 - y Tile: 1 - cycles: 1 ---- !u!12 &722930543 -ParticleAnimator: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 1200000, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, - type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 722930540} - Does Animate Color?: 1 - colorAnimation[0]: - serializedVersion: 2 - rgba: 184542099 - colorAnimation[1]: - serializedVersion: 2 - rgba: 4294962290 - colorAnimation[2]: - serializedVersion: 2 - rgba: 4287922990 - colorAnimation[3]: - serializedVersion: 2 - rgba: 1292855184 - colorAnimation[4]: - serializedVersion: 2 - rgba: 985629450 - worldRotationAxis: {x: 0, y: 0, z: 0} - localRotationAxis: {x: 0, y: 0, z: 0} - sizeGrow: 20 - rndForce: {x: 0, y: 0, z: 0} - force: {x: 0, y: 0, z: 0} - damping: 1 - stopSimulation: 0 - autodestruct: 0 ---- !u!4 &722930544 -Transform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 400000, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 722930540} - m_LocalRotation: {x: 0.50000006, y: 0.50000006, z: 0.49999994, w: 0.49999994} - m_LocalPosition: {x: 0.004717404, y: -0, z: 0.030425942} - m_LocalScale: {x: 0.42857146, y: 0.4285713, z: 0.4285713} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_Children: [] - m_Father: {fileID: 1166955095} - m_RootOrder: 1 --- !u!1 &805392154 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 805392155} - - 114: {fileID: 805392156} - - 114: {fileID: 805392157} + - component: {fileID: 805392155} + - component: {fileID: 805392156} + - component: {fileID: 805392157} m_Layer: 0 m_Name: SceneContext m_TagString: Untagged @@ -340,10 +253,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &805392156 MonoBehaviour: m_ObjectHideFlags: 0 @@ -375,91 +288,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ac59283f2813c5643a2495056b74c1c0, type: 3} m_Name: m_EditorClassIdentifier: ---- !u!1 &1166955091 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 100008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 - m_Component: - - 4: {fileID: 1166955095} - - 65: {fileID: 1166955093} - - 114: {fileID: 1166955096} - - 114: {fileID: 1166955092} - m_Layer: 8 - m_Name: Ship - m_TagString: ship - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1166955092 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1166955091} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0166d8ff8d905b048b2448179e1f5d11, type: 3} - m_Name: - m_EditorClassIdentifier: - _components: - - {fileID: 1166955096} - _identifier: - _context: {fileID: 0} - _bindType: 0 ---- !u!65 &1166955093 -BoxCollider: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 6500002, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, - type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1166955091} - m_Material: {fileID: 0} - m_IsTrigger: 1 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 0.39, y: 0.21, z: 0.69} - m_Center: {x: 0, y: 0, z: 0} ---- !u!4 &1166955095 -Transform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 400008, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1166955091} - m_LocalRotation: {x: 0.5, y: 0.5, z: -0.5, w: 0.5} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.7, y: 0.7, z: 0.7} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 1511966312} - - {fileID: 722930544} - m_Father: {fileID: 0} - m_RootOrder: 3 ---- !u!114 &1166955096 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1166955091} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: aab42c7e45a13404daf7de27c7366efc, type: 3} - m_Name: - m_EditorClassIdentifier: - _meshRenderer: {fileID: 1511966314} - _particleEmitter: {fileID: 722930541} --- !u!1 &1194014231 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 1194014232} - - 114: {fileID: 1194014233} - - 114: {fileID: 1194014234} + - component: {fileID: 1194014232} + - component: {fileID: 1194014233} + - component: {fileID: 1194014234} m_Layer: 0 m_Name: Gui m_TagString: Untagged @@ -476,10 +314,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 3.0068893, y: -1.6959872, z: 7.0009694} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1194014233 MonoBehaviour: m_ObjectHideFlags: 0 @@ -784,17 +622,17 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 1495790307} - - 114: {fileID: 1495790309} - - 20: {fileID: 1495790306} - - 92: {fileID: 1495790305} - - 124: {fileID: 1495790304} - - 81: {fileID: 1495790303} - - 114: {fileID: 1495790310} - - 82: {fileID: 1495790308} - - 82: {fileID: 1495790311} + - component: {fileID: 1495790307} + - component: {fileID: 1495790309} + - component: {fileID: 1495790306} + - component: {fileID: 1495790305} + - component: {fileID: 1495790304} + - component: {fileID: 1495790303} + - component: {fileID: 1495790310} + - component: {fileID: 1495790308} + - component: {fileID: 1495790311} m_Layer: 0 m_Name: Camera m_TagString: MainCamera @@ -866,10 +704,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: -11.627775} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 374077286} m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!82 &1495790308 AudioSource: m_ObjectHideFlags: 0 @@ -886,6 +724,7 @@ AudioSource: Loop: 1 Mute: 0 Spatialize: 0 + SpatializePostEffects: 0 Priority: 128 DopplerLevel: 1 MinDistance: 1 @@ -898,12 +737,14 @@ AudioSource: rolloffCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -914,7 +755,8 @@ AudioSource: panLevelCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 @@ -925,7 +767,8 @@ AudioSource: spreadCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 @@ -936,7 +779,8 @@ AudioSource: reverbZoneMixCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 @@ -992,6 +836,7 @@ AudioSource: Loop: 0 Mute: 0 Spatialize: 0 + SpatializePostEffects: 0 Priority: 128 DopplerLevel: 1 MinDistance: 1 @@ -1004,12 +849,14 @@ AudioSource: rolloffCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1020,7 +867,8 @@ AudioSource: panLevelCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 @@ -1031,7 +879,8 @@ AudioSource: spreadCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 @@ -1042,7 +891,8 @@ AudioSource: reverbZoneMixCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 @@ -1050,86 +900,18 @@ AudioSource: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 0 ---- !u!1 &1511966311 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 100006, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 - m_Component: - - 4: {fileID: 1511966312} - - 33: {fileID: 1511966313} - - 23: {fileID: 1511966314} - m_Layer: 8 - m_Name: Renderer - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1511966312 -Transform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 400006, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1511966311} - m_LocalRotation: {x: -0.7071068, y: -0.7071068, z: 0, w: 0} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.044991173, y: 0.04499118, z: 0.044991173} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_Children: [] - m_Father: {fileID: 1166955095} - m_RootOrder: 0 ---- !u!33 &1511966313 -MeshFilter: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 3300000, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, - type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1511966311} - m_Mesh: {fileID: 4300000, guid: 564c86c1543c6eb4e8525374599f15cc, type: 3} ---- !u!23 &1511966314 -MeshRenderer: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 2300000, guid: f4cdd74364fb9d6448ecf7663dd0cfe9, - type: 2} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1511966311} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 1 - m_Materials: - - {fileID: 2100000, guid: a0e138ce6cd06f74d83cf3884415be92, type: 2} - m_SubsetIndices: - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingOrder: 0 --- !u!1 &1907929665 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 1907929669} - - 33: {fileID: 1907929668} - - 64: {fileID: 1907929667} - - 23: {fileID: 1907929666} - - 114: {fileID: 1907929670} + - component: {fileID: 1907929669} + - component: {fileID: 1907929668} + - component: {fileID: 1907929667} + - component: {fileID: 1907929666} + - component: {fileID: 1907929670} m_Layer: 0 m_Name: Background m_TagString: Untagged @@ -1151,7 +933,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: f96f18654fcb0a742b51183dab201105, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -1159,7 +943,7 @@ MeshRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -1177,6 +961,8 @@ MeshCollider: m_Enabled: 1 serializedVersion: 2 m_Convex: 0 + m_InflateMesh: 0 + m_SkinWidth: 0.01 m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} --- !u!33 &1907929668 MeshFilter: @@ -1194,10 +980,10 @@ Transform: m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068} m_LocalPosition: {x: 0, y: 0, z: 6.5125256} m_LocalScale: {x: 5.9777775, y: 2.2373586, z: 4} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 374077286} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1907929670 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Asteroid.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Asteroid.prefab index f3b464aae..333e4f940 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Asteroid.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Asteroid.prefab @@ -5,14 +5,14 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400000} - - 33: {fileID: 3300000} - - 23: {fileID: 2300000} - - 54: {fileID: 5400000} - - 135: {fileID: 13500000} - - 114: {fileID: 11400000} + - component: {fileID: 400000} + - component: {fileID: 3300000} + - component: {fileID: 2300000} + - component: {fileID: 5400000} + - component: {fileID: 13500000} + - component: {fileID: 11400000} m_Layer: 9 m_Name: Asteroid m_TagString: asteroid @@ -29,10 +29,10 @@ Transform: m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &2300000 MeshRenderer: m_ObjectHideFlags: 1 @@ -47,7 +47,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: a1f30c6b2183c3f4a9ffa3cb444d6ddc, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -55,7 +57,7 @@ MeshRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Explosion.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Explosion.prefab index c4db1ae33..3900cdfd0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Explosion.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Explosion.prefab @@ -5,9 +5,9 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400000} + - component: {fileID: 400000} m_Layer: 0 m_Name: Explosion m_TagString: Untagged @@ -20,12 +20,12 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400004} - - 15: {fileID: 1500002} - - 12: {fileID: 1200002} - - 26: {fileID: 2600002} + - component: {fileID: 400004} + - component: {fileID: 1500002} + - component: {fileID: 1200002} + - component: {fileID: 2600002} m_Layer: 0 m_Name: Fire m_TagString: Untagged @@ -38,12 +38,12 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400002} - - 15: {fileID: 1500000} - - 12: {fileID: 1200000} - - 26: {fileID: 2600000} + - component: {fileID: 400002} + - component: {fileID: 1500000} + - component: {fileID: 1200000} + - component: {fileID: 2600000} m_Layer: 0 m_Name: Smoke m_TagString: Untagged @@ -60,12 +60,12 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 400004} - {fileID: 400002} m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400002 Transform: m_ObjectHideFlags: 1 @@ -75,10 +75,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0.13954875, y: 0.7529835, z: -1.1806568} m_LocalScale: {x: 0.65, y: 0.65, z: 0.65} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 400000} m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400004 Transform: m_ObjectHideFlags: 1 @@ -88,10 +88,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0.13954875, y: 0.7529835, z: -1.1806568} m_LocalScale: {x: 0.65, y: 0.65, z: 0.65} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 400000} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!12 &1200000 ParticleAnimator: m_ObjectHideFlags: 1 @@ -220,7 +220,9 @@ ParticleRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: eb5315e2f77c540b6bf545720e84d3a5, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -228,7 +230,7 @@ ParticleRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -259,7 +261,9 @@ ParticleRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 0babe53ca63bb49209164496ab5e4231, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -267,7 +271,7 @@ ParticleRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Ship.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Ship.prefab index 83d679f5f..cc467b056 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Ship.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/Ship.prefab @@ -2,15 +2,15 @@ %TAG !u! tag:unity3d.com,2011: --- !u!1 &100000 GameObject: - m_ObjectHideFlags: 1 + m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400000} - - 15: {fileID: 1500000} - - 12: {fileID: 1200000} - - 26: {fileID: 2600000} + - component: {fileID: 400000} + - component: {fileID: 1500000} + - component: {fileID: 1200000} + - component: {fileID: 2600000} m_Layer: 8 m_Name: Fire m_TagString: Untagged @@ -23,11 +23,11 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400006} - - 33: {fileID: 3300000} - - 23: {fileID: 2300000} + - component: {fileID: 400006} + - component: {fileID: 3300000} + - component: {fileID: 2300000} m_Layer: 8 m_Name: Renderer m_TagString: Untagged @@ -40,12 +40,12 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400008} - - 82: {fileID: 8200000} - - 65: {fileID: 6500002} - - 114: {fileID: 11400000} + - component: {fileID: 400008} + - component: {fileID: 6500002} + - component: {fileID: 114952695426007222} + - component: {fileID: 114063788560133230} m_Layer: 8 m_Name: Ship m_TagString: ship @@ -59,12 +59,13 @@ Transform: m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 100000} - m_LocalRotation: {x: 0.7071067, y: 0, z: 0, w: -0.7071069} - m_LocalPosition: {x: -0.000000024998723, y: 0.104851745, z: -0.6762645} - m_LocalScale: {x: 9.525678, y: 9.525674, z: 9.525674} + m_LocalRotation: {x: 0.50000006, y: 0.50000006, z: 0.49999994, w: 0.49999994} + m_LocalPosition: {x: 0.004717404, y: -0, z: 0.030425942} + m_LocalScale: {x: 0.42857146, y: 0.4285713, z: 0.4285713} m_Children: [] - m_Father: {fileID: 400006} - m_RootOrder: 0 + m_Father: {fileID: 400008} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400006 Transform: m_ObjectHideFlags: 1 @@ -74,10 +75,10 @@ Transform: m_LocalRotation: {x: -0.7071068, y: -0.7071068, z: 0, w: 0} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0.044991173, y: 0.04499118, z: 0.044991173} - m_Children: - - {fileID: 400000} + m_Children: [] m_Father: {fileID: 400008} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400008 Transform: m_ObjectHideFlags: 1 @@ -89,8 +90,10 @@ Transform: m_LocalScale: {x: 0.7, y: 0.7, z: 0.7} m_Children: - {fileID: 400006} + - {fileID: 400000} m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!12 &1200000 ParticleAnimator: m_ObjectHideFlags: 1 @@ -157,17 +160,22 @@ MeshRenderer: m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: a0e138ce6cd06f74d83cf3884415be92, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 0 - m_ReflectionProbeUsage: 1 m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -183,17 +191,22 @@ ParticleRenderer: m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 0babe53ca63bb49209164496ab5e4231, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 0 - m_ReflectionProbeUsage: 1 m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -229,81 +242,34 @@ BoxCollider: serializedVersion: 2 m_Size: {x: 0.39, y: 0.21, z: 0.69} m_Center: {x: 0, y: 0, z: 0} ---- !u!82 &8200000 -AudioSource: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 100008} + m_IsPrefabParent: 1 +--- !u!114 &114063788560133230 +MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 100008} m_Enabled: 1 - serializedVersion: 4 - OutputAudioMixerGroup: {fileID: 0} - m_audioClip: {fileID: 8300000, guid: 16e0334dc2987ac429998196827191ed, type: 3} - m_PlayOnAwake: 0 - m_Volume: 1 - m_Pitch: 1 - Loop: 0 - Mute: 0 - Spatialize: 0 - Priority: 128 - DopplerLevel: 1 - MinDistance: 1 - MaxDistance: 500 - Pan2D: 0 - rolloffMode: 0 - BypassEffects: 0 - BypassListenerEffects: 0 - BypassReverbZones: 0 - rolloffCustomCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - panLevelCustomCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 0 - spreadCustomCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - reverbZoneMixCustomCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 0 ---- !u!114 &11400000 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0166d8ff8d905b048b2448179e1f5d11, type: 3} + m_Name: + m_EditorClassIdentifier: + _components: + - {fileID: 114952695426007222} + _identifier: + _context: {fileID: 0} + _bindType: 0 +--- !u!114 &114952695426007222 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} @@ -311,19 +277,8 @@ MonoBehaviour: m_GameObject: {fileID: 100008} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3d2395b0230e353488352840a8083fba, type: 3} + m_Script: {fileID: 11500000, guid: aab42c7e45a13404daf7de27c7366efc, type: 3} m_Name: m_EditorClassIdentifier: - MeshRenderer: {fileID: 2300000} - ParticleEmitter: {fileID: 1500000} ---- !u!1001 &100100000 -Prefab: - m_ObjectHideFlags: 1 - serializedVersion: 2 - m_Modification: - m_TransformParent: {fileID: 0} - m_Modifications: [] - m_RemovedComponents: [] - m_ParentPrefab: {fileID: 0} - m_RootGameObject: {fileID: 100008} - m_IsPrefabParent: 1 + _meshRenderer: {fileID: 2300000} + _particleEmitter: {fileID: 1500000} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/ShipBroken.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/ShipBroken.prefab index 32572822f..22f52a19a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/ShipBroken.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Prefabs/ShipBroken.prefab @@ -5,13 +5,13 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400000} - - 33: {fileID: 3300000} - - 23: {fileID: 2300000} - - 54: {fileID: 5400002} - - 64: {fileID: 6400002} + - component: {fileID: 400000} + - component: {fileID: 3300000} + - component: {fileID: 2300000} + - component: {fileID: 5400002} + - component: {fileID: 6400002} m_Layer: 0 m_Name: Cube_010 m_TagString: Untagged @@ -24,13 +24,13 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400002} - - 33: {fileID: 3300002} - - 23: {fileID: 2300002} - - 54: {fileID: 5400000} - - 64: {fileID: 6400000} + - component: {fileID: 400002} + - component: {fileID: 3300002} + - component: {fileID: 2300002} + - component: {fileID: 5400000} + - component: {fileID: 6400000} m_Layer: 0 m_Name: Cube_005 m_TagString: Untagged @@ -43,13 +43,13 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400004} - - 33: {fileID: 3300004} - - 23: {fileID: 2300004} - - 54: {fileID: 5400004} - - 64: {fileID: 6400004} + - component: {fileID: 400004} + - component: {fileID: 3300004} + - component: {fileID: 2300004} + - component: {fileID: 5400004} + - component: {fileID: 6400004} m_Layer: 0 m_Name: Cube_011 m_TagString: Untagged @@ -62,13 +62,13 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400006} - - 33: {fileID: 3300006} - - 23: {fileID: 2300006} - - 54: {fileID: 5400006} - - 64: {fileID: 6400006} + - component: {fileID: 400006} + - component: {fileID: 3300006} + - component: {fileID: 2300006} + - component: {fileID: 5400006} + - component: {fileID: 6400006} m_Layer: 0 m_Name: Cube_008 m_TagString: Untagged @@ -81,13 +81,13 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400008} - - 33: {fileID: 3300008} - - 23: {fileID: 2300008} - - 54: {fileID: 5400008} - - 64: {fileID: 6400008} + - component: {fileID: 400008} + - component: {fileID: 3300008} + - component: {fileID: 2300008} + - component: {fileID: 5400008} + - component: {fileID: 6400008} m_Layer: 0 m_Name: Cube_006 m_TagString: Untagged @@ -100,9 +100,9 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400010} + - component: {fileID: 400010} m_Layer: 0 m_Name: ShipBroken m_TagString: Untagged @@ -119,10 +119,10 @@ Transform: m_LocalRotation: {x: 0.7071068, y: -0.0000007277363, z: 0.7071068, w: 0.0000007277363} m_LocalPosition: {x: -0.14782198, y: 0.13996994, z: 0.50999993} m_LocalScale: {x: 0.0725404, y: 0.045714427, z: 0.045714427} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 400010} m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400002 Transform: m_ObjectHideFlags: 1 @@ -132,10 +132,10 @@ Transform: m_LocalRotation: {x: 0.7071068, y: -0.0000007277363, z: 0.7071068, w: 0.0000007277363} m_LocalPosition: {x: -0.05714888, y: 0.086045384, z: 0.23121913} m_LocalScale: {x: -0.07388986, y: -0.132471, z: -0.18752591} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 400010} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400004 Transform: m_ObjectHideFlags: 1 @@ -145,10 +145,10 @@ Transform: m_LocalRotation: {x: 0.7071068, y: -0.0000007277363, z: 0.7071068, w: 0.0000007277363} m_LocalPosition: {x: -0.08334432, y: -0.2727112, z: 0.34174734} m_LocalScale: {x: 34.729897, y: 34.729897, z: 34.729897} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 400010} m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400006 Transform: m_ObjectHideFlags: 1 @@ -158,10 +158,10 @@ Transform: m_LocalRotation: {x: 0.7071068, y: -0.0000007277363, z: 0.7071068, w: 0.0000007277363} m_LocalPosition: {x: 0.009275186, y: -0.09390866, z: 0.14864963} m_LocalScale: {x: 34.729897, y: 34.729897, z: 34.729897} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 400010} m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400008 Transform: m_ObjectHideFlags: 1 @@ -171,10 +171,10 @@ Transform: m_LocalRotation: {x: 0.7071068, y: -0.0000007277363, z: 0.7071068, w: 0.0000007277363} m_LocalPosition: {x: -0.008923158, y: 0.12896016, z: 0.08406838} m_LocalScale: {x: 34.729897, y: 34.729897, z: 34.729897} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 400010} m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400010 Transform: m_ObjectHideFlags: 1 @@ -184,7 +184,6 @@ Transform: m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068} m_LocalPosition: {x: 0.6605213, y: 0, z: 0.4974662} m_LocalScale: {x: 0.7, y: 0.7, z: 0.7} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 400002} - {fileID: 400008} @@ -193,6 +192,7 @@ Transform: - {fileID: 400004} m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &2300000 MeshRenderer: m_ObjectHideFlags: 1 @@ -207,7 +207,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 62155033a16c4eb4ab0878b56d98970f, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -215,7 +217,7 @@ MeshRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -236,7 +238,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 02f272d5e8ff508428baf80fadda022a, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -244,7 +248,7 @@ MeshRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -265,7 +269,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 62155033a16c4eb4ab0878b56d98970f, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -273,7 +279,7 @@ MeshRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -294,7 +300,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 62155033a16c4eb4ab0878b56d98970f, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -302,7 +310,7 @@ MeshRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -323,7 +331,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 62155033a16c4eb4ab0878b56d98970f, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -331,7 +341,7 @@ MeshRenderer: m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -459,6 +469,8 @@ MeshCollider: m_Enabled: 1 serializedVersion: 2 m_Convex: 1 + m_InflateMesh: 0 + m_SkinWidth: 0.01 m_Mesh: {fileID: 4300000, guid: 833675a5109244941b0f5019725ef776, type: 3} --- !u!64 &6400002 MeshCollider: @@ -471,6 +483,8 @@ MeshCollider: m_Enabled: 1 serializedVersion: 2 m_Convex: 1 + m_InflateMesh: 0 + m_SkinWidth: 0.01 m_Mesh: {fileID: 4300000, guid: cd4e202637727f548ab597eec0394427, type: 3} --- !u!64 &6400004 MeshCollider: @@ -483,6 +497,8 @@ MeshCollider: m_Enabled: 1 serializedVersion: 2 m_Convex: 1 + m_InflateMesh: 0 + m_SkinWidth: 0.01 m_Mesh: {fileID: 4300002, guid: 5735f3b443f71894589af1323ad7a29b, type: 3} --- !u!64 &6400006 MeshCollider: @@ -495,6 +511,8 @@ MeshCollider: m_Enabled: 1 serializedVersion: 2 m_Convex: 1 + m_InflateMesh: 0 + m_SkinWidth: 0.01 m_Mesh: {fileID: 4300006, guid: 5735f3b443f71894589af1323ad7a29b, type: 3} --- !u!64 &6400008 MeshCollider: @@ -507,6 +525,8 @@ MeshCollider: m_Enabled: 1 serializedVersion: 2 m_Convex: 1 + m_InflateMesh: 0 + m_SkinWidth: 0.01 m_Mesh: {fileID: 4300008, guid: 5735f3b443f71894589af1323ad7a29b, type: 3} --- !u!1001 &100100000 Prefab: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset.meta index 9630993a2..5ba4bc5d6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 guid: 48da99ff693be7b4d89b133042973796 -timeCreated: 1477234562 -licenseType: Free +timeCreated: 1461789524 +licenseType: Pro NativeFormatImporter: userData: assetBundleName: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs new file mode 100644 index 000000000..10487fdbd --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs @@ -0,0 +1,42 @@ +using UnityEngine; +using System.Collections; +using Zenject; +using ModestTree; + +namespace Zenject.Asteroids +{ + // This scene is an example of how decorators work + // We override move settings to make the ship much slower and add a hotkey to manually spawn asteroids + // Decorators are really useful in particular for running different test configurations + public class GameDecoratorInstaller : MonoInstaller + { + public ShipStateMoving.Settings OverrideMoveSettings; + + // If you are injecting into an installer then you will need to put the binding in PreInstall + public override void InstallBindings() + { + Container.Bind().To().AsSingle(); + // Do not spawn asteroids automatically + Container.BindInstance(false).WhenInjectedInto(); + } + } + + public class TestHotKeysAdder : ITickable + { + readonly AsteroidManager _asteroidManager; + + public TestHotKeysAdder(AsteroidManager asteroidManager) + { + _asteroidManager = asteroidManager; + } + + public void Tick() + { + if (Input.GetKeyDown(KeyCode.F4)) + { + _asteroidManager.SpawnNext(); + Log.Info("Spawned new asteroid!"); + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta similarity index 53% rename from UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta index 17c6139a5..6ebbc9ba2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Command/Command.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta @@ -1,12 +1,8 @@ fileFormatVersion: 2 -guid: 81019001810e20b4e87aa6761a4700c2 -timeCreated: 1480006190 -licenseType: Pro +guid: f5efd89f29bfcd141907dd60701bc741 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs index 721e63b2a..e3817588a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs @@ -82,7 +82,7 @@ void InstallMisc() void InstallShip() { - Container.BindSignal(); + Container.Bind().AsSingle(); Container.Bind().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameController.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameController.cs index 384df5067..97fcbe5ec 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameController.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameController.cs @@ -18,15 +18,15 @@ public class GameController : IInitializable, ITickable, IDisposable readonly Ship _ship; readonly AsteroidManager _asteroidSpawner; - Signals.ShipCrashed _shipCrashed; + GameEvents _gameEvents; GameStates _state = GameStates.WaitingToStart; float _elapsedTime; public GameController( Ship ship, AsteroidManager asteroidSpawner, - Signals.ShipCrashed shipCrashedSignal) + GameEvents gameEvents) { - _shipCrashed = shipCrashedSignal; + _gameEvents = gameEvents; _asteroidSpawner = asteroidSpawner; _ship = ship; } @@ -53,12 +53,12 @@ public void Initialize() Cursor.visible = false; - _shipCrashed += OnShipCrashed; + _gameEvents.ShipCrashed += OnShipCrashed; } public void Dispose() { - _shipCrashed -= OnShipCrashed; + _gameEvents.ShipCrashed -= OnShipCrashed; } public void Tick() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameSignals.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameSignals.cs deleted file mode 100644 index 83d7cb1e4..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameSignals.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Zenject.Asteroids -{ - public static class Signals - { - public class ShipCrashed : Signal - { - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameSignals.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameSignals.cs.meta deleted file mode 100644 index 9411d7bc8..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameSignals.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 78aa36c5c8cb6b74eb365f481df42e24 -timeCreated: 1461793480 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/AudioHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/AudioHandler.cs index 2d8934375..b227bcb8e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/AudioHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/AudioHandler.cs @@ -9,26 +9,26 @@ public class AudioHandler : IInitializable, IDisposable readonly Settings _settings; readonly AudioSource _audioSource; - Signals.ShipCrashed _shipCrashed; + GameEvents _gameEvents; public AudioHandler( - Signals.ShipCrashed shipCrashed, + GameEvents gameEvents, AudioSource audioSource, Settings settings) { _settings = settings; _audioSource = audioSource; - _shipCrashed = shipCrashed; + _gameEvents = gameEvents; } public void Initialize() { - _shipCrashed += OnShipCrashed; + _gameEvents.ShipCrashed += OnShipCrashed; } public void Dispose() { - _shipCrashed -= OnShipCrashed; + _gameEvents.ShipCrashed -= OnShipCrashed; } void OnShipCrashed() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/GuiHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/GuiHandler.cs index 393752f50..819e3b496 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/GuiHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/GuiHandler.cs @@ -10,7 +10,7 @@ namespace Zenject.Asteroids { public class GuiHandler : MonoBehaviour, IDisposable, IInitializable { - Signals.ShipCrashed _shipCrashed; + GameEvents _gameEvents; GameController _gameController; [SerializeField] @@ -41,10 +41,10 @@ public class GuiHandler : MonoBehaviour, IDisposable, IInitializable [Inject] public void Construct( - GameController gameController, Signals.ShipCrashed shipCrashed) + GameController gameController, GameEvents gameEvents) { _gameController = gameController; - _shipCrashed = shipCrashed; + _gameEvents = gameEvents; } void OnGUI() @@ -206,12 +206,12 @@ void StartGui() public void Initialize() { - _shipCrashed += OnShipCrashed; + _gameEvents.ShipCrashed += OnShipCrashed; } public void Dispose() { - _shipCrashed -= OnShipCrashed; + _gameEvents.ShipCrashed -= OnShipCrashed; } void OnShipCrashed() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs index bafd9e6c1..cf97ac04e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs @@ -19,7 +19,7 @@ public class ShipStateDead : ShipState readonly BrokenShipFactory _brokenShipFactory; readonly ExplosionFactory _explosionFactory; readonly Settings _settings; - readonly Signals.ShipCrashed _shipCrashed; + readonly GameEvents _gameEvents; readonly Ship _ship; GameObject _shipBroken; @@ -27,14 +27,14 @@ public class ShipStateDead : ShipState public ShipStateDead( Settings settings, Ship ship, - Signals.ShipCrashed shipCrashed, + GameEvents gameEvents, ExplosionFactory explosionFactory, BrokenShipFactory brokenShipFactory) { _brokenShipFactory = brokenShipFactory; _explosionFactory = explosionFactory; _settings = settings; - _shipCrashed = shipCrashed; + _gameEvents = gameEvents; _ship = ship; } @@ -57,7 +57,7 @@ public override void Start() rigidBody.AddForce(randomDir * _settings.explosionForce); } - _shipCrashed.Fire(); + _gameEvents.ShipCrashed(); } public override void Stop() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Util/GameEvents.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Util/GameEvents.cs new file mode 100644 index 000000000..622bbc517 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Util/GameEvents.cs @@ -0,0 +1,9 @@ +using System; + +namespace Zenject.Asteroids +{ + public class GameEvents + { + public Action ShipCrashed = delegate {}; + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/ISignal.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Util/GameEvents.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/ISignal.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Util/GameEvents.cs.meta index 97aba1bdf..f76a21ab0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/ISignal.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Util/GameEvents.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 283c81053f95d9a4cad1ee64c78aaefe -timeCreated: 1477950441 +guid: 44a6c869bd4f68c479f02155b98fbeca +timeCreated: 1483817409 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers.meta index 1aa7594e8..2a6980cd1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 51aa9aea803da234bbc9721a2fd13ffd +guid: 47e7c4af6b407724daffa76ababbeb5e folderAsset: yes -timeCreated: 1478028474 +timeCreated: 1477227179 licenseType: Free DefaultImporter: userData: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings/GameSettingsInstaller.asset b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings/GameSettingsInstaller.asset rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings/GameSettingsInstaller.asset.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings/GameSettingsInstaller.asset.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset.meta index f43e96dd7..fb9e7d6b9 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings/GameSettingsInstaller.asset.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 guid: 91a82aa816bb01d4cb9396481c2614a1 -timeCreated: 1477234562 -licenseType: Free +timeCreated: 1461784532 +licenseType: Pro NativeFormatImporter: userData: assetBundleName: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Bullet.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Bullet.prefab index a086e53df..61398de77 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Bullet.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Bullet.prefab @@ -29,7 +29,6 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: -1.474, y: 1.83, z: 0} m_LocalScale: {x: 1.9560189, y: 0.13736466, z: 0.31226227} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 @@ -42,20 +41,17 @@ MeshRenderer: m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} m_SubsetIndices: m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_ReflectionProbeUsage: 1 m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Enemy.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Enemy.prefab index ec35533bf..ee881be7d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Enemy.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Enemy.prefab @@ -48,7 +48,6 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0.39402217, w: 0.91910094} m_LocalPosition: {x: 41.7, y: 4.7, z: 0} m_LocalScale: {x: 0.79406416, y: 0.794064, z: 0.79406404} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 471460} m_Father: {fileID: 0} @@ -62,7 +61,6 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 463158} m_RootOrder: 0 @@ -75,20 +73,17 @@ MeshRenderer: m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 50755dee91b8d2142a777c6b00ad6923, type: 2} m_SubsetIndices: m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 1 + m_ReflectionProbeUsage: 1 m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -143,7 +138,7 @@ MonoBehaviour: _components: - {fileID: 11462742} _identifier: - _context: {fileID: 0} + _compositionRoot: {fileID: 0} _bindType: 0 --- !u!114 &11414686 MonoBehaviour: @@ -229,7 +224,7 @@ MonoBehaviour: - {fileID: 11453994} _installerPrefabs: [] _scriptableObjectInstallers: [] - _kernel: {fileID: 0} + _facade: {fileID: 0} --- !u!1001 &100100000 Prefab: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab index b1dcf693b..56ed297bd 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab @@ -44,7 +44,6 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: -1, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 400002} m_RootOrder: 0 @@ -57,7 +56,6 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 1, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 400000} m_Father: {fileID: 0} @@ -82,7 +80,7 @@ ParticleSystem: m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 100000} - serializedVersion: 4 + serializedVersion: 2 lengthInSec: 1.5 startDelay: scalar: 0 @@ -120,13 +118,12 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 speed: 1 + randomSeed: 0 looping: 0 prewarm: 0 playOnAwake: 1 moveWithTransform: 0 - autoRandomSeed: 1 scalingMode: 2 - randomSeed: 0 InitialModule: serializedVersion: 2 enabled: 1 @@ -201,7 +198,6 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 startColor: - serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -288,80 +284,14 @@ ParticleSystem: atime7: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - minMaxState: 0 - startSize: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - startSizeY: - scalar: 1 - maxCurve: + minColor: serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: + rgba: 4294967295 + maxColor: serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 + rgba: 4294967295 minMaxState: 0 - startSizeZ: + startSize: scalar: 1 maxCurve: serializedVersion: 2 @@ -504,7 +434,6 @@ ParticleSystem: randomizeRotationDirection: 0 gravityModifier: 0 maxNumParticles: 1000 - size3D: 0 rotation3D: 0 ShapeModule: serializedVersion: 2 @@ -615,77 +544,6 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 - y: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - z: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - separateAxes: 0 RotationModule: enabled: 1 x: @@ -787,7 +645,6 @@ ParticleSystem: ColorModule: enabled: 1 gradient: - serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -874,13 +731,17 @@ ParticleSystem: atime7: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} + minColor: + serializedVersion: 2 + rgba: 4294967295 + maxColor: + serializedVersion: 2 + rgba: 4294967295 minMaxState: 1 UVModule: enabled: 0 frameOverTime: - scalar: 0.9999 + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: @@ -914,47 +775,11 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 - startFrame: - scalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 tilesX: 1 tilesY: 1 animationType: 0 rowIndex: 0 cycles: 1 - uvChannelMask: -1 randomRow: 1 VelocityModule: enabled: 0 @@ -1366,78 +1191,7 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 - y: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - z: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 range: {x: 0, y: 1} - separateAxes: 0 RotationBySpeedModule: enabled: 0 x: @@ -1550,7 +1304,6 @@ ParticleSystem: ColorBySpeedModule: enabled: 0 gradient: - serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -1637,13 +1390,17 @@ ParticleSystem: atime7: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} + minColor: + serializedVersion: 2 + rgba: 4294967295 + maxColor: + serializedVersion: 2 + rgba: 4294967295 minMaxState: 1 range: {x: 0, y: 1} CollisionModule: enabled: 0 - serializedVersion: 3 + serializedVersion: 2 type: 0 collisionMode: 0 plane0: {fileID: 0} @@ -1758,7 +1515,6 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 minKillSpeed: 0 - maxKillSpeed: 10000 radiusScale: 1 collidesWith: serializedVersion: 2 @@ -1769,19 +1525,6 @@ ParticleSystem: collisionMessages: 0 collidesWithDynamic: 1 interiorCollisions: 1 - TriggerModule: - enabled: 0 - collisionShape0: {fileID: 0} - collisionShape1: {fileID: 0} - collisionShape2: {fileID: 0} - collisionShape3: {fileID: 0} - collisionShape4: {fileID: 0} - collisionShape5: {fileID: 0} - inside: 1 - outside: 0 - enter: 0 - exit: 0 - radiusScale: 1 SubModule: enabled: 0 subEmitterBirth: {fileID: 0} @@ -1796,7 +1539,7 @@ ParticleSystem: m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 100002} - serializedVersion: 4 + serializedVersion: 2 lengthInSec: 1.5 startDelay: scalar: 0 @@ -1834,13 +1577,12 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 speed: 1 + randomSeed: 0 looping: 0 prewarm: 0 playOnAwake: 1 moveWithTransform: 0 - autoRandomSeed: 1 scalingMode: 2 - randomSeed: 0 InitialModule: serializedVersion: 2 enabled: 1 @@ -1915,7 +1657,6 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 startColor: - serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -2002,80 +1743,14 @@ ParticleSystem: atime7: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} - minMaxState: 0 - startSize: - scalar: 1 - maxCurve: + minColor: serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: + rgba: 4294967295 + maxColor: serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 + rgba: 4294967295 minMaxState: 0 - startSizeY: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - startSizeZ: + startSize: scalar: 1 maxCurve: serializedVersion: 2 @@ -2218,7 +1893,6 @@ ParticleSystem: randomizeRotationDirection: 0 gravityModifier: 0 maxNumParticles: 1000 - size3D: 0 rotation3D: 0 ShapeModule: serializedVersion: 2 @@ -2329,77 +2003,6 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 - y: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - z: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - separateAxes: 0 RotationModule: enabled: 0 x: @@ -2511,7 +2114,6 @@ ParticleSystem: ColorModule: enabled: 1 gradient: - serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -2598,13 +2200,17 @@ ParticleSystem: atime7: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} + minColor: + serializedVersion: 2 + rgba: 4294967295 + maxColor: + serializedVersion: 2 + rgba: 4294967295 minMaxState: 1 UVModule: enabled: 0 frameOverTime: - scalar: 0.9999 + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: @@ -2638,47 +2244,11 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 - startFrame: - scalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 tilesX: 1 tilesY: 1 animationType: 0 rowIndex: 0 cycles: 1 - uvChannelMask: -1 randomRow: 1 VelocityModule: enabled: 0 @@ -3090,78 +2660,7 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 - y: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - z: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 range: {x: 0, y: 1} - separateAxes: 0 RotationBySpeedModule: enabled: 0 x: @@ -3274,7 +2773,6 @@ ParticleSystem: ColorBySpeedModule: enabled: 0 gradient: - serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -3361,13 +2859,17 @@ ParticleSystem: atime7: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: {r: 1, g: 1, b: 1, a: 1} - maxColor: {r: 1, g: 1, b: 1, a: 1} + minColor: + serializedVersion: 2 + rgba: 4294967295 + maxColor: + serializedVersion: 2 + rgba: 4294967295 minMaxState: 1 range: {x: 0, y: 1} CollisionModule: enabled: 0 - serializedVersion: 3 + serializedVersion: 2 type: 0 collisionMode: 0 plane0: {fileID: 0} @@ -3482,7 +2984,6 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 minKillSpeed: 0 - maxKillSpeed: 10000 radiusScale: 1 collidesWith: serializedVersion: 2 @@ -3493,19 +2994,6 @@ ParticleSystem: collisionMessages: 0 collidesWithDynamic: 1 interiorCollisions: 1 - TriggerModule: - enabled: 0 - collisionShape0: {fileID: 0} - collisionShape1: {fileID: 0} - collisionShape2: {fileID: 0} - collisionShape3: {fileID: 0} - collisionShape4: {fileID: 0} - collisionShape5: {fileID: 0} - inside: 1 - outside: 0 - enter: 0 - exit: 0 - radiusScale: 1 SubModule: enabled: 0 subEmitterBirth: {fileID: 0} @@ -3523,20 +3011,17 @@ ParticleSystemRenderer: m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 0 m_Materials: - {fileID: 2100000, guid: b1ca011c5f92d4fd4b5aeac44fd607c6, type: 2} m_SubsetIndices: m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 0 + m_ReflectionProbeUsage: 0 m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -3567,20 +3052,17 @@ ParticleSystemRenderer: m_Enabled: 1 m_CastShadows: 0 m_ReceiveShadows: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 0 - m_ReflectionProbeUsage: 0 m_Materials: - {fileID: 10301, guid: 0000000000000000f000000000000000, type: 0} m_SubsetIndices: m_StaticBatchRoot: {fileID: 0} + m_UseLightProbes: 0 + m_ReflectionProbeUsage: 0 m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionDetector.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionDetector.cs index 1fc5a8bb9..720b5275f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionDetector.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionDetector.cs @@ -5,12 +5,14 @@ namespace Zenject.SpaceFighter { public class EnemyCollisionDetector : MonoBehaviour { - EnemySignals.Hit _hitTrigger; + GameEvents _gameEvents; + EnemyModel _enemy; [Inject] - public void Construct(EnemySignals.Hit hitTrigger) + public void Construct(GameEvents gameEvents, EnemyModel enemy) { - _hitTrigger = hitTrigger; + _gameEvents = gameEvents; + _enemy = enemy; } public void OnTriggerEnter(Collider other) @@ -19,7 +21,7 @@ public void OnTriggerEnter(Collider other) if (bullet != null && bullet.Type != BulletTypes.FromEnemy) { - _hitTrigger.Fire(bullet); + _gameEvents.EnemyHit(_enemy, bullet); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs index 25f7c15d1..b035aad37 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs @@ -10,15 +10,15 @@ public class EnemyCollisionHandler : IInitializable, IDisposable readonly Settings _settings; readonly EnemyModel _model; - EnemySignals.Hit _hitSignal; + GameEvents _gameEvents; public EnemyCollisionHandler( EnemyModel model, Settings settings, AudioPlayer audioPlayer, - EnemySignals.Hit hitSignal) + GameEvents gameEvents) { - _hitSignal = hitSignal; + _gameEvents = gameEvents; _audioPlayer = audioPlayer; _settings = settings; _model = model; @@ -26,16 +26,21 @@ public EnemyCollisionHandler( public void Initialize() { - _hitSignal += OnHit; + _gameEvents.EnemyHit += OnHit; } public void Dispose() { - _hitSignal -= OnHit; + _gameEvents.EnemyHit -= OnHit; } - void OnHit(Bullet bullet) + void OnHit(EnemyModel enemy, Bullet bullet) { + if (enemy != _model) + { + return; + } + _audioPlayer.Play(_settings.HitSound); _model.AddForce(-bullet.MoveDirection * _settings.HitForce); _model.TakeDamage(_settings.HealthLoss); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs index 036b492f8..3256f0aa0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs @@ -5,7 +5,7 @@ namespace Zenject.SpaceFighter { public class EnemyHealthWatcher : ITickable { - readonly EnemyKilledSignal _killedSignal; + readonly GameEvents _gameEvents; readonly Explosion.Factory _explosionFactory; readonly Context _context; readonly EnemyModel _model; @@ -14,9 +14,9 @@ public EnemyHealthWatcher( EnemyModel model, Context context, Explosion.Factory explosionFactory, - EnemyKilledSignal killedSignal) + GameEvents gameEvents) { - _killedSignal = killedSignal; + _gameEvents = gameEvents; _explosionFactory = explosionFactory; _context = context; _model = model; @@ -37,7 +37,7 @@ void Die() GameObject.Destroy(_context.gameObject); - _killedSignal.Fire(); + _gameEvents.EnemyKilled(_model); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemySignals.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemySignals.cs deleted file mode 100644 index 59a82534b..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemySignals.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Zenject.SpaceFighter -{ - public static class EnemySignals - { - // Triggered when enemy is hit by a bullet - public class Hit : Signal - { - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemySignals.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemySignals.cs.meta deleted file mode 100644 index 631e7f75e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemySignals.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: db64fded81f1bbe4d865f902b643d686 -timeCreated: 1456619910 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs index 53148f62a..36bb88b39 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs @@ -11,26 +11,26 @@ public class EnemyStateCommon : IInitializable, IDisposable, ITickable readonly EnemyModel _model; readonly EnemyStateManager _stateManager; - EnemySignals.Hit _hitSignal; + GameEvents _gameEvents; public EnemyStateCommon( - EnemySignals.Hit hitSignal, + GameEvents gameEvents, EnemyStateManager stateManager, EnemyModel model) { _model = model; _stateManager = stateManager; - _hitSignal = hitSignal; + _gameEvents = gameEvents; } public void Initialize() { - _hitSignal += OnHit; + _gameEvents.EnemyHit += OnHit; } public void Dispose() { - _hitSignal -= OnHit; + _gameEvents.EnemyHit -= OnHit; } public void Tick() @@ -39,8 +39,13 @@ public void Tick() _model.Position = new Vector3(_model.Position.x, _model.Position.y, 0); } - void OnHit(Bullet bullet) + void OnHit(EnemyModel model, Bullet bullet) { + if (model != _model) + { + return; + } + // Run away to fight another day _stateManager.ChangeState(EnemyStates.RunAway); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs new file mode 100644 index 000000000..8bd03c306 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs @@ -0,0 +1,12 @@ +using System; + +namespace Zenject.SpaceFighter +{ + public class GameEvents + { + public Action EnemyHit = delegate {}; + public Action PlayerHit = delegate {}; + public Action PlayerKilled = delegate {}; + public Action EnemyKilled = delegate {}; + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal0.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs.meta index ee56a5dd0..facbf0984 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/CommandsAndSignals/Signal/Signal0.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: e1a7f1a79271d714bb98c2bb7aec80ed -timeCreated: 1477950441 +guid: 432f74bf3abdd7e4facd4bba2a8fe60b +timeCreated: 1483820546 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs index 0a3e48e41..eab052cc1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs @@ -32,8 +32,6 @@ public override void InstallBindings() Container.BindAllInterfaces().To().AsSingle(); - Container.BindSignal(); - Container.BindAllInterfaces().To().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs index 6cab23575..6742e900a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs @@ -15,8 +15,7 @@ public override void InstallBindings() { Container.BindAllInterfaces().To().AsSingle(); - Container.BindSignal(); - Container.BindSignal(); + Container.Bind().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs index e35a8291d..68740ac2a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs @@ -25,8 +25,6 @@ public override void InstallBindings() Container.BindAllInterfaces().To().AsSingle(); - Container.BindSignal(); - InstallSettings(); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameRestartHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameRestartHandler.cs index 73d9ddb06..3b4f9fa5c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameRestartHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameRestartHandler.cs @@ -9,26 +9,26 @@ public class GameRestartHandler : IInitializable, IDisposable, ITickable { readonly Settings _settings; - PlayerKilledSignal _killedSignal; + GameEvents _gameEvents; bool _isDelaying; float _delayStartTime; public GameRestartHandler( Settings settings, - PlayerKilledSignal killedSignal) + GameEvents gameEvents) { - _killedSignal = killedSignal; + _gameEvents = gameEvents; _settings = settings; } public void Initialize() { - _killedSignal += OnPlayerKilled; + _gameEvents.PlayerKilled += OnPlayerKilled; } public void Dispose() { - _killedSignal -= OnPlayerKilled; + _gameEvents.PlayerKilled -= OnPlayerKilled; } public void Tick() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameSignals.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameSignals.cs deleted file mode 100644 index 43db2ef73..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameSignals.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using UnityEngine; -using Zenject; - -namespace Zenject.SpaceFighter -{ - // Triggered when the player explodes - public class PlayerKilledSignal : Signal - { - } - - // Triggered when the enemy explodes - public class EnemyKilledSignal : Signal - { - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameSignals.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameSignals.cs.meta deleted file mode 100644 index e7055436e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameSignals.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 1541c518ae008c948bf4b77ad99a620c -timeCreated: 1456418717 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs index 0a47e680b..4eced4e11 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs @@ -10,15 +10,15 @@ public class PlayerBulletHitHandler : IInitializable, IDisposable readonly Settings _settings; readonly PlayerModel _model; - PlayerSignals.Hit _hitSignal; + GameEvents _gameEvents; public PlayerBulletHitHandler( PlayerModel model, Settings settings, AudioPlayer audioPlayer, - PlayerSignals.Hit hitSignal) + GameEvents gameEvents) { - _hitSignal = hitSignal; + _gameEvents = gameEvents; _audioPlayer = audioPlayer; _settings = settings; _model = model; @@ -26,12 +26,12 @@ public PlayerBulletHitHandler( public void Initialize() { - _hitSignal += OnHit; + _gameEvents.PlayerHit += OnHit; } public void Dispose() { - _hitSignal -= OnHit; + _gameEvents.PlayerHit -= OnHit; } void OnHit(Bullet bullet) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs index 7124bb86b..5311c4a8c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs @@ -5,12 +5,12 @@ namespace Zenject.SpaceFighter { public class PlayerCollisionDetector : MonoBehaviour { - PlayerSignals.Hit _hitTrigger; + GameEvents _gameEvents; [Inject] - public void Construct(PlayerSignals.Hit hitTrigger) + public void Construct(GameEvents gameEvents) { - _hitTrigger = hitTrigger; + _gameEvents = gameEvents; } public void OnTriggerEnter(Collider other) @@ -19,7 +19,7 @@ public void OnTriggerEnter(Collider other) if (bullet != null && bullet.Type != BulletTypes.FromPlayer) { - _hitTrigger.Fire(bullet); + _gameEvents.PlayerHit(bullet); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs index c969c3502..7f3145e49 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs @@ -1,13 +1,12 @@ using ModestTree; using UnityEngine; using Zenject; -using System; #pragma warning disable 649 namespace Zenject.SpaceFighter { - public class PlayerHealthDisplay : MonoBehaviour, IDisposable, IInitializable + public class PlayerHealthDisplay : MonoBehaviour { [SerializeField] float _leftPadding; @@ -41,29 +40,18 @@ public class PlayerHealthDisplay : MonoBehaviour, IDisposable, IInitializable Texture2D _textureBackground; int _killCount; - EnemyKilledSignal _enemyKilledSignal; - [Inject] - public void Construct(PlayerModel model, EnemyKilledSignal enemyKilledSignal) + public void Construct(PlayerModel model, GameEvents gameEvents) { _model = model; - _enemyKilledSignal = enemyKilledSignal; - } - public void Initialize() - { _textureForeground = CreateColorTexture(_foregroundColor); _textureBackground = CreateColorTexture(_backgroundColor); - _enemyKilledSignal += OnEnemyKilled; - } - - public void Dispose() - { - _enemyKilledSignal -= OnEnemyKilled; + gameEvents.EnemyKilled += OnEnemyKilled; } - void OnEnemyKilled() + void OnEnemyKilled(EnemyModel enemy) { _killCount++; } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs index 2480d165c..8fc4501c6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs @@ -6,16 +6,16 @@ namespace Zenject.SpaceFighter { public class PlayerHealthWatcher : ITickable { - readonly PlayerKilledSignal _killedSignal; + readonly GameEvents _gameEvents; readonly Explosion.Factory _explosionFactory; readonly PlayerModel _model; public PlayerHealthWatcher( PlayerModel model, Explosion.Factory explosionFactory, - PlayerKilledSignal killedSignal) + GameEvents gameEvents) { - _killedSignal = killedSignal; + _gameEvents = gameEvents; _explosionFactory = explosionFactory; _model = model; } @@ -37,7 +37,7 @@ void Die() _model.Renderer.enabled = false; - _killedSignal.Fire(); + _gameEvents.PlayerKilled(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerSignals.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerSignals.cs deleted file mode 100644 index 97f7a7ea1..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerSignals.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Zenject.SpaceFighter -{ - public static class PlayerSignals - { - // Fired when a bullet hits the player - public class Hit : Signal - { - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerSignals.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerSignals.cs.meta deleted file mode 100644 index d898a7b78..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerSignals.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 2fa5ccc4497e47f42be4aed6dcaaa532 -timeCreated: 1456592909 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings.meta deleted file mode 100644 index 63f95c4ab..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Settings.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: a78bf88ed0ab24c46a0e397c9e46201a -folderAsset: yes -timeCreated: 1461784520 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity index 0c83b4387..051861809 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity @@ -1,15 +1,15 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!29 &1 -SceneSettings: +OcclusionCullingSettings: m_ObjectHideFlags: 0 - m_PVSData: - m_PVSObjectsArray: [] - m_PVSPortalsArray: [] + serializedVersion: 2 m_OcclusionBakeSettings: smallestOccluder: 5 smallestHole: 0.25 backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} --- !u!104 &2 RenderSettings: m_ObjectHideFlags: 0 @@ -37,7 +37,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.45170426, g: 0.5020569, b: 0.57611024, a: 1} + m_IndirectSpecularColor: {r: 0.4508896, g: 0.50078845, b: 0.57456195, a: 1} --- !u!157 &3 LightmapSettings: m_ObjectHideFlags: 0 @@ -80,25 +80,26 @@ NavMeshSettings: m_ObjectHideFlags: 0 m_BuildSettings: serializedVersion: 2 + agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 agentSlope: 45 agentClimb: 0.4 ledgeDropHeight: 0 maxJumpAcrossDistance: 0 - accuratePlacement: 0 minRegionArea: 2 - cellSize: 0.16666667 manualCellSize: 0 + cellSize: 0.16666667 + accuratePlacement: 0 m_NavMeshData: {fileID: 0} --- !u!1 &29135873 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 29135874} + - component: {fileID: 29135874} m_Layer: 0 m_Name: Level m_TagString: Untagged @@ -115,26 +116,26 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 724552921} - {fileID: 539215572} m_Father: {fileID: 0} m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &414693287 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 414693292} - - 20: {fileID: 414693291} - - 114: {fileID: 414693293} - - 124: {fileID: 414693290} - - 92: {fileID: 414693289} - - 81: {fileID: 414693288} - - 82: {fileID: 414693294} + - component: {fileID: 414693292} + - component: {fileID: 414693291} + - component: {fileID: 414693293} + - component: {fileID: 414693290} + - component: {fileID: 414693289} + - component: {fileID: 414693288} + - component: {fileID: 414693294} m_Layer: 0 m_Name: Camera m_TagString: Untagged @@ -206,10 +207,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: -1.0086417, y: 2.105907, z: -17.09} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &414693293 MonoBehaviour: m_ObjectHideFlags: 0 @@ -242,6 +243,7 @@ AudioSource: Loop: 0 Mute: 0 Spatialize: 0 + SpatializePostEffects: 0 Priority: 128 DopplerLevel: 1 MinDistance: 1 @@ -254,12 +256,14 @@ AudioSource: rolloffCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -270,7 +274,8 @@ AudioSource: panLevelCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 @@ -281,7 +286,8 @@ AudioSource: spreadCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 @@ -292,7 +298,8 @@ AudioSource: reverbZoneMixCustomCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 @@ -305,13 +312,13 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 534447711} - - 114: {fileID: 534447710} - - 114: {fileID: 534447709} + - component: {fileID: 534447711} + - component: {fileID: 534447710} + - component: {fileID: 534447709} m_Layer: 0 - m_Name: SceneContext + m_Name: SceneCompositionRoot m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -357,21 +364,21 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &539215571 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 539215572} - - 33: {fileID: 539215575} - - 64: {fileID: 539215574} - - 23: {fileID: 539215573} + - component: {fileID: 539215572} + - component: {fileID: 539215575} + - component: {fileID: 539215574} + - component: {fileID: 539215573} m_Layer: 0 m_Name: Plane m_TagString: Untagged @@ -388,10 +395,10 @@ Transform: m_LocalRotation: {x: -0.00000005960466, y: 0.7071068, z: -0.7071068, w: -0.00000014901164} m_LocalPosition: {x: -1.8492146, y: 1.4, z: 14.4} m_LocalScale: {x: 2395.4941, y: 2395.4934, z: 2395.4934} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 29135874} m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &539215573 MeshRenderer: m_ObjectHideFlags: 0 @@ -406,7 +413,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: d2b89dae86aac9a4d9b52881cf3be975, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -414,7 +423,7 @@ MeshRenderer: m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -432,6 +441,8 @@ MeshCollider: m_Enabled: 1 serializedVersion: 2 m_Convex: 0 + m_InflateMesh: 0 + m_SkinWidth: 0.01 m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} --- !u!33 &539215575 MeshFilter: @@ -445,10 +456,10 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 697465886} - - 114: {fileID: 697465885} + - component: {fileID: 697465886} + - component: {fileID: 697465885} m_Layer: 0 m_Name: ControlsDisplay m_TagString: Untagged @@ -480,19 +491,19 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: -0.47249365, y: -0.1732688, z: 0.5937815} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &724552920 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 724552921} - - 108: {fileID: 724552922} + - component: {fileID: 724552921} + - component: {fileID: 724552922} m_Layer: 0 m_Name: Directional light m_TagString: Untagged @@ -509,10 +520,10 @@ Transform: m_LocalRotation: {x: 0.28220388, y: -0.29990056, z: 0.09336465, w: 0.90647876} m_LocalPosition: {x: 19.95923, y: 26.566778, z: -29.98478} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 29135874} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!108 &724552922 Light: m_ObjectHideFlags: 0 @@ -552,10 +563,10 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 855903056} - - 114: {fileID: 855903057} + - component: {fileID: 855903056} + - component: {fileID: 855903057} m_Layer: 8 m_Name: Installer m_TagString: Untagged @@ -572,10 +583,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 1303116743} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &855903057 MonoBehaviour: m_ObjectHideFlags: 0 @@ -608,11 +619,10 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 1034220755} - - 114: {fileID: 1034220756} - - 114: {fileID: 1034220757} + - component: {fileID: 1034220755} + - component: {fileID: 1034220756} m_Layer: 8 m_Name: HealthDisplay m_TagString: Untagged @@ -629,10 +639,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 1303116743} m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1034220756 MonoBehaviour: m_ObjectHideFlags: 0 @@ -653,22 +663,6 @@ MonoBehaviour: _killCountOffset: 30 _foregroundColor: {r: 1, g: 0.08823532, b: 0.08823532, a: 1} _backgroundColor: {r: 1, g: 1, b: 1, a: 1} ---- !u!114 &1034220757 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1034220754} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0166d8ff8d905b048b2448179e1f5d11, type: 3} - m_Name: - m_EditorClassIdentifier: - _components: - - {fileID: 1034220756} - _identifier: - _context: {fileID: 0} - _bindType: 1 --- !u!4 &1177745373 stripped Transform: m_PrefabParentObject: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} @@ -678,17 +672,17 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 1303116743} - - 114: {fileID: 1303116747} - - 33: {fileID: 1303116746} - - 65: {fileID: 1303116745} - - 23: {fileID: 1303116744} - - 54: {fileID: 1303116749} - - 114: {fileID: 1303116750} - - 114: {fileID: 1303116751} - - 114: {fileID: 1303116748} + - component: {fileID: 1303116743} + - component: {fileID: 1303116747} + - component: {fileID: 1303116746} + - component: {fileID: 1303116745} + - component: {fileID: 1303116744} + - component: {fileID: 1303116749} + - component: {fileID: 1303116750} + - component: {fileID: 1303116751} + - component: {fileID: 1303116748} m_Layer: 8 m_Name: Player m_TagString: Untagged @@ -705,12 +699,12 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: -1.38, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 855903056} - {fileID: 1034220755} m_Father: {fileID: 0} m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &1303116744 MeshRenderer: m_ObjectHideFlags: 0 @@ -725,7 +719,9 @@ MeshRenderer: m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 8f4cc0ab4d6d85f4ea468f16219910a1, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} @@ -733,7 +729,7 @@ MeshRenderer: m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -875,9 +871,9 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 1911468625} + - component: {fileID: 1911468625} m_Layer: 0 m_Name: Enemies m_TagString: Untagged @@ -894,8 +890,52 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 1177745373} m_Father: {fileID: 0} m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1920614870 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1920614872} + - component: {fileID: 1920614871} + m_Layer: 0 + m_Name: Test + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1920614871 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1920614870} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 08eca9f7688a0a24685b89133b020c8e, type: 3} + m_Name: + m_EditorClassIdentifier: + _installers: [] + _installerPrefabs: [] + _scriptableObjectInstallers: [] + _kernel: {fileID: 0} +--- !u!4 &1920614872 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1920614870} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands.meta deleted file mode 100644 index 51ff5e5c4..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: d776344b997f1714b89606a3bc0ae7fc -folderAsset: yes -timeCreated: 1461712383 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs deleted file mode 100644 index 19c8e0754..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestCommands : ZenjectIntegrationTestFixture - { - [SetUp] - public void CommonInstall() - { - Container.BindAllInterfacesAndSelf().To().AsSingle(); - } - - [Test] - public void TestToSingle1() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.Bind().AsSingle(); - - Container.DeclareCommand(); - Container.HandleCommand() - .With(x => x.Execute).AsSingle(); - - Initialize(); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.IsEqual(Bar.InstanceCount, 1); - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 1); - } - - [Test] - public void TestToCached1() - { - Bar.WasTriggered = false; - Bar.InstanceCount = 0; - - Container.Bind().AsCached(); - - Container.DeclareCommand(); - Container.HandleCommand() - .With(x => x.Execute).AsCached(); - - Initialize(); - - Container.Resolve(); - var cmd = Container.Resolve(); - - Assert.IsEqual(Bar.InstanceCount, 1); - Assert.That(!Bar.WasTriggered); - - cmd.Execute(); - - Assert.That(Bar.WasTriggered); - Assert.IsEqual(Bar.InstanceCount, 2); - - cmd.Execute(); - Assert.IsEqual(Bar.InstanceCount, 2); - } - - [Test] - public void TestNoHandlerDefault() - { - Container.DeclareCommand(); - - Initialize(); - - var cmd = Container.Resolve(); - cmd.Execute(); - } - - [Test] - public void TestNoHandlerRequiredFailure() - { - Container.DeclareCommand().RequireHandler(); - - Initialize(); - - var cmd = Container.Resolve(); - - Assert.Throws(() => cmd.Execute()); - } - - [Test] - public void TestNoHandlerRequiredSuccess() - { - Container.DeclareCommand().RequireHandler(); - Container.HandleCommand() - .With(x => x.Execute).AsCached(); - - Initialize(); - - var cmd = Container.Resolve(); - cmd.Execute(); - } - - [Test] - public void TestToMethod() - { - bool wasCalled = false; - - Container.DeclareCommand(); - Container.HandleCommand() - .WithMethod(() => wasCalled = true); - - Initialize(); - - var cmd = Container.Resolve(); - - Assert.That(!wasCalled); - cmd.Execute(); - Assert.That(wasCalled); - } - - [Test] - public void TestMultipleHandlers() - { - bool wasCalled1 = false; - bool wasCalled2 = false; - - Container.DeclareCommand(); - Container.HandleCommand() - .WithMethod(() => wasCalled1 = true); - Container.HandleCommand() - .WithMethod(() => wasCalled2 = true); - - Initialize(); - - var cmd = Container.Resolve(); - - Assert.That(!wasCalled1); - Assert.That(!wasCalled2); - cmd.Execute(); - Assert.That(wasCalled1); - Assert.That(wasCalled2); - } - - public void TestMultipleHandlersError() - { - bool wasCalled1 = false; - bool wasCalled2 = false; - - Container.DeclareCommand() - .RequireSingleHandler(); - - Container.HandleCommand() - .WithMethod(() => wasCalled1 = true); - Container.HandleCommand() - .WithMethod(() => wasCalled2 = true); - - Initialize(); - - var cmd = Container.Resolve(); - - Assert.That(!wasCalled1); - Assert.That(!wasCalled2); - cmd.Execute(); - Assert.That(wasCalled1); - Assert.That(wasCalled2); - } - - public class DoSomethingCommand : Command - { - } - - public class Bar - { - public static int InstanceCount = 0; - - public Bar() - { - InstanceCount ++; - } - - public static bool WasTriggered - { - get; - set; - } - - public void Execute() - { - WasTriggered = true; - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs.meta deleted file mode 100644 index 59dcb0e05..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommands.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: be0ac5028ebaac948a2cc3c1b0c556fe -timeCreated: 1480710679 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs deleted file mode 100644 index 50cf3a01f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestCommandsWithParameters : ZenjectIntegrationTestFixture - { - [SetUp] - public void CommonInstall() - { - Container.BindAllInterfacesAndSelf().To().AsSingle(); - } - - [Test] - public void TestParameters1() - { - Bar1.Value = null; - - Container.DeclareCommand(); - Container.HandleCommand() - .With(x => x.Execute).AsSingle(); - - Initialize(); - - var cmd = Container.Resolve(); - - Assert.IsNull(Bar1.Value); - - cmd.Execute("asdf"); - - Assert.IsEqual(Bar1.Value, "asdf"); - } - - [Test] - public void TestParameters2() - { - Bar2.Value1 = null; - Bar2.Value2 = 0; - - Container.DeclareCommand(); - Container.HandleCommand() - .With(x => x.Execute).AsSingle(); - - Initialize(); - - var cmd = Container.Resolve(); - - Assert.IsNull(Bar2.Value1); - Assert.IsEqual(Bar2.Value2, 0); - - cmd.Execute("asdf", 4); - - Assert.IsEqual(Bar2.Value1, "asdf"); - Assert.IsEqual(Bar2.Value2, 4); - } - - [Test] - public void TestParameters3() - { - Bar3.Value1 = null; - Bar3.Value2 = 0; - Bar3.Value3 = 0.0f; - - Container.DeclareCommand(); - Container.HandleCommand() - .With(x => x.Execute).AsSingle(); - - Initialize(); - - var cmd = Container.Resolve(); - - Assert.IsNull(Bar3.Value1); - Assert.IsEqual(Bar3.Value2, 0); - Assert.IsEqual(Bar3.Value3, 0.0f); - - cmd.Execute("asdf", 4, 7.2f); - - Assert.IsEqual(Bar3.Value1, "asdf"); - Assert.IsEqual(Bar3.Value2, 4); - Assert.IsEqual(Bar3.Value3, 7.2f); - } - - [Test] - public void TestParameters4() - { - Bar4.Value1 = null; - Bar4.Value2 = 0; - Bar4.Value3 = 0.0f; - Bar4.Value4 = '0'; - - Container.DeclareCommand(); - Container.HandleCommand() - .With(x => x.Execute).AsSingle(); - - Initialize(); - - var cmd = Container.Resolve(); - - Assert.IsNull(Bar4.Value1); - Assert.IsEqual(Bar4.Value2, 0); - Assert.IsEqual(Bar4.Value3, 0.0f); - Assert.IsEqual(Bar4.Value4, '0'); - - cmd.Execute("asdf", 4, 7.2f, 'z'); - - Assert.IsEqual(Bar4.Value1, "asdf"); - Assert.IsEqual(Bar4.Value2, 4); - Assert.IsEqual(Bar4.Value3, 7.2f); - Assert.IsEqual(Bar4.Value4, 'z'); - } - - public class DoSomethingCommand1 : Command { } - public class DoSomethingCommand2 : Command { } - public class DoSomethingCommand3 : Command { } - public class DoSomethingCommand4 : Command { } - - public class Bar1 - { - public static string Value; - - public void Execute(string value) - { - Value = value; - } - } - - public class Bar2 - { - public static string Value1; - public static int Value2; - - public void Execute(string value1, int value2) - { - Value1 = value1; - Value2 = value2; - } - } - - public class Bar3 - { - public static string Value1; - public static int Value2; - public static float Value3; - - public void Execute(string value1, int value2, float value3) - { - Value1 = value1; - Value2 = value2; - Value3 = value3; - } - } - - public class Bar4 - { - public static string Value1; - public static int Value2; - public static float Value3; - public static char Value4; - - public void Execute(string value1, int value2, float value3, char value4) - { - Value1 = value1; - Value2 = value2; - Value3 = value3; - Value4 = value4; - } - } - } -} - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs.meta deleted file mode 100644 index 91901e0dc..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Commands/TestCommandsWithParameters.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 54d58f70a70c295479aaf30f1c27529a -timeCreated: 1480710679 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals.meta deleted file mode 100644 index e7c5b7847..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 1794d53da15377c49b98fbd059129e7a -folderAsset: yes -timeCreated: 1461712383 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs deleted file mode 100644 index 939baa1f8..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestSignals : ZenjectUnitTestFixture - { - [Test] - public void RunTest() - { - Container.Bind().AsSingle(); - Container.Bind().AsSingle(); - - Container.BindSignal(); - - var foo = Container.Resolve(); - var bar = Container.Resolve(); - bar.Initialize(); - - Assert.That(!bar.ReceivedSignal); - foo.DoSomething(); - Assert.That(bar.ReceivedSignal); - - bar.Dispose(); - } - - [Test] - public void RunTestSignalInterfaces() - { - Container.BindSignal(); - - Container.BindSignal(); - - Container.Bind() - .To(typeof(AnotherSignal), typeof(SomethingHappenedSignal)).FromResolve(); - - var fooSignals = Container.ResolveAll(); - - Assert.IsEqual(fooSignals.Count, 2); - } - - public interface IFooSignal - { - } - - public class SomethingHappenedSignal : Signal, IFooSignal - { - } - - public class AnotherSignal : Signal, IFooSignal - { - } - - public class Foo - { - SomethingHappenedSignal _trigger; - - public Foo(SomethingHappenedSignal trigger) - { - _trigger = trigger; - } - - public void DoSomething() - { - _trigger.Fire(); - } - } - - public class Bar - { - SomethingHappenedSignal _signal; - bool _receivedSignal; - - public Bar(SomethingHappenedSignal signal) - { - _signal = signal; - } - - public bool ReceivedSignal - { - get - { - return _receivedSignal; - } - } - - public void Initialize() - { - _signal += OnStarted; - } - - public void Dispose() - { - _signal -= OnStarted; - } - - void OnStarted() - { - _receivedSignal = true; - } - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs.meta deleted file mode 100644 index ec076a915..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: ce4ad39fbe024ff4d99e4849cd291bd3 -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs deleted file mode 100644 index 97eb39ada..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestSignalsOneParam : ZenjectUnitTestFixture - { - [Test] - public void RunTest() - { - Container.Bind().AsSingle(); - Container.Bind().AsSingle(); - - Container.BindSignal(); - - var foo = Container.Resolve(); - var bar = Container.Resolve(); - bar.Initialize(); - - Assert.IsNull(bar.ReceivedValue); - foo.DoSomething("asdf"); - Assert.IsEqual(bar.ReceivedValue, "asdf"); - - bar.Dispose(); - } - - public class SomethingHappenedSignal : Signal - { - } - - public class Foo - { - SomethingHappenedSignal _trigger; - - public Foo(SomethingHappenedSignal trigger) - { - _trigger = trigger; - } - - public void DoSomething(string value) - { - _trigger.Fire(value); - } - } - - public class Bar - { - SomethingHappenedSignal _signal; - string _receivedValue; - - public Bar(SomethingHappenedSignal signal) - { - _signal = signal; - } - - public string ReceivedValue - { - get - { - return _receivedValue; - } - } - - public void Initialize() - { - _signal += OnStarted; - } - - public void Dispose() - { - _signal -= OnStarted; - } - - void OnStarted(string value) - { - _receivedValue = value; - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs.meta deleted file mode 100644 index 3ea96a2ce..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 9fdf57189cb3f8642bb5cdb90f96cc35 -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSixParams.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSixParams.cs deleted file mode 100644 index 214153b5e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSixParams.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestSignalsSixParams : ZenjectUnitTestFixture - { - [Test] - public void RunTest() - { - Container.Bind().AsSingle(); - Container.Bind().AsSingle(); - - Container.BindSignal(); - - var foo = Container.Resolve(); - var bar = Container.Resolve(); - bar.Initialize(); - - Assert.IsNull(bar.ReceivedValue); - foo.DoSomething("asdf", 5, 1.2f, "zxcv", 5, 123.0f); - Assert.IsEqual(bar.ReceivedValue, "zxcv"); - - bar.Dispose(); - } - - public class SomethingHappenedSignal : Signal - { - } - - public class Foo - { - SomethingHappenedSignal _signal; - - public Foo(SomethingHappenedSignal signal) - { - _signal = signal; - } - - public void DoSomething(string value1, int value2, float value3, string value4, int value5, float value6) - { - _signal.Fire(value1, value2, value3, value4, value5, value6); - } - } - - public class Bar - { - SomethingHappenedSignal _signal; - string _receivedValue; - - public Bar(SomethingHappenedSignal signal) - { - _signal = signal; - } - - public string ReceivedValue - { - get - { - return _receivedValue; - } - } - - public void Initialize() - { - _signal += OnStarted; - } - - public void Dispose() - { - _signal -= OnStarted; - } - - void OnStarted(string value1, int value2, float value3, string value4, int value5, float value6) - { - _receivedValue = value4; - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSixParams.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSixParams.cs.meta deleted file mode 100644 index e718a338c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSixParams.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 08da30b429e06b84fbf6d60bdee9ab5b -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs deleted file mode 100644 index 5491b296d..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestSignalsWithIdentifiers : ZenjectUnitTestFixture - { - [Test] - public void RunTest() - { - Container.BindSignal(); - - Container.Bind().AsSingle(); - Container.Bind().AsSingle(); - - Container.BindSignal("special"); - - Container.Bind().AsSingle(); - Container.Bind().AsSingle(); - - var foo = Container.Resolve(); - var bar = Container.Resolve(); - - var fooSpecial = Container.Resolve(); - var barSpecial = Container.Resolve(); - - bar.Initialize(); - barSpecial.Initialize(); - - Assert.IsNull(bar.ReceivedValue); - Assert.IsNull(barSpecial.ReceivedValue); - - foo.DoSomething("asdf"); - - Assert.IsEqual(bar.ReceivedValue, "asdf"); - Assert.IsNull(barSpecial.ReceivedValue); - - bar.ReceivedValue = null; - - fooSpecial.DoSomething("zxcv"); - - Assert.IsEqual(barSpecial.ReceivedValue, "zxcv"); - Assert.IsNull(bar.ReceivedValue); - - bar.Dispose(); - barSpecial.Dispose(); - } - - public class SomethingHappenedSignal : Signal - { - } - - public class Foo - { - SomethingHappenedSignal _signal; - - public Foo( - SomethingHappenedSignal signal) - { - _signal = signal; - } - - public void DoSomething(string value) - { - _signal.Fire(value); - } - } - - public class Bar - { - SomethingHappenedSignal _signal; - - public Bar(SomethingHappenedSignal signal) - { - _signal = signal; - } - - public string ReceivedValue - { - get; - set; - } - - public void Initialize() - { - _signal += OnStarted; - } - - public void Dispose() - { - _signal -= OnStarted; - } - - void OnStarted(string value) - { - ReceivedValue = value; - } - } - - public class FooSpecial - { - SomethingHappenedSignal _signal; - - public FooSpecial( - [Inject(Id = "special")] - SomethingHappenedSignal signal) - { - _signal = signal; - } - - public void DoSomething(string value) - { - _signal.Fire(value); - } - } - - public class BarSpecial - { - SomethingHappenedSignal _signal; - - public BarSpecial( - [Inject(Id = "special")] - SomethingHappenedSignal signal) - { - _signal = signal; - } - - public string ReceivedValue - { - get; - set; - } - - public void Initialize() - { - _signal += OnStarted; - } - - public void Dispose() - { - _signal -= OnStarted; - } - - void OnStarted(string value) - { - ReceivedValue = value; - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs.meta deleted file mode 100644 index 70dce6eb5..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 057cd7f4732b70a4e835ddc4e469bc55 -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs deleted file mode 100644 index f1fceb444..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject; - -namespace Zenject.Tests -{ - [TestFixture] - public class TestTriggers1 : ZenjectUnitTestFixture - { - [Test] - public void Test1() - { - Container.BindSignal(); - - var signal = Container.Resolve(); - - bool received = false; - signal += delegate { received = true; }; - - // This is a compiler error - //signal.Event(); - - Assert.That(!received); - signal.Fire(); - Assert.That(received); - } - - public class FooSignal : Signal - { - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs.meta deleted file mode 100644 index 49b97367b..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 010922184142d084dae3e5f949de729f -timeCreated: 1461712384 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj index b0f5500a8..ea7c02207 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj @@ -54,10 +54,6 @@ {46f25a62-2e29-48cb-95f3-bdbcb0976ddc} Zenject - - {b543a0b8-2630-424e-b628-53457be4884b} - Zenject.Commands - diff --git a/UnityProject/Assets/Zenject/Source/Zenject.csproj b/UnityProject/Assets/Zenject/Source/Zenject.csproj index 165fc39c8..0a0d899fe 100644 --- a/UnityProject/Assets/Zenject/Source/Zenject.csproj +++ b/UnityProject/Assets/Zenject/Source/Zenject.csproj @@ -45,6 +45,7 @@ + @@ -110,6 +111,7 @@ + @@ -117,6 +119,7 @@ + From e1f9aa8843cdb419a716b97abab420adf2ce153a Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 7 Jan 2017 22:16:02 -0400 Subject: [PATCH 10/62] Renamed some of the BindInfo binder classes to be more descriptive so they can be re-used in the commands/signals package --- .../AutoMocking/ZenjectMoqExtensions.cs | 2 +- .../Binders/ArgConditionCopyNonLazyBinder.cs | 25 ++++++ ... => ArgConditionCopyNonLazyBinder.cs.meta} | 4 +- ...ArgumentsBinder.cs => ArgNonLazyBinder.cs} | 9 ++- ...inder.cs.meta => ArgNonLazyBinder.cs.meta} | 4 +- .../Binding/Binders/ArgumentsBinder.cs.meta | 12 --- ...inder.cs => ConditionCopyNonLazyBinder.cs} | 14 ++-- ...eta => ConditionCopyNonLazyBinder.cs.meta} | 6 +- ...ntainersBinder.cs => CopyNonLazyBinder.cs} | 4 +- ...nder.cs.meta => CopyNonLazyBinder.cs.meta} | 6 +- .../FactoryFromBinder/FactoryFromBinder0.cs | 14 ++-- .../FactoryFromBinder/FactoryFromBinder1.cs | 4 +- .../FactoryFromBinder/FactoryFromBinder2.cs | 4 +- .../FactoryFromBinder/FactoryFromBinder3.cs | 4 +- .../FactoryFromBinder/FactoryFromBinder4.cs | 4 +- .../FactoryFromBinder/FactoryFromBinder5.cs | 4 +- .../FactorySubContainerBinder0.cs | 12 +-- .../FactorySubContainerBinder1.cs | 4 +- .../FactorySubContainerBinder2.cs | 4 +- .../FactorySubContainerBinder3.cs | 4 +- .../FactorySubContainerBinder4.cs | 4 +- .../FactorySubContainerBinder5.cs | 4 +- .../FactorySubContainerBinderBase.cs | 6 +- .../FactorySubContainerBinderWithParams.cs | 12 +-- .../Binders/Factory/FactoryFromBinderBase.cs | 22 +++--- .../Binding/Binders/FromBinders/FromBinder.cs | 79 +++++++++++-------- .../Binders/FromBinders/FromBinderGeneric.cs | 15 ++-- .../FromBinders/FromBinderNonGeneric.cs | 13 ++- .../GameObjectGroupNameScopeArgBinder.cs.meta | 12 --- .../GameObjectGroupNameScopeBinder.cs.meta | 12 --- .../GameObjectNameGroupNameBinder.cs.meta | 12 --- ...eObjectNameGroupNameScopeArgBinder.cs.meta | 12 --- ...GameObjectNameGroupNameScopeBinder.cs.meta | 12 --- ...ameTransformConditionCopyNonLazyBinder.cs} | 6 +- ...ransformConditionCopyNonLazyBinder.cs.meta | 12 +++ ...sformScopeArgConditionCopyNonLazyBinder.cs | 22 ++++++ ...ScopeArgConditionCopyNonLazyBinder.cs.meta | 12 +++ ... => NameTransformScopeArgNonLazyBinder.cs} | 7 +- ...NameTransformScopeArgNonLazyBinder.cs.meta | 12 +++ ...ansformScopeConditionCopyNonLazyBinder.cs} | 6 +- ...ormScopeConditionCopyNonLazyBinder.cs.meta | 12 +++ ...=> TransformConditionCopyNonLazyBinder.cs} | 10 +-- ...ransformConditionCopyNonLazyBinder.cs.meta | 12 +++ ...sformScopeArgConditionCopyNonLazyBinder.cs | 43 ++++++++++ ...ScopeArgConditionCopyNonLazyBinder.cs.meta | 12 +++ ...r.cs => TransformScopeArgNonLazyBinder.cs} | 11 +-- .../TransformScopeArgNonLazyBinder.cs.meta | 12 +++ ...ansformScopeConditionCopyNonLazyBinder.cs} | 10 +-- ...ormScopeConditionCopyNonLazyBinder.cs.meta | 12 +++ .../Source/Binding/Binders/IdScopeBinder.cs | 16 ---- .../IdScopeConditionCopyNonLazyBinder.cs | 16 ++++ .../IdScopeConditionCopyNonLazyBinder.cs.meta | 12 +++ .../Binding/Binders/ScopeArgBinder.cs.meta | 12 --- .../ScopeArgConditionCopyNonLazyBinder.cs | 39 +++++++++ ...ScopeArgConditionCopyNonLazyBinder.cs.meta | 12 +++ ...eArgBinder.cs => ScopeArgNonLazyBinder.cs} | 13 +-- .../Binders/ScopeArgNonLazyBinder.cs.meta | 12 +++ .../Binding/Binders/ScopeBinder.cs.meta | 12 --- .../ScopeConditionCopyNonLazyBinder.cs | 39 +++++++++ .../ScopeConditionCopyNonLazyBinder.cs.meta | 12 +++ .../{ScopeBinder.cs => ScopeNonLazyBinder.cs} | 13 +-- .../Binders/ScopeNonLazyBinder.cs.meta | 12 +++ .../Binding/Binders/SubContainerBinder.cs | 18 ++--- .../Zenject/Source/Factories/KeyedFactory.cs | 2 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 6 +- UnityProject/Assets/Zenject/Version.txt | 2 +- 66 files changed, 531 insertions(+), 287 deletions(-) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs rename UnityProject/Assets/Zenject/Source/Binding/Binders/{CopyIntoSubContainersBinder.cs.meta => ArgConditionCopyNonLazyBinder.cs.meta} (76%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/{ArgumentsBinder.cs => ArgNonLazyBinder.cs} (57%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/{IdScopeBinder.cs.meta => ArgNonLazyBinder.cs.meta} (76%) delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ArgumentsBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/{ConditionBinder.cs => ConditionCopyNonLazyBinder.cs} (58%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/{GameObject/GameObjectGroupNameBinder.cs.meta => ConditionCopyNonLazyBinder.cs.meta} (69%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/{CopyIntoSubContainersBinder.cs => CopyNonLazyBinder.cs} (74%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/{ConditionBinder.cs.meta => CopyNonLazyBinder.cs.meta} (69%) delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeArgBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeArgBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/{GameObjectNameGroupNameBinder.cs => NameTransformConditionCopyNonLazyBinder.cs} (54%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformConditionCopyNonLazyBinder.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgConditionCopyNonLazyBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgConditionCopyNonLazyBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/{GameObjectNameGroupNameScopeBinder.cs => NameTransformScopeArgNonLazyBinder.cs} (62%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgNonLazyBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/{GameObjectNameGroupNameScopeArgBinder.cs => NameTransformScopeConditionCopyNonLazyBinder.cs} (53%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeConditionCopyNonLazyBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/{GameObjectGroupNameBinder.cs => TransformConditionCopyNonLazyBinder.cs} (57%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformConditionCopyNonLazyBinder.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgConditionCopyNonLazyBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgConditionCopyNonLazyBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/{GameObjectGroupNameScopeBinder.cs => TransformScopeArgNonLazyBinder.cs} (65%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgNonLazyBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/{GameObjectGroupNameScopeArgBinder.cs => TransformScopeConditionCopyNonLazyBinder.cs} (62%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeConditionCopyNonLazyBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeConditionCopyNonLazyBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeConditionCopyNonLazyBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgBinder.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgConditionCopyNonLazyBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgConditionCopyNonLazyBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/{ScopeArgBinder.cs => ScopeArgNonLazyBinder.cs} (67%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgNonLazyBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeBinder.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeConditionCopyNonLazyBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeConditionCopyNonLazyBinder.cs.meta rename UnityProject/Assets/Zenject/Source/Binding/Binders/{ScopeBinder.cs => ScopeNonLazyBinder.cs} (68%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeNonLazyBinder.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/AutoMocking/ZenjectMoqExtensions.cs b/UnityProject/Assets/Zenject/OptionalExtras/AutoMocking/ZenjectMoqExtensions.cs index b3575641c..6d1ca4588 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/AutoMocking/ZenjectMoqExtensions.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/AutoMocking/ZenjectMoqExtensions.cs @@ -11,7 +11,7 @@ namespace Zenject { public static class ZenjectMoqExtensions { - public static ScopeBinder FromMock(this FromBinderGeneric binder) + public static ScopeConditionCopyNonLazyBinder FromMock(this FromBinderGeneric binder) where TContract : class { #if UNITY_EDITOR && !UNITY_WEBPLAYER diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs new file mode 100644 index 000000000..55880d610 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Zenject +{ + public class ArgConditionCopyNonLazyBinder : ConditionCopyNonLazyBinder + { + public ArgConditionCopyNonLazyBinder(BindInfo bindInfo) + : base(bindInfo) + { + } + + public ConditionCopyNonLazyBinder WithArguments(params object[] args) + { + BindInfo.Arguments = InjectUtil.CreateArgList(args); + return this; + } + + public ConditionCopyNonLazyBinder WithArgumentsExplicit(IEnumerable extraArgs) + { + BindInfo.Arguments = extraArgs.ToList(); + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyIntoSubContainersBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/CopyIntoSubContainersBinder.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs.meta index 52215c940..ae1492d4d 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyIntoSubContainersBinder.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: f3141928a4651044eada61d164cff730 -timeCreated: 1477174222 +guid: d0eff25a90fc7a4479dbb9a1f74dddc2 +timeCreated: 1483833202 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgumentsBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs similarity index 57% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/ArgumentsBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs index 1bb24612c..9a42acbd0 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgumentsBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs @@ -3,23 +3,24 @@ namespace Zenject { - public class ArgumentsBinder : ConditionBinder + public class ArgNonLazyBinder : NonLazyBinder { - public ArgumentsBinder(BindInfo bindInfo) + public ArgNonLazyBinder(BindInfo bindInfo) : base(bindInfo) { } - public ConditionBinder WithArguments(params object[] args) + public NonLazyBinder WithArguments(params object[] args) { BindInfo.Arguments = InjectUtil.CreateArgList(args); return this; } - public ConditionBinder WithArgumentsExplicit(IEnumerable extraArgs) + public NonLazyBinder WithArgumentsExplicit(IEnumerable extraArgs) { BindInfo.Arguments = extraArgs.ToList(); return this; } } } + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeBinder.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs.meta index 4f0c0902b..74f9982e7 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeBinder.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 887ae236eb91b1b41ad103ceadff733c -timeCreated: 1463321349 +guid: 71c55280804e3bd48816a3244114d1f0 +timeCreated: 1483833202 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgumentsBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgumentsBinder.cs.meta deleted file mode 100644 index 9b2d5f659..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgumentsBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 084a5f41759ff214e95363ab860a89fb -timeCreated: 1461708048 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionCopyNonLazyBinder.cs similarity index 58% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionCopyNonLazyBinder.cs index 0482a925e..5d19a6e37 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionCopyNonLazyBinder.cs @@ -4,35 +4,35 @@ namespace Zenject { - public class ConditionBinder : CopyIntoSubContainersBinder + public class ConditionCopyNonLazyBinder : CopyNonLazyBinder { - public ConditionBinder(BindInfo bindInfo) + public ConditionCopyNonLazyBinder(BindInfo bindInfo) : base(bindInfo) { } - public CopyIntoSubContainersBinder When(BindingCondition condition) + public CopyNonLazyBinder When(BindingCondition condition) { BindInfo.Condition = condition; return this; } - public CopyIntoSubContainersBinder WhenInjectedIntoInstance(object instance) + public CopyNonLazyBinder WhenInjectedIntoInstance(object instance) { return When(r => ReferenceEquals(r.ObjectInstance, instance)); } - public CopyIntoSubContainersBinder WhenInjectedInto(params Type[] targets) + public CopyNonLazyBinder WhenInjectedInto(params Type[] targets) { return When(r => targets.Where(x => r.ObjectType != null && r.ObjectType.DerivesFromOrEqual(x)).Any()); } - public CopyIntoSubContainersBinder WhenInjectedInto() + public CopyNonLazyBinder WhenInjectedInto() { return When(r => r.ObjectType != null && r.ObjectType.DerivesFromOrEqual(typeof(T))); } - public CopyIntoSubContainersBinder WhenNotInjectedInto() + public CopyNonLazyBinder WhenNotInjectedInto() { return When(r => r.ObjectType == null || !r.ObjectType.DerivesFromOrEqual(typeof(T))); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionCopyNonLazyBinder.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameBinder.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionCopyNonLazyBinder.cs.meta index ab826188d..905792a7b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameBinder.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionCopyNonLazyBinder.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 0f07eaa541805f14e85b23024c9c2bf5 -timeCreated: 1461708048 -licenseType: Pro +guid: a638543bf618ed94fb418f48d9ea9329 +timeCreated: 1483833202 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyIntoSubContainersBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs similarity index 74% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/CopyIntoSubContainersBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs index b611f309e..4eb11f152 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyIntoSubContainersBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs @@ -1,9 +1,9 @@ using ModestTree; namespace Zenject { - public class CopyIntoSubContainersBinder : NonLazyBinder + public class CopyNonLazyBinder : NonLazyBinder { - public CopyIntoSubContainersBinder(BindInfo bindInfo) + public CopyNonLazyBinder(BindInfo bindInfo) : base(bindInfo) { } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs.meta index a80c3e121..a8fbbfd24 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConditionBinder.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: da956a6de7e2bdd409af77dacc8cdbc0 -timeCreated: 1461708054 -licenseType: Pro +guid: 6cf2e5d7a11cf6c418960ff59949b5fa +timeCreated: 1483833202 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs index 08a93b5aa..5ff68d3b8 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs @@ -13,12 +13,12 @@ public FactoryFromBinder( { } - public ConditionBinder FromResolveGetter(Func method) + public ConditionCopyNonLazyBinder FromResolveGetter(Func method) { return FromResolveGetter(null, method); } - public ConditionBinder FromResolveGetter( + public ConditionCopyNonLazyBinder FromResolveGetter( object subIdentifier, Func method) { SubFinalizer = CreateFinalizer( @@ -27,7 +27,7 @@ public ConditionBinder FromResolveGetter( return this; } - public ConditionBinder FromMethod(Func method) + public ConditionCopyNonLazyBinder FromMethod(Func method) { SubFinalizer = CreateFinalizer( (container) => new MethodProviderWithContainer(method)); @@ -35,7 +35,7 @@ public ConditionBinder FromMethod(Func method) return this; } - public ConditionBinder FromInstance(object instance) + public ConditionCopyNonLazyBinder FromInstance(object instance) { BindingUtil.AssertInstanceDerivesFromOrEqual(instance, AllParentTypes); @@ -45,13 +45,13 @@ public ConditionBinder FromInstance(object instance) return this; } - public ArgumentsBinder FromFactory() + public ArgConditionCopyNonLazyBinder FromFactory() where TSubFactory : IFactory { SubFinalizer = CreateFinalizer( (container) => new FactoryProvider(container, BindInfo.Arguments)); - return new ArgumentsBinder(BindInfo); + return new ArgConditionCopyNonLazyBinder(BindInfo); } public FactorySubContainerBinder FromSubContainerResolve() @@ -67,7 +67,7 @@ public FactorySubContainerBinder FromSubContainerResolve(object subId #if !NOT_UNITY3D - public ConditionBinder FromResource(string resourcePath) + public ConditionCopyNonLazyBinder FromResource(string resourcePath) { BindingUtil.AssertDerivesFromUnityObject(ContractType); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder1.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder1.cs index 58d0d9f6e..2750914dc 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder1.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder1.cs @@ -13,7 +13,7 @@ public FactoryFromBinder( { } - public ConditionBinder FromMethod(Func method) + public ConditionCopyNonLazyBinder FromMethod(Func method) { SubFinalizer = CreateFinalizer( (container) => new MethodProviderWithContainer(method)); @@ -21,7 +21,7 @@ public ConditionBinder FromMethod(Func method) return this; } - public ConditionBinder FromFactory() + public ConditionCopyNonLazyBinder FromFactory() where TSubFactory : IFactory { SubFinalizer = CreateFinalizer( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder2.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder2.cs index b5613c351..437975f7d 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder2.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder2.cs @@ -10,7 +10,7 @@ public FactoryFromBinder(BindInfo bindInfo, Type factoryType, BindFinalizerWrapp { } - public ConditionBinder FromMethod(Func method) + public ConditionCopyNonLazyBinder FromMethod(Func method) { SubFinalizer = CreateFinalizer( (container) => new MethodProviderWithContainer(method)); @@ -18,7 +18,7 @@ public ConditionBinder FromMethod(Func return this; } - public ConditionBinder FromFactory() + public ConditionCopyNonLazyBinder FromFactory() where TSubFactory : IFactory { SubFinalizer = CreateFinalizer( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder3.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder3.cs index 6cea81829..2e631358f 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder3.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder3.cs @@ -10,7 +10,7 @@ public FactoryFromBinder(BindInfo bindInfo, Type factoryType, BindFinalizerWrapp { } - public ConditionBinder FromMethod(Func method) + public ConditionCopyNonLazyBinder FromMethod(Func method) { SubFinalizer = CreateFinalizer( (container) => new MethodProviderWithContainer(method)); @@ -18,7 +18,7 @@ public ConditionBinder FromMethod(Func() + public ConditionCopyNonLazyBinder FromFactory() where TSubFactory : IFactory { SubFinalizer = CreateFinalizer( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder4.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder4.cs index affb06e55..910feef46 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder4.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder4.cs @@ -10,7 +10,7 @@ public FactoryFromBinder(BindInfo bindInfo, Type factoryType, BindFinalizerWrapp { } - public ConditionBinder FromMethod(ModestTree.Util.Func method) + public ConditionCopyNonLazyBinder FromMethod(ModestTree.Util.Func method) { SubFinalizer = CreateFinalizer( (container) => new MethodProviderWithContainer(method)); @@ -18,7 +18,7 @@ public ConditionBinder FromMethod(ModestTree.Util.Func() + public ConditionCopyNonLazyBinder FromFactory() where TSubFactory : IFactory { SubFinalizer = CreateFinalizer( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder5.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder5.cs index 2c60a84a3..9ea00d719 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder5.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder5.cs @@ -10,7 +10,7 @@ public FactoryFromBinder(BindInfo bindInfo, Type factoryType, BindFinalizerWrapp { } - public ConditionBinder FromMethod(ModestTree.Util.Func method) + public ConditionCopyNonLazyBinder FromMethod(ModestTree.Util.Func method) { SubFinalizer = CreateFinalizer( (container) => new MethodProviderWithContainer(method)); @@ -18,7 +18,7 @@ public ConditionBinder FromMethod(ModestTree.Util.Func() + public ConditionCopyNonLazyBinder FromFactory() where TSubFactory : IFactory { SubFinalizer = CreateFinalizer( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs index 766042d99..bcebd3fcb 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs @@ -12,7 +12,7 @@ public FactorySubContainerBinder( { } - public ConditionBinder ByMethod(Action installerMethod) + public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) { SubFinalizer = CreateFinalizer( (container) => new SubContainerDependencyProvider( @@ -20,12 +20,12 @@ public ConditionBinder ByMethod(Action installerMethod) new SubContainerCreatorByMethod( container, installerMethod))); - return new ConditionBinder(BindInfo); + return new ConditionCopyNonLazyBinder(BindInfo); } #if !NOT_UNITY3D - public GameObjectNameGroupNameBinder ByPrefab(UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); @@ -39,10 +39,10 @@ public GameObjectNameGroupNameBinder ByPrefab(UnityEngine.Object prefab) new PrefabProvider(prefab), gameObjectInfo))); - return new GameObjectNameGroupNameBinder(BindInfo, gameObjectInfo); + return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public GameObjectNameGroupNameBinder ByPrefabResource(string resourcePath) + public NameTransformConditionCopyNonLazyBinder ByPrefabResource(string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); @@ -56,7 +56,7 @@ public GameObjectNameGroupNameBinder ByPrefabResource(string resourcePath) new PrefabProviderResource(resourcePath), gameObjectInfo))); - return new GameObjectNameGroupNameBinder(BindInfo, gameObjectInfo); + return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } #endif } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder1.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder1.cs index 95939fba3..7ee50f521 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder1.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder1.cs @@ -12,7 +12,7 @@ public FactorySubContainerBinder( { } - public ConditionBinder ByMethod(Action installerMethod) + public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) { SubFinalizer = CreateFinalizer( (container) => new SubContainerDependencyProvider( @@ -20,7 +20,7 @@ public ConditionBinder ByMethod(Action installerMethod) new SubContainerCreatorByMethod( container, installerMethod))); - return new ConditionBinder(BindInfo); + return new ConditionCopyNonLazyBinder(BindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder2.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder2.cs index 82efbf668..dafca5349 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder2.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder2.cs @@ -12,7 +12,7 @@ public FactorySubContainerBinder( { } - public ConditionBinder ByMethod(Action installerMethod) + public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) { SubFinalizer = CreateFinalizer( (container) => new SubContainerDependencyProvider( @@ -20,7 +20,7 @@ public ConditionBinder ByMethod(Action installerM new SubContainerCreatorByMethod( container, installerMethod))); - return new ConditionBinder(BindInfo); + return new ConditionCopyNonLazyBinder(BindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder3.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder3.cs index 388f60ff3..fda8d7867 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder3.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder3.cs @@ -12,7 +12,7 @@ public FactorySubContainerBinder( { } - public ConditionBinder ByMethod(Action installerMethod) + public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) { SubFinalizer = CreateFinalizer( (container) => new SubContainerDependencyProvider( @@ -20,7 +20,7 @@ public ConditionBinder ByMethod(Action i new SubContainerCreatorByMethod( container, installerMethod))); - return new ConditionBinder(BindInfo); + return new ConditionCopyNonLazyBinder(BindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder4.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder4.cs index ae41ce66f..0a19d02d7 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder4.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder4.cs @@ -12,7 +12,7 @@ public FactorySubContainerBinder( { } - public ConditionBinder ByMethod(ModestTree.Util.Action installerMethod) + public ConditionCopyNonLazyBinder ByMethod(ModestTree.Util.Action installerMethod) { SubFinalizer = CreateFinalizer( (container) => new SubContainerDependencyProvider( @@ -20,7 +20,7 @@ public ConditionBinder ByMethod(ModestTree.Util.Action( container, installerMethod))); - return new ConditionBinder(BindInfo); + return new ConditionCopyNonLazyBinder(BindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder5.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder5.cs index d35dae058..db44b301c 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder5.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder5.cs @@ -12,7 +12,7 @@ public FactorySubContainerBinder( { } - public ConditionBinder ByMethod(ModestTree.Util.Action installerMethod) + public ConditionCopyNonLazyBinder ByMethod(ModestTree.Util.Action installerMethod) { SubFinalizer = CreateFinalizer( (container) => new SubContainerDependencyProvider( @@ -20,7 +20,7 @@ public ConditionBinder ByMethod(ModestTree.Util.Action( container, installerMethod))); - return new ConditionBinder(BindInfo); + return new ConditionCopyNonLazyBinder(BindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs index 8ea7d6a30..82a3acd20 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs @@ -61,13 +61,13 @@ protected IBindingFinalizer CreateFinalizer(Func provide BindInfo, FactoryType, providerFunc); } - public ArgumentsBinder ByInstaller() + public ArgConditionCopyNonLazyBinder ByInstaller() where TInstaller : InstallerBase { return ByInstaller(typeof(TInstaller)); } - public ArgumentsBinder ByInstaller(Type installerType) + public ArgConditionCopyNonLazyBinder ByInstaller(Type installerType) { Assert.That(installerType.DerivesFrom(), "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType.Name()); @@ -78,7 +78,7 @@ public ArgumentsBinder ByInstaller(Type installerType) new SubContainerCreatorByInstaller( container, installerType, BindInfo.Arguments))); - return new ArgumentsBinder(BindInfo); + return new ArgConditionCopyNonLazyBinder(BindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs index 8dd9626d9..c8af021f7 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs @@ -14,13 +14,13 @@ public FactorySubContainerBinderWithParams( #if !NOT_UNITY3D - public GameObjectNameGroupNameBinder ByPrefab(UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefab) where TInstaller : IInstaller { return ByPrefab(typeof(TInstaller), prefab); } - public GameObjectNameGroupNameBinder ByPrefab(Type installerType, UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder ByPrefab(Type installerType, UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); @@ -38,16 +38,16 @@ public GameObjectNameGroupNameBinder ByPrefab(Type installerType, UnityEngine.Ob new PrefabProvider(prefab), gameObjectInfo))); - return new GameObjectNameGroupNameBinder(BindInfo, gameObjectInfo); + return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public GameObjectNameGroupNameBinder ByPrefabResource(string resourcePath) + public NameTransformConditionCopyNonLazyBinder ByPrefabResource(string resourcePath) where TInstaller : IInstaller { return ByPrefabResource(typeof(TInstaller), resourcePath); } - public GameObjectNameGroupNameBinder ByPrefabResource( + public NameTransformConditionCopyNonLazyBinder ByPrefabResource( Type installerType, string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); @@ -63,7 +63,7 @@ public GameObjectNameGroupNameBinder ByPrefabResource( new PrefabProviderResource(resourcePath), gameObjectInfo))); - return new GameObjectNameGroupNameBinder(BindInfo, gameObjectInfo); + return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } #endif } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs index 2b50c20ee..899993457 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs @@ -8,7 +8,7 @@ namespace Zenject { - public class FactoryFromBinderBase : ArgumentsBinder + public class FactoryFromBinderBase : ArgConditionCopyNonLazyBinder { public FactoryFromBinderBase( BindInfo bindInfo, @@ -76,7 +76,7 @@ protected IBindingFinalizer CreateFinalizer(Func provide } // Note that this isn't necessary to call since it's the default - public ConditionBinder FromNew() + public ConditionCopyNonLazyBinder FromNew() { BindingUtil.AssertIsNotComponent(ContractType); BindingUtil.AssertIsNotAbstract(ContractType); @@ -84,12 +84,12 @@ public ConditionBinder FromNew() return this; } - public ConditionBinder FromResolve() + public ConditionCopyNonLazyBinder FromResolve() { return FromResolve(null); } - public ConditionBinder FromResolve(object subIdentifier) + public ConditionCopyNonLazyBinder FromResolve(object subIdentifier) { SubFinalizer = CreateFinalizer( (container) => new ResolveProvider( @@ -100,7 +100,7 @@ public ConditionBinder FromResolve(object subIdentifier) #if !NOT_UNITY3D - public GameObjectNameGroupNameBinder FromGameObject() + public NameTransformConditionCopyNonLazyBinder FromGameObject() { var gameObjectInfo = new GameObjectCreationParameters(); @@ -121,10 +121,10 @@ public GameObjectNameGroupNameBinder FromGameObject() new List(), gameObjectInfo)); } - return new GameObjectNameGroupNameBinder(BindInfo, gameObjectInfo); + return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public ConditionBinder FromComponent(GameObject gameObject) + public ConditionCopyNonLazyBinder FromComponent(GameObject gameObject) { BindingUtil.AssertIsValidGameObject(gameObject); BindingUtil.AssertIsComponent(ContractType); @@ -138,7 +138,7 @@ public ConditionBinder FromComponent(GameObject gameObject) return this; } - public GameObjectNameGroupNameBinder FromPrefab(UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder FromPrefab(UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); @@ -164,10 +164,10 @@ public GameObjectNameGroupNameBinder FromPrefab(UnityEngine.Object prefab) new List(), new PrefabProvider(prefab)))); } - return new GameObjectNameGroupNameBinder(BindInfo, gameObjectInfo); + return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public GameObjectNameGroupNameBinder FromPrefabResource(string resourcePath) + public NameTransformConditionCopyNonLazyBinder FromPrefabResource(string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); @@ -193,7 +193,7 @@ public GameObjectNameGroupNameBinder FromPrefabResource(string resourcePath) new List(), new PrefabProviderResource(resourcePath)))); } - return new GameObjectNameGroupNameBinder(BindInfo, gameObjectInfo); + return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } #endif } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index e1910eede..e1b8e0e0a 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -11,7 +11,7 @@ namespace Zenject { - public abstract class FromBinder : ScopeArgBinder + public abstract class FromBinder : ScopeArgConditionCopyNonLazyBinder { public FromBinder( BindInfo bindInfo, @@ -58,7 +58,7 @@ protected IEnumerable ConcreteTypes } // This is the default if nothing else is called - public ScopeArgBinder FromNew() + public ScopeArgConditionCopyNonLazyBinder FromNew() { BindingUtil.AssertTypesAreNotComponents(ConcreteTypes); BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); @@ -66,19 +66,19 @@ public ScopeArgBinder FromNew() return this; } - public ScopeBinder FromResolve() + public ScopeConditionCopyNonLazyBinder FromResolve() { return FromResolve(null); } - public ScopeBinder FromResolve(object subIdentifier) + public ScopeConditionCopyNonLazyBinder FromResolve(object subIdentifier) { SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.ToResolve, subIdentifier, (container, type) => new ResolveProvider(type, container, subIdentifier, false)); - return new ScopeBinder(BindInfo); + return new ScopeConditionCopyNonLazyBinder(BindInfo); } public SubContainerBinder FromSubContainerResolve() @@ -92,7 +92,7 @@ public SubContainerBinder FromSubContainerResolve(object subIdentifier) BindInfo, FinalizerWrapper, subIdentifier); } - public ScopeArgBinder FromFactory(Type factoryType) + public ScopeArgConditionCopyNonLazyBinder FromFactory(Type factoryType) { Assert.That(factoryType.DerivesFrom()); @@ -102,12 +102,12 @@ public ScopeArgBinder FromFactory(Type factoryType) (container, type) => new UntypedFactoryProvider( factoryType, container, BindInfo.Arguments)); - return new ScopeArgBinder(BindInfo); + return new ScopeArgConditionCopyNonLazyBinder(BindInfo); } #if !NOT_UNITY3D - public ScopeArgBinder FromComponent(GameObject gameObject) + public ScopeArgConditionCopyNonLazyBinder FromComponent(GameObject gameObject) { BindingUtil.AssertIsValidGameObject(gameObject); BindingUtil.AssertIsComponent(ConcreteTypes); @@ -118,10 +118,10 @@ public ScopeArgBinder FromComponent(GameObject gameObject) (container, type) => new AddToExistingGameObjectComponentProvider( gameObject, container, type, BindInfo.ConcreteIdentifier, BindInfo.Arguments)); - return new ScopeArgBinder(BindInfo); + return new ScopeArgConditionCopyNonLazyBinder(BindInfo); } - public ArgumentsBinder FromSiblingComponent() + public ArgConditionCopyNonLazyBinder FromSiblingComponent() { BindingUtil.AssertIsComponent(ConcreteTypes); BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); @@ -130,16 +130,20 @@ public ArgumentsBinder FromSiblingComponent() BindInfo, (container, type) => new AddToCurrentGameObjectComponentProvider( container, type, BindInfo.ConcreteIdentifier, BindInfo.Arguments)); - return new ArgumentsBinder(BindInfo); + return new ArgConditionCopyNonLazyBinder(BindInfo); } - public GameObjectNameGroupNameScopeArgBinder FromGameObject() + public NameTransformScopeArgConditionCopyNonLazyBinder FromGameObject() + { + return FromGameObject(new GameObjectCreationParameters()); + } + + public NameTransformScopeArgConditionCopyNonLazyBinder FromGameObject( + GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsAbstractOrComponentOrGameObject(BindInfo.ContractTypes); BindingUtil.AssertIsComponentOrGameObject(ConcreteTypes); - var gameObjectInfo = new GameObjectCreationParameters(); - if (ConcreteTypes.All(x => x == typeof(GameObject))) { SubFinalizer = new ScopableBindingFinalizer( @@ -166,36 +170,45 @@ public GameObjectNameGroupNameScopeArgBinder FromGameObject() gameObjectInfo)); } - return new GameObjectNameGroupNameScopeArgBinder(BindInfo, gameObjectInfo); + return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); + } + + public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefab(UnityEngine.Object prefab) + { + return FromPrefab( + prefab, new GameObjectCreationParameters()); } - public GameObjectNameGroupNameScopeArgBinder FromPrefab(UnityEngine.Object prefab) + public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefab( + UnityEngine.Object prefab, GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsValidPrefab(prefab); BindingUtil.AssertIsAbstractOrComponentOrGameObject(AllParentTypes); - var gameObjectInfo = new GameObjectCreationParameters(); - SubFinalizer = new PrefabBindingFinalizer( BindInfo, gameObjectInfo, prefab); - return new GameObjectNameGroupNameScopeArgBinder(BindInfo, gameObjectInfo); + return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); + } + + public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefabResource(string resourcePath) + { + return FromPrefabResource(resourcePath, new GameObjectCreationParameters()); } - public GameObjectNameGroupNameScopeArgBinder FromPrefabResource(string resourcePath) + public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefabResource( + string resourcePath, GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsValidResourcePath(resourcePath); BindingUtil.AssertIsAbstractOrComponentOrGameObject(AllParentTypes); - var gameObjectInfo = new GameObjectCreationParameters(); - SubFinalizer = new PrefabResourceBindingFinalizer( BindInfo, gameObjectInfo, resourcePath); - return new GameObjectNameGroupNameScopeArgBinder(BindInfo, gameObjectInfo); + return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public ScopeBinder FromResource(string resourcePath) + public ScopeConditionCopyNonLazyBinder FromResource(string resourcePath) { BindingUtil.AssertDerivesFromUnityObject(ConcreteTypes); @@ -205,12 +218,12 @@ public ScopeBinder FromResource(string resourcePath) resourcePath.ToLower(), (_, type) => new ResourceProvider(resourcePath, type)); - return new ScopeBinder(BindInfo); + return new ScopeConditionCopyNonLazyBinder(BindInfo); } #endif - public ScopeArgBinder FromMethodUntyped(Func method) + public ScopeArgConditionCopyNonLazyBinder FromMethodUntyped(Func method) { SubFinalizer = new ScopableBindingFinalizer( BindInfo, @@ -220,7 +233,7 @@ public ScopeArgBinder FromMethodUntyped(Func method) return this; } - protected ScopeArgBinder FromMethodBase(Func method) + protected ScopeArgConditionCopyNonLazyBinder FromMethodBase(Func method) { BindingUtil.AssertIsDerivedFromTypes(typeof(TConcrete), AllParentTypes); @@ -232,7 +245,7 @@ protected ScopeArgBinder FromMethodBase(Func() + protected ScopeArgConditionCopyNonLazyBinder FromFactoryBase() where TFactory : IFactory { BindingUtil.AssertIsDerivedFromTypes(typeof(TConcrete), AllParentTypes); @@ -242,10 +255,10 @@ protected ScopeArgBinder FromFactoryBase() SingletonTypes.ToFactory, typeof(TFactory), (container, type) => new FactoryProvider(container, BindInfo.Arguments)); - return new ScopeArgBinder(BindInfo); + return new ScopeArgConditionCopyNonLazyBinder(BindInfo); } - protected ScopeBinder FromResolveGetterBase( + protected ScopeConditionCopyNonLazyBinder FromResolveGetterBase( object identifier, Func method) { BindingUtil.AssertIsDerivedFromTypes(typeof(TResult), AllParentTypes); @@ -256,10 +269,10 @@ protected ScopeBinder FromResolveGetterBase( new SingletonImplIds.ToGetter(identifier, method), (container, type) => new GetterProvider(identifier, method, container)); - return new ScopeBinder(BindInfo); + return new ScopeConditionCopyNonLazyBinder(BindInfo); } - protected ScopeBinder FromInstanceBase(object instance, bool allowNull) + protected ScopeConditionCopyNonLazyBinder FromInstanceBase(object instance, bool allowNull) { if (!allowNull) { @@ -274,7 +287,7 @@ protected ScopeBinder FromInstanceBase(object instance, bool allowNull) BindInfo, SingletonTypes.ToInstance, instance, (container, type) => new InstanceProvider(container, type, instance)); - return new ScopeBinder(BindInfo); + return new ScopeConditionCopyNonLazyBinder(BindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs index b6d1184de..035bf5713 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs @@ -12,43 +12,42 @@ public FromBinderGeneric( BindingUtil.AssertIsDerivedFromTypes(typeof(TContract), BindInfo.ContractTypes); } - public ScopeArgBinder FromFactory() + public ScopeArgConditionCopyNonLazyBinder FromFactory() where TFactory : IFactory { return FromFactoryBase(); } - public ScopeArgBinder FromFactory() + public ScopeArgConditionCopyNonLazyBinder FromFactory() where TFactory : IFactory where TConcrete : TContract { return FromFactoryBase(); } - public ScopeArgBinder FromMethod(Func method) + public ScopeArgConditionCopyNonLazyBinder FromMethod(Func method) { return FromMethodBase(method); } - public ScopeBinder FromResolveGetter(Func method) + public ScopeConditionCopyNonLazyBinder FromResolveGetter(Func method) { return FromResolveGetter(null, method); } - public ScopeBinder FromResolveGetter(object identifier, Func method) + public ScopeConditionCopyNonLazyBinder FromResolveGetter(object identifier, Func method) { return FromResolveGetterBase(identifier, method); } - public ScopeBinder FromInstance(TContract instance) + public ScopeConditionCopyNonLazyBinder FromInstance(TContract instance) { return FromInstance(instance, false); } - public ScopeBinder FromInstance(TContract instance, bool allowNull) + public ScopeConditionCopyNonLazyBinder FromInstance(TContract instance, bool allowNull) { return FromInstanceBase(instance, allowNull); } } } - diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderNonGeneric.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderNonGeneric.cs index 7cccc066d..65b531c95 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderNonGeneric.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderNonGeneric.cs @@ -11,36 +11,35 @@ public FromBinderNonGeneric( { } - public ScopeArgBinder FromFactory() + public ScopeArgConditionCopyNonLazyBinder FromFactory() where TFactory : IFactory { return FromFactoryBase(); } - public ScopeArgBinder FromMethod(Func method) + public ScopeArgConditionCopyNonLazyBinder FromMethod(Func method) { return FromMethodBase(method); } - public ScopeBinder FromResolveGetter(Func method) + public ScopeConditionCopyNonLazyBinder FromResolveGetter(Func method) { return FromResolveGetter(null, method); } - public ScopeBinder FromResolveGetter(object identifier, Func method) + public ScopeConditionCopyNonLazyBinder FromResolveGetter(object identifier, Func method) { return FromResolveGetterBase(identifier, method); } - public ScopeBinder FromInstance(object instance) + public ScopeConditionCopyNonLazyBinder FromInstance(object instance) { return FromInstance(instance, false); } - public ScopeBinder FromInstance(object instance, bool allowNull) + public ScopeConditionCopyNonLazyBinder FromInstance(object instance, bool allowNull) { return FromInstanceBase(instance, allowNull); } } } - diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeArgBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeArgBinder.cs.meta deleted file mode 100644 index 7d830a29e..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeArgBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 34e63a233a088e944a32590c76919c16 -timeCreated: 1461708049 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeBinder.cs.meta deleted file mode 100644 index c7b39d9e9..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3da4853aeaa68824db5e7c8af3c8e45e -timeCreated: 1461708049 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameBinder.cs.meta deleted file mode 100644 index a5cfad5bb..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4f1cc8d9735442c4ea28caf540a764b1 -timeCreated: 1461708050 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeArgBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeArgBinder.cs.meta deleted file mode 100644 index bde82516e..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeArgBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 6eb8f3951eafa0b4dbc408a1b719dadb -timeCreated: 1461708051 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeBinder.cs.meta deleted file mode 100644 index e81ec4946..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: ee810770ed5ffc2479349ede9e969369 -timeCreated: 1461708054 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformConditionCopyNonLazyBinder.cs similarity index 54% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformConditionCopyNonLazyBinder.cs index 35156daa4..a26ca40c9 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformConditionCopyNonLazyBinder.cs @@ -2,15 +2,15 @@ namespace Zenject { - public class GameObjectNameGroupNameBinder : GameObjectGroupNameBinder + public class NameTransformConditionCopyNonLazyBinder : TransformConditionCopyNonLazyBinder { - public GameObjectNameGroupNameBinder( + public NameTransformConditionCopyNonLazyBinder( BindInfo bindInfo, GameObjectCreationParameters gameObjectInfo) : base(bindInfo, gameObjectInfo) { } - public GameObjectGroupNameBinder WithGameObjectName(string gameObjectName) + public TransformConditionCopyNonLazyBinder WithGameObjectName(string gameObjectName) { GameObjectInfo.Name = gameObjectName; return this; diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..1267d1abb --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: da8964661c7b6d54ca3c303423fa09a2 +timeCreated: 1483833202 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgConditionCopyNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgConditionCopyNonLazyBinder.cs new file mode 100644 index 000000000..42f97a998 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgConditionCopyNonLazyBinder.cs @@ -0,0 +1,22 @@ +#if !NOT_UNITY3D + +namespace Zenject +{ + public class NameTransformScopeArgConditionCopyNonLazyBinder : TransformScopeArgConditionCopyNonLazyBinder + { + public NameTransformScopeArgConditionCopyNonLazyBinder( + BindInfo bindInfo, + GameObjectCreationParameters gameObjectInfo) + : base(bindInfo, gameObjectInfo) + { + } + + public TransformScopeArgConditionCopyNonLazyBinder WithGameObjectName(string gameObjectName) + { + GameObjectInfo.Name = gameObjectName; + return this; + } + } +} + +#endif diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..76b39a50f --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5af74c801595f2d458350c212ddd5b52 +timeCreated: 1483833202 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgNonLazyBinder.cs similarity index 62% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgNonLazyBinder.cs index 9bcd98035..cc976b158 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgNonLazyBinder.cs @@ -2,16 +2,16 @@ namespace Zenject { - public class GameObjectNameGroupNameScopeBinder : GameObjectGroupNameScopeBinder + public class NameTransformScopeArgNonLazyBinder : TransformScopeArgNonLazyBinder { - public GameObjectNameGroupNameScopeBinder( + public NameTransformScopeArgNonLazyBinder( BindInfo bindInfo, GameObjectCreationParameters gameObjectInfo) : base(bindInfo, gameObjectInfo) { } - public GameObjectGroupNameScopeBinder WithGameObjectName(string gameObjectName) + public TransformScopeArgNonLazyBinder WithGameObjectName(string gameObjectName) { GameObjectInfo.Name = gameObjectName; return this; @@ -20,3 +20,4 @@ public GameObjectGroupNameScopeBinder WithGameObjectName(string gameObjectName) } #endif + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgNonLazyBinder.cs.meta new file mode 100644 index 000000000..9f9a58bf9 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeArgNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: aa33e6042ce404a4f839a3c27a697a04 +timeCreated: 1483833202 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeArgBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeConditionCopyNonLazyBinder.cs similarity index 53% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeArgBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeConditionCopyNonLazyBinder.cs index a63534dd7..1da60ce3b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectNameGroupNameScopeArgBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeConditionCopyNonLazyBinder.cs @@ -2,16 +2,16 @@ namespace Zenject { - public class GameObjectNameGroupNameScopeArgBinder : GameObjectGroupNameScopeArgBinder + public class NameTransformScopeConditionCopyNonLazyBinder : TransformScopeConditionCopyNonLazyBinder { - public GameObjectNameGroupNameScopeArgBinder( + public NameTransformScopeConditionCopyNonLazyBinder( BindInfo bindInfo, GameObjectCreationParameters gameObjectInfo) : base(bindInfo, gameObjectInfo) { } - public GameObjectGroupNameScopeArgBinder WithGameObjectName(string gameObjectName) + public TransformScopeConditionCopyNonLazyBinder WithGameObjectName(string gameObjectName) { GameObjectInfo.Name = gameObjectName; return this; diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..ac0b0f66f --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/NameTransformScopeConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f4e6abc79259aa54db4d9a7b46581029 +timeCreated: 1483833203 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformConditionCopyNonLazyBinder.cs similarity index 57% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformConditionCopyNonLazyBinder.cs index 84ad7d9e9..4ab14d796 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformConditionCopyNonLazyBinder.cs @@ -4,9 +4,9 @@ using UnityEngine; namespace Zenject { - public class GameObjectGroupNameBinder : ConditionBinder + public class TransformConditionCopyNonLazyBinder : ConditionCopyNonLazyBinder { - public GameObjectGroupNameBinder(BindInfo bindInfo, GameObjectCreationParameters gameObjInfo) + public TransformConditionCopyNonLazyBinder(BindInfo bindInfo, GameObjectCreationParameters gameObjInfo) : base(bindInfo) { GameObjectInfo = gameObjInfo; @@ -18,19 +18,19 @@ protected GameObjectCreationParameters GameObjectInfo private set; } - public ConditionBinder UnderTransform(Transform parent) + public ConditionCopyNonLazyBinder UnderTransform(Transform parent) { GameObjectInfo.ParentTransform = parent; return this; } - public ConditionBinder UnderTransform(Func parentGetter) + public ConditionCopyNonLazyBinder UnderTransform(Func parentGetter) { GameObjectInfo.ParentTransformGetter = parentGetter; return this; } - public ConditionBinder UnderTransformGroup(string transformGroupname) + public ConditionCopyNonLazyBinder UnderTransformGroup(string transformGroupname) { GameObjectInfo.GroupName = transformGroupname; return this; diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..dfad1095c --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 846dc8b98a861b44782334efc90109bb +timeCreated: 1483833202 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgConditionCopyNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgConditionCopyNonLazyBinder.cs new file mode 100644 index 000000000..4d814f3ed --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgConditionCopyNonLazyBinder.cs @@ -0,0 +1,43 @@ +#if !NOT_UNITY3D + +using System; +using UnityEngine; +namespace Zenject +{ + public class TransformScopeArgConditionCopyNonLazyBinder : ScopeArgConditionCopyNonLazyBinder + { + public TransformScopeArgConditionCopyNonLazyBinder( + BindInfo bindInfo, + GameObjectCreationParameters gameObjectInfo) + : base(bindInfo) + { + GameObjectInfo = gameObjectInfo; + } + + protected GameObjectCreationParameters GameObjectInfo + { + get; + private set; + } + + public ScopeArgConditionCopyNonLazyBinder UnderTransform(Transform parent) + { + GameObjectInfo.ParentTransform = parent; + return this; + } + + public ScopeArgConditionCopyNonLazyBinder UnderTransform(Func parentGetter) + { + GameObjectInfo.ParentTransformGetter = parentGetter; + return this; + } + + public ScopeArgConditionCopyNonLazyBinder UnderTransformGroup(string transformGroupname) + { + GameObjectInfo.GroupName = transformGroupname; + return this; + } + } +} + +#endif diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..e8829f5c6 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a1ae50515b6b4f145b4a03a7d2aefc10 +timeCreated: 1483833202 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgNonLazyBinder.cs similarity index 65% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgNonLazyBinder.cs index b943a6e84..ff2e0bc42 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgNonLazyBinder.cs @@ -4,9 +4,9 @@ using UnityEngine; namespace Zenject { - public class GameObjectGroupNameScopeBinder : ScopeBinder + public class TransformScopeArgNonLazyBinder : ScopeArgNonLazyBinder { - public GameObjectGroupNameScopeBinder( + public TransformScopeArgNonLazyBinder( BindInfo bindInfo, GameObjectCreationParameters gameObjectInfo) : base(bindInfo) @@ -20,19 +20,19 @@ protected GameObjectCreationParameters GameObjectInfo private set; } - public ScopeBinder UnderTransform(Transform parent) + public ScopeArgNonLazyBinder UnderTransform(Transform parent) { GameObjectInfo.ParentTransform = parent; return this; } - public ScopeBinder UnderTransform(Func parentGetter) + public ScopeArgNonLazyBinder UnderTransform(Func parentGetter) { GameObjectInfo.ParentTransformGetter = parentGetter; return this; } - public ScopeBinder UnderTransformGroup(string transformGroupname) + public ScopeArgNonLazyBinder UnderTransformGroup(string transformGroupname) { GameObjectInfo.GroupName = transformGroupname; return this; @@ -41,3 +41,4 @@ public ScopeBinder UnderTransformGroup(string transformGroupname) } #endif + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgNonLazyBinder.cs.meta new file mode 100644 index 000000000..4ba9618c8 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeArgNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0f4eba870ab01f44a8f09044fa2dfcf7 +timeCreated: 1483833201 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeArgBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeConditionCopyNonLazyBinder.cs similarity index 62% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeArgBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeConditionCopyNonLazyBinder.cs index 4ad5a6623..c8f1b0bcd 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/GameObjectGroupNameScopeArgBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeConditionCopyNonLazyBinder.cs @@ -4,9 +4,9 @@ using UnityEngine; namespace Zenject { - public class GameObjectGroupNameScopeArgBinder : ScopeArgBinder + public class TransformScopeConditionCopyNonLazyBinder : ScopeConditionCopyNonLazyBinder { - public GameObjectGroupNameScopeArgBinder( + public TransformScopeConditionCopyNonLazyBinder( BindInfo bindInfo, GameObjectCreationParameters gameObjectInfo) : base(bindInfo) @@ -20,19 +20,19 @@ protected GameObjectCreationParameters GameObjectInfo private set; } - public ScopeArgBinder UnderTransform(Transform parent) + public ScopeConditionCopyNonLazyBinder UnderTransform(Transform parent) { GameObjectInfo.ParentTransform = parent; return this; } - public ScopeArgBinder UnderTransform(Func parentGetter) + public ScopeConditionCopyNonLazyBinder UnderTransform(Func parentGetter) { GameObjectInfo.ParentTransformGetter = parentGetter; return this; } - public ScopeArgBinder UnderTransformGroup(string transformGroupname) + public ScopeConditionCopyNonLazyBinder UnderTransformGroup(string transformGroupname) { GameObjectInfo.GroupName = transformGroupname; return this; diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..fc65b8db1 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/GameObject/TransformScopeConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 322248bc158e67d4fa16b727e73a40a2 +timeCreated: 1483833201 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeBinder.cs deleted file mode 100644 index 79a775c0b..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeBinder.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Zenject -{ - public class IdScopeBinder : ScopeBinder - { - public IdScopeBinder(BindInfo bindInfo) - : base(bindInfo) - { - } - - public ScopeBinder WithId(object identifier) - { - BindInfo.Identifier = identifier; - return this; - } - } -} diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeConditionCopyNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeConditionCopyNonLazyBinder.cs new file mode 100644 index 000000000..75928370d --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeConditionCopyNonLazyBinder.cs @@ -0,0 +1,16 @@ +namespace Zenject +{ + public class IdScopeConditionCopyNonLazyBinder : ScopeConditionCopyNonLazyBinder + { + public IdScopeConditionCopyNonLazyBinder(BindInfo bindInfo) + : base(bindInfo) + { + } + + public ScopeConditionCopyNonLazyBinder WithId(object identifier) + { + BindInfo.Identifier = identifier; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..c6d804e02 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdScopeConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3c65f57f681813347a60ce759489885b +timeCreated: 1483833201 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgBinder.cs.meta deleted file mode 100644 index edddf8dab..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5db64cdd1b047a84c860dfa6dd944278 -timeCreated: 1461708050 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgConditionCopyNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgConditionCopyNonLazyBinder.cs new file mode 100644 index 000000000..9ff8f2346 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgConditionCopyNonLazyBinder.cs @@ -0,0 +1,39 @@ +using ModestTree; + +namespace Zenject +{ + public class ScopeArgConditionCopyNonLazyBinder : ArgConditionCopyNonLazyBinder + { + public ScopeArgConditionCopyNonLazyBinder(BindInfo bindInfo) + : base(bindInfo) + { + } + + public ArgConditionCopyNonLazyBinder AsSingle() + { + return AsSingle(null); + } + + public ArgConditionCopyNonLazyBinder AsSingle(object concreteIdentifier) + { + Assert.IsNull(BindInfo.ConcreteIdentifier); + + BindInfo.Scope = ScopeTypes.Singleton; + BindInfo.ConcreteIdentifier = concreteIdentifier; + return this; + } + + public ArgConditionCopyNonLazyBinder AsCached() + { + BindInfo.Scope = ScopeTypes.Cached; + return this; + } + + // Note that this is the default so it's not necessary to call this + public ArgConditionCopyNonLazyBinder AsTransient() + { + BindInfo.Scope = ScopeTypes.Transient; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..8dddeb9d1 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c2426e868a6366d4a9402ae5d432108f +timeCreated: 1483833202 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgNonLazyBinder.cs similarity index 67% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgNonLazyBinder.cs index 7c03385df..53cf02f96 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgNonLazyBinder.cs @@ -2,19 +2,19 @@ namespace Zenject { - public class ScopeArgBinder : ArgumentsBinder + public class ScopeArgNonLazyBinder : ArgNonLazyBinder { - public ScopeArgBinder(BindInfo bindInfo) + public ScopeArgNonLazyBinder(BindInfo bindInfo) : base(bindInfo) { } - public ArgumentsBinder AsSingle() + public ArgNonLazyBinder AsSingle() { return AsSingle(null); } - public ArgumentsBinder AsSingle(object concreteIdentifier) + public ArgNonLazyBinder AsSingle(object concreteIdentifier) { Assert.IsNull(BindInfo.ConcreteIdentifier); @@ -23,17 +23,18 @@ public ArgumentsBinder AsSingle(object concreteIdentifier) return this; } - public ArgumentsBinder AsCached() + public ArgNonLazyBinder AsCached() { BindInfo.Scope = ScopeTypes.Cached; return this; } // Note that this is the default so it's not necessary to call this - public ArgumentsBinder AsTransient() + public ArgNonLazyBinder AsTransient() { BindInfo.Scope = ScopeTypes.Transient; return this; } } } + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgNonLazyBinder.cs.meta new file mode 100644 index 000000000..64db707f2 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeArgNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 37e1bc8789d95ed408fbeb70c376d056 +timeCreated: 1483833201 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeBinder.cs.meta deleted file mode 100644 index 72525a76c..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeBinder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 1e35d68e3e1d0a841a636b2125a491a5 -timeCreated: 1461708048 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeConditionCopyNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeConditionCopyNonLazyBinder.cs new file mode 100644 index 000000000..8a0dc9be0 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeConditionCopyNonLazyBinder.cs @@ -0,0 +1,39 @@ +using ModestTree; + +namespace Zenject +{ + public class ScopeConditionCopyNonLazyBinder : ConditionCopyNonLazyBinder + { + public ScopeConditionCopyNonLazyBinder(BindInfo bindInfo) + : base(bindInfo) + { + } + + public ConditionCopyNonLazyBinder AsSingle() + { + return AsSingle(null); + } + + public ConditionCopyNonLazyBinder AsSingle(object concreteIdentifier) + { + Assert.IsNull(BindInfo.ConcreteIdentifier); + + BindInfo.Scope = ScopeTypes.Singleton; + BindInfo.ConcreteIdentifier = concreteIdentifier; + return this; + } + + public ConditionCopyNonLazyBinder AsCached() + { + BindInfo.Scope = ScopeTypes.Cached; + return this; + } + + // Note that this is the default so it's not necessary to call this + public ConditionCopyNonLazyBinder AsTransient() + { + BindInfo.Scope = ScopeTypes.Transient; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeConditionCopyNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeConditionCopyNonLazyBinder.cs.meta new file mode 100644 index 000000000..193e6b4ae --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeConditionCopyNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 74403915c364af945bfc6ff54d7e5bb6 +timeCreated: 1483833202 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeNonLazyBinder.cs similarity index 68% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeNonLazyBinder.cs index d2b884473..537bf3e71 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeNonLazyBinder.cs @@ -2,19 +2,19 @@ namespace Zenject { - public class ScopeBinder : ConditionBinder + public class ScopeNonLazyBinder : NonLazyBinder { - public ScopeBinder(BindInfo bindInfo) + public ScopeNonLazyBinder(BindInfo bindInfo) : base(bindInfo) { } - public ConditionBinder AsSingle() + public NonLazyBinder AsSingle() { return AsSingle(null); } - public ConditionBinder AsSingle(object concreteIdentifier) + public NonLazyBinder AsSingle(object concreteIdentifier) { Assert.IsNull(BindInfo.ConcreteIdentifier); @@ -23,14 +23,14 @@ public ConditionBinder AsSingle(object concreteIdentifier) return this; } - public ConditionBinder AsCached() + public NonLazyBinder AsCached() { BindInfo.Scope = ScopeTypes.Cached; return this; } // Note that this is the default so it's not necessary to call this - public ConditionBinder AsTransient() + public NonLazyBinder AsTransient() { BindInfo.Scope = ScopeTypes.Transient; return this; @@ -38,3 +38,4 @@ public ConditionBinder AsTransient() } } + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeNonLazyBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeNonLazyBinder.cs.meta new file mode 100644 index 000000000..fc3cd9394 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ScopeNonLazyBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3040e09a43bdb9842a7d713a68b7bb46 +timeCreated: 1483833201 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs index b2453dcb7..72fe32166 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs @@ -30,13 +30,13 @@ protected IBindingFinalizer SubFinalizer } } - public ScopeBinder ByInstaller() + public ScopeConditionCopyNonLazyBinder ByInstaller() where TInstaller : InstallerBase { return ByInstaller(typeof(TInstaller)); } - public ScopeBinder ByInstaller(Type installerType) + public ScopeConditionCopyNonLazyBinder ByInstaller(Type installerType) { Assert.That(installerType.DerivesFrom(), "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType.Name()); @@ -44,20 +44,20 @@ public ScopeBinder ByInstaller(Type installerType) SubFinalizer = new SubContainerInstallerBindingFinalizer( _bindInfo, installerType, _subIdentifier); - return new ScopeBinder(_bindInfo); + return new ScopeConditionCopyNonLazyBinder(_bindInfo); } - public ScopeBinder ByMethod(Action installerMethod) + public ScopeConditionCopyNonLazyBinder ByMethod(Action installerMethod) { SubFinalizer = new SubContainerMethodBindingFinalizer( _bindInfo, installerMethod, _subIdentifier); - return new ScopeBinder(_bindInfo); + return new ScopeConditionCopyNonLazyBinder(_bindInfo); } #if !NOT_UNITY3D - public GameObjectNameGroupNameScopeBinder ByPrefab(UnityEngine.Object prefab) + public NameTransformScopeConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); @@ -66,10 +66,10 @@ public GameObjectNameGroupNameScopeBinder ByPrefab(UnityEngine.Object prefab) SubFinalizer = new SubContainerPrefabBindingFinalizer( _bindInfo, gameObjectInfo, prefab, _subIdentifier); - return new GameObjectNameGroupNameScopeBinder(_bindInfo, gameObjectInfo); + return new NameTransformScopeConditionCopyNonLazyBinder(_bindInfo, gameObjectInfo); } - public GameObjectNameGroupNameScopeBinder ByPrefabResource(string resourcePath) + public NameTransformScopeConditionCopyNonLazyBinder ByPrefabResource(string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); @@ -78,7 +78,7 @@ public GameObjectNameGroupNameScopeBinder ByPrefabResource(string resourcePath) SubFinalizer = new SubContainerPrefabResourceBindingFinalizer( _bindInfo, gameObjectInfo, resourcePath, _subIdentifier); - return new GameObjectNameGroupNameScopeBinder(_bindInfo, gameObjectInfo); + return new NameTransformScopeConditionCopyNonLazyBinder(_bindInfo, gameObjectInfo); } #endif } diff --git a/UnityProject/Assets/Zenject/Source/Factories/KeyedFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/KeyedFactory.cs index 37aeef814..2276cf628 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/KeyedFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/KeyedFactory.cs @@ -86,7 +86,7 @@ public virtual void Validate() } } - protected static ConditionBinder AddBindingInternal(DiContainer container, TKey key) + protected static ConditionCopyNonLazyBinder AddBindingInternal(DiContainer container, TKey key) where TDerived : TBase { return container.Bind>() diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 59812b863..47e7637dc 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -1958,12 +1958,12 @@ public ConcreteIdBinderNonGeneric BindAllInterfacesAndSelf(Type type) // // Container.Bind().FromInstance(new Foo()); // - public IdScopeBinder BindInstance(TContract instance) + public IdScopeConditionCopyNonLazyBinder BindInstance(TContract instance) { return BindInstance(instance, false); } - public IdScopeBinder BindInstance(TContract instance, bool allowNull) + public IdScopeConditionCopyNonLazyBinder BindInstance(TContract instance, bool allowNull) { if (!allowNull) { @@ -1978,7 +1978,7 @@ public IdScopeBinder BindInstance(TContract instance, bool allowNull) bindInfo, SingletonTypes.ToInstance, instance, (container, type) => new InstanceProvider(container, type, instance)); - return new IdScopeBinder(bindInfo); + return new IdScopeConditionCopyNonLazyBinder(bindInfo); } public FactoryToChoiceIdBinder BindIFactory() diff --git a/UnityProject/Assets/Zenject/Version.txt b/UnityProject/Assets/Zenject/Version.txt index 4f8c63965..ef216a53f 100644 --- a/UnityProject/Assets/Zenject/Version.txt +++ b/UnityProject/Assets/Zenject/Version.txt @@ -1 +1 @@ -4.7 +4.8 From bf6971019a533424268738be58ef45f9951cde6a Mon Sep 17 00:00:00 2001 From: Helton Leal Date: Wed, 21 Dec 2016 23:53:52 -0300 Subject: [PATCH 11/62] Fixed an issue where Instantiate of a clone prefab that was disabled is activated wrongly --- UnityProject/Assets/Zenject/Source/Main/DiContainer.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 47e7637dc..6f249b165 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -1205,10 +1205,15 @@ public object InstantiatePrefabForComponentExplicit( Assert.That(componentType.IsInterface() || componentType.DerivesFrom(), "Expected type '{0}' to derive from UnityEngine.Component", componentType.Name()); - var gameObj = (GameObject)GameObject.Instantiate(GetPrefabAsGameObject(prefab)); + GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); + + var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); gameObj.transform.SetParent(GetTransformGroup(gameObjectBindInfo), false); - gameObj.SetActive(true); + + if (prefabAsGameObject.activeSelf) { + gameObj.SetActive(true); + } return InjectGameObjectForComponentExplicit( gameObj, componentType, args); From 45f66b9c9c439346a6052471eb06c7671bd64905 Mon Sep 17 00:00:00 2001 From: Helton Leal Date: Wed, 21 Dec 2016 23:58:07 -0300 Subject: [PATCH 12/62] Replaced tabs for spacing to keep the project standard --- UnityProject/Assets/Zenject/Source/Main/DiContainer.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 6f249b165..10f42dc98 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -1205,15 +1205,15 @@ public object InstantiatePrefabForComponentExplicit( Assert.That(componentType.IsInterface() || componentType.DerivesFrom(), "Expected type '{0}' to derive from UnityEngine.Component", componentType.Name()); - GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); + GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); - var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); + var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); gameObj.transform.SetParent(GetTransformGroup(gameObjectBindInfo), false); - if (prefabAsGameObject.activeSelf) { - gameObj.SetActive(true); - } + if (prefabAsGameObject.activeSelf) { + gameObj.SetActive(true); + } return InjectGameObjectForComponentExplicit( gameObj, componentType, args); From 3723ddf656a94603eccb063351c9bdcc13207098 Mon Sep 17 00:00:00 2001 From: Helton Leal Date: Sat, 14 Jan 2017 15:09:51 -0300 Subject: [PATCH 13/62] Removed unwanted activation --- UnityProject/Assets/Zenject/Source/Main/DiContainer.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 10f42dc98..542e010fe 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -1211,10 +1211,6 @@ public object InstantiatePrefabForComponentExplicit( gameObj.transform.SetParent(GetTransformGroup(gameObjectBindInfo), false); - if (prefabAsGameObject.activeSelf) { - gameObj.SetActive(true); - } - return InjectGameObjectForComponentExplicit( gameObj, componentType, args); } From 3c500029c25ca68bd67100a7c6e1bf212caee7f7 Mon Sep 17 00:00:00 2001 From: James Davies Date: Fri, 2 Dec 2016 21:07:53 +0000 Subject: [PATCH 14/62] Added pooling and a pooled factory. --- .../Factories/Bindings/TestPoolFactoryTo0.cs | 67 +++++++++++++ .../Bindings/TestPoolFactoryTo0.cs.meta | 12 +++ .../Zenject/Source/Factories/IFactory.cs | 54 +++++++++-- .../Zenject/Source/Factories/PoolFactory.cs | 48 +++++++++ .../Source/Factories/PoolFactory.cs.meta | 12 +++ .../Assets/Zenject/Source/Pooling.meta | 9 ++ .../Assets/Zenject/Source/Pooling/IPool.cs | 15 +++ .../Zenject/Source/Pooling/IPool.cs.meta | 12 +++ .../Zenject/Source/Pooling/IPoolItem.cs | 7 ++ .../Zenject/Source/Pooling/IPoolItem.cs.meta | 12 +++ .../Zenject/Source/Pooling/ObjectPool.cs | 97 +++++++++++++++++++ .../Zenject/Source/Pooling/ObjectPool.cs.meta | 12 +++ 12 files changed, 351 insertions(+), 6 deletions(-) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs create mode 100644 UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Pooling.meta create mode 100644 UnityProject/Assets/Zenject/Source/Pooling/IPool.cs create mode 100644 UnityProject/Assets/Zenject/Source/Pooling/IPool.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs create mode 100644 UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs create mode 100644 UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs new file mode 100644 index 000000000..49f32f24e --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestPoolFactoryTo0 : ZenjectUnitTestFixture + { + [Test] + public void TestSelf() + { + Assert.IsNotNull(new Foo.Factory().Get()); + } + + [Test] + public void TestPool() + { + Foo.Factory factory = new Foo.Factory(); + + List items = new List(); + + for (int count = 4; count > 0; count--) + { + items.Add(factory.Get()); + + Assert.That(factory.TotalActive == items.Count); + Assert.That(factory.TotalInactive == count - 1); + Assert.That(factory.PoolSize == 4); + } + + items.Add(factory.Get()); + + Assert.That(factory.TotalActive == 5); + Assert.That(factory.TotalInactive == 0); + Assert.That(factory.PoolSize == 5); + + + for (int i = 0; i < items.Count; i++) + { + factory.Return(items[i]); + + Assert.That(factory.TotalActive == items.Count - (i + 1)); + Assert.That(factory.TotalInactive == i + 1); + Assert.That(factory.PoolSize == 5); + } + } + + private class Foo : IPoolItem + { + public Foo() + { + + } + + public void Reset() + { + + } + + public class Factory : PoolFactory + { + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs.meta new file mode 100644 index 000000000..ca8a3d668 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a9b399b2b4f8a184eb6b6c47cd77009e +timeCreated: 1461708048 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/IFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/IFactory.cs index 2d431910c..b56c300d6 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/IFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/IFactory.cs @@ -4,34 +4,76 @@ public interface IFactory { } - public interface IFactory : IFactory + public interface IFactory : IFactory { TValue Create(); } - public interface IFactory : IFactory + public interface IFactory : IFactory { TValue Create(TParam1 param); } - public interface IFactory : IFactory + public interface IFactory : IFactory { TValue Create(TParam1 param1, TParam2 param2); } - public interface IFactory : IFactory + public interface IFactory : IFactory { TValue Create(TParam1 param1, TParam2 param2, TParam3 param3); } - public interface IFactory : IFactory + public interface IFactory : IFactory { TValue Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4); } - public interface IFactory : IFactory + public interface IFactory : IFactory { TValue Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5); } + + public interface IPoolFactory : IFactory + where TValue : IPoolItem, new() + { + TValue Get(); + void Return(TValue item); + } + + public interface IPoolFactory : IFactory + where TValue : IPoolItem, new() + { + TValue Create(TParam1 param); + void Return(TValue item); + } + + public interface IPoolFactory : IFactory + where TValue : IPoolItem, new() + { + TValue Create(TParam1 param1, TParam2 param2); + void Return(TValue item); + } + + public interface IPoolFactory : IFactory + where TValue : IPoolItem, new() + { + TValue Create(TParam1 param1, TParam2 param2, TParam3 param3); + void Return(TValue item); + } + + public interface IPoolFactory : IFactory + where TValue : IPoolItem, new() + { + TValue Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4); + void Return(TValue item); + } + + public interface IPoolFactory : IFactory + where TValue : IPoolItem, new() + { + TValue Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5); + void Return(TValue item); + } } diff --git a/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs new file mode 100644 index 000000000..5687ff20c --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; + +namespace Zenject +{ + public abstract class DynamicPoolFactory : DynamicFactory + where TValue : IPoolItem, new() + { + public int PoolSize { get { return Pool.PoolSize; } } + public int TotalActive { get { return Pool.TotalActive; } } + public int TotalInactive { get { return Pool.TotalInactive; } } + + protected ObjectPool Pool { get; set; } + } + + public class PoolFactory : DynamicPoolFactory, IPoolFactory + where TValue : IPoolItem, new() + { + // If you were hoping to override this method, use BindFactory<>.ToFactory instead + public TValue Get() + { + if (Pool == null) + { + Pool = new ObjectPool(4, CreateInternal); + } + + return Pool.Get(); + } + + public void Return(TValue item) + { + Pool.Return(item); + } + + private TValue CreateInternal() + { + return CreateInternal(new List()); + } + + protected sealed override IEnumerable ParamTypes + { + get + { + yield break; + } + } + } +} \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs.meta new file mode 100644 index 000000000..c5e3ed392 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d843594067e131d4ab956888139fbd1f +timeCreated: 1480706812 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Pooling.meta b/UnityProject/Assets/Zenject/Source/Pooling.meta new file mode 100644 index 000000000..b4940fe09 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Pooling.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f31b8835604036d42ba13a44763d70d6 +folderAsset: yes +timeCreated: 1480708268 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs b/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs new file mode 100644 index 000000000..5dd21179d --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs @@ -0,0 +1,15 @@ +using System; + +namespace Zenject +{ + public interface IPool : IDisposable + where T : IPoolItem + { + int PoolSize { get; } + int TotalActive { get; } + int TotalInactive { get; } + + T Get(); + void Return(T item); + } +} \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs.meta b/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs.meta new file mode 100644 index 000000000..91f6d42df --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e7c590cda0196ac4f97bc86ab73bb3a5 +timeCreated: 1480708500 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs b/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs new file mode 100644 index 000000000..8d32d85fc --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs @@ -0,0 +1,7 @@ +namespace Zenject +{ + public interface IPoolItem + { + void Reset(); + } +} \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs.meta b/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs.meta new file mode 100644 index 000000000..904392260 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 67c2c6a336587444da40891aa0123ecc +timeCreated: 1480706967 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs b/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs new file mode 100644 index 000000000..8a1c585f4 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; + +namespace Zenject +{ + public class ObjectPool : IPool + where T : IPoolItem, new() + { + private Stack m_unusedItems; + private Func m_createItemAction; + + public int PoolSize { get; private set; } + public int TotalActive { get { return PoolSize - TotalInactive; } } + public int TotalInactive { get { return m_unusedItems.Count; } } + + public ObjectPool() : this(4) { } + + public ObjectPool(int initalialSize) + { + m_createItemAction = CreateNew; + + InitialisePool(initalialSize); + } + + public ObjectPool(int initalialSize, Func createItemAction) + { + m_createItemAction = createItemAction; + + InitialisePool(initalialSize); + } + + public void Dispose() + { + // ToDo: Should we mark IPoolItem as IDisposable? Or should we check if T is IDisposable and call dispose? + + m_unusedItems.Clear(); + m_unusedItems = null; + } + + public T Get() + { + T item; + + if (m_unusedItems.Count == 0) + { + PoolSize++; + + item = new T(); + } + else + { + item = m_unusedItems.Pop(); + } + + // Reset the item when it's requested. This is like Initialise. + // ToDo: Should this be changed to Initialise? + item.Reset(); + + return item; + } + + public void Return(T item) + { + // Check to make sure someone hasn't released twice. + if (m_unusedItems.Count > 0 && ReferenceEquals(m_unusedItems.Peek(), item)) + { + throw new InvalidPoolReleaseException(); + } + + m_unusedItems.Push(item); + } + + private void InitialisePool(int initalialSize) + { + m_unusedItems = new Stack(initalialSize); + PoolSize = initalialSize; + + for (int i = 0; i < initalialSize; i++) + { + m_unusedItems.Push(m_createItemAction.Invoke()); + } + } + + private T CreateNew() + { + return new T(); + } + } + + public class InvalidPoolReleaseException : Exception + { + public InvalidPoolReleaseException() + : base("Can not release item that's already released.") + { + } + } +} \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs.meta b/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs.meta new file mode 100644 index 000000000..9e26aaed2 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 77782f76bfdd943488f3f475944806a6 +timeCreated: 1480708272 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From be4dfc215cc907872df66ca28ef930810006932e Mon Sep 17 00:00:00 2001 From: James Davies Date: Sat, 7 Jan 2017 20:32:38 +0000 Subject: [PATCH 15/62] Fixed issue with pooling creating new T rather than using Zenject. --- UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs b/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs index 8a1c585f4..ac83e737c 100644 --- a/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs +++ b/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs @@ -45,7 +45,7 @@ public T Get() { PoolSize++; - item = new T(); + item = m_createItemAction.Invoke(); } else { From b7304e14334fe7ad70070e0f149ca48f3bda7e31 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 15 Jan 2017 22:54:17 -0400 Subject: [PATCH 16/62] - Refactored a bunch of things in memory pooling re issue #189 - Refactored the way factories work in general a bit to be cleaner - Added fluent interface for memory pools to specify initial size and the expand algorithm to use - Added support for up to 5 parameters to PooledFactory - Moved IGuiRenderable interface to the non-editor directory so that people can optionally use it as an alternative to MonoBehaviour.OnGui - Updated sample projects to use memory pools --- .../Scripts/Asteroid/Asteroid.cs | 22 +- .../Scripts/Asteroid/AsteroidManager.cs | 4 +- .../Editor/Tests/TestAsteroidManager.cs | 5 +- .../Scripts/Installers/GameInstaller.cs | 3 +- .../Media/Prefabs/Explosion07.prefab | 3997 +++++++++++++---- .../Scripts/Enemy/EnemyHealthWatcher.cs | 2 +- .../Scripts/Enemy/States/EnemyStateAttack.cs | 2 +- .../Scripts/Installers/GameInstaller.cs | 4 +- .../Scripts/Misc/Bullet.cs | 24 +- .../Scripts/Misc/Explosion.cs | 32 +- .../Scripts/Player/PlayerHealthWatcher.cs | 2 +- .../Scripts/Player/PlayerShootHandler.cs | 2 +- .../SampleGame2 (Advanced)/SpaceFighter.unity | 2 +- .../Factories/Bindings/TestPoolFactoryTo0.cs | 67 - .../Bindings/TestPooledFactoryTo0.cs | 211 + ...0.cs.meta => TestPooledFactoryTo0.cs.meta} | 6 +- .../Bindings/TestPooledFactoryTo1.cs | 100 + .../Bindings/TestPooledFactoryTo1.cs.meta} | 6 +- .../Binding/BindInfo/FactoryBindInfo.cs | 22 + .../Binding/BindInfo/FactoryBindInfo.cs.meta | 12 + .../Binding/BindInfo/PooledFactoryBindInfo.cs | 29 + .../BindInfo/PooledFactoryBindInfo.cs.meta | 12 + .../Factory/DynamicFactoryBindingFinalizer.cs | 14 +- .../FactoryFromBinder/FactoryFromBinder0.cs | 28 +- .../FactoryFromBinder/FactoryFromBinder1.cs | 16 +- .../FactoryFromBinder/FactoryFromBinder2.cs | 15 +- .../FactoryFromBinder/FactoryFromBinder3.cs | 15 +- .../FactoryFromBinder/FactoryFromBinder4.cs | 15 +- .../FactoryFromBinder/FactoryFromBinder5.cs | 20 +- .../FactorySubContainerBinder0.cs | 17 +- .../FactorySubContainerBinder1.cs | 9 +- .../FactorySubContainerBinder2.cs | 9 +- .../FactorySubContainerBinder3.cs | 9 +- .../FactorySubContainerBinder4.cs | 9 +- .../FactorySubContainerBinder5.cs | 9 +- .../FactorySubContainerBinderBase.cs | 40 +- .../FactorySubContainerBinderWithParams.cs | 13 +- .../Binders/Factory/FactoryFromBinderBase.cs | 77 +- .../FactoryToChoiceBinder0.cs | 24 +- .../FactoryToChoiceBinder1.cs | 24 +- .../FactoryToChoiceBinder2.cs | 24 +- .../FactoryToChoiceBinder3.cs | 24 +- .../FactoryToChoiceBinder4.cs | 24 +- .../FactoryToChoiceBinder5.cs | 27 +- .../Factory/FactoryToChoiceIdBinder.meta} | 5 +- .../FactoryToChoiceIdBinder0.cs | 23 + .../FactoryToChoiceIdBinder0.cs.meta | 12 + .../FactoryToChoiceIdBinder1.cs | 21 + .../FactoryToChoiceIdBinder1.cs.meta | 12 + .../FactoryToChoiceIdBinder2.cs | 22 + .../FactoryToChoiceIdBinder2.cs.meta | 12 + .../FactoryToChoiceIdBinder3.cs | 23 + .../FactoryToChoiceIdBinder3.cs.meta | 12 + .../FactoryToChoiceIdBinder4.cs | 21 + .../FactoryToChoiceIdBinder4.cs.meta | 12 + .../FactoryToChoiceIdBinder5.cs | 22 + .../FactoryToChoiceIdBinder5.cs.meta | 12 + .../Binding/Binders/Factory/Pooling.meta} | 5 +- .../Pooling/PooledFactoryBindingFinalizer.cs | 40 + .../PooledFactoryBindingFinalizer.cs.meta | 12 + .../Pooling/PooledFactoryExpandBinder.cs | 36 + .../Pooling/PooledFactoryExpandBinder.cs.meta | 12 + .../Pooling/PooledFactoryInitialSizeBinder.cs | 29 + .../PooledFactoryInitialSizeBinder.cs.meta | 12 + .../Editor/EditorWindow/IGuiRenderable.cs | 9 - .../Source/Factories/DynamicFactory.cs | 2 +- .../Zenject/Source/Factories/IFactory.cs | 42 - .../Zenject/Source/Factories/PoolFactory.cs | 48 - .../Source/{ => Factories}/Pooling.meta | 6 +- .../Factories/Pooling/DynamicPooledFactory.cs | 191 + .../Pooling/DynamicPooledFactory.cs.meta | 12 + .../Source/Factories/Pooling/IPoolable.cs | 37 + .../Factories/Pooling/IPoolable.cs.meta | 12 + .../Factories/Pooling/IPooledFactory.cs | 46 + .../Factories/Pooling/IPooledFactory.cs.meta | 12 + .../Source/Factories/Pooling/PooledFactory.cs | 149 + .../Factories/Pooling/PooledFactory.cs.meta | 12 + .../Source/Install/Contexts/ProjectContext.cs | 6 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 169 +- .../Assets/Zenject/Source/Pooling/IPool.cs | 15 - .../Zenject/Source/Pooling/IPool.cs.meta | 12 - .../Zenject/Source/Pooling/IPoolItem.cs | 7 - .../Zenject/Source/Pooling/IPoolItem.cs.meta | 12 - .../Zenject/Source/Pooling/ObjectPool.cs | 97 - .../Zenject/Source/Pooling/ObjectPool.cs.meta | 12 - .../GuiRenderableManager.cs | 6 +- .../GuiRenderableManager.cs.meta | 6 +- .../Zenject/Source/Runtime/GuiRenderer.cs | 25 + .../Source/Runtime/GuiRenderer.cs.meta | 12 + .../Zenject/Source/Usage/IGuiRenderable.cs | 14 + .../IGuiRenderable.cs.meta | 6 +- .../Source/Util/PoolableMonoBehaviour.meta | 9 + 92 files changed, 4789 insertions(+), 1580 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestPoolFactoryTo0.cs.meta => TestPooledFactoryTo0.cs.meta} (69%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs rename UnityProject/Assets/Zenject/{Source/Factories/PoolFactory.cs.meta => OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs.meta} (69%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/BindInfo/FactoryBindInfo.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/BindInfo/FactoryBindInfo.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs.meta rename UnityProject/Assets/Zenject/Source/{Zenject.csproj.user.meta => Binding/Binders/Factory/FactoryToChoiceIdBinder.meta} (58%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder0.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder0.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder1.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder1.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder2.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder2.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder3.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder3.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder4.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder4.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder5.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder5.cs.meta rename UnityProject/Assets/Zenject/{OptionalExtras/UnitTests/Editor/Zenject-tests.csproj.user.meta => Source/Binding/Binders/Factory/Pooling.meta} (58%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Editor/EditorWindow/IGuiRenderable.cs delete mode 100644 UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs rename UnityProject/Assets/Zenject/Source/{ => Factories}/Pooling.meta (57%) create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Pooling/IPool.cs delete mode 100644 UnityProject/Assets/Zenject/Source/Pooling/IPool.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs delete mode 100644 UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs delete mode 100644 UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs.meta rename UnityProject/Assets/Zenject/Source/{Editor/EditorWindow => Runtime}/GuiRenderableManager.cs (90%) rename UnityProject/Assets/Zenject/Source/{Editor/EditorWindow => Runtime}/GuiRenderableManager.cs.meta (69%) create mode 100644 UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs create mode 100644 UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs rename UnityProject/Assets/Zenject/Source/{Editor/EditorWindow => Usage}/IGuiRenderable.cs.meta (69%) create mode 100644 UnityProject/Assets/Zenject/Source/Util/PoolableMonoBehaviour.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/Asteroid.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/Asteroid.cs index 23d4965e1..dee1a5f95 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/Asteroid.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/Asteroid.cs @@ -6,9 +6,8 @@ namespace Zenject.Asteroids { - public class Asteroid : MonoBehaviour + public class Asteroid : MonoBehaviour, IPoolable { - bool _hasDisposed; LevelHelper _level; Rigidbody _rigidBody; Settings _settings; @@ -25,6 +24,16 @@ public void Construct(LevelHelper level, Settings settings) _rigidBody = GetComponent(); } + public void OnSpawned() + { + gameObject.SetActive(true); + } + + public void OnDespawned() + { + gameObject.SetActive(false); + } + public Vector3 Position { get @@ -95,13 +104,6 @@ public void Tick() CheckForTeleport(); } - public void Dispose() - { - Assert.That(!_hasDisposed); - _hasDisposed = true; - GameObject.Destroy(gameObject); - } - void CheckForTeleport() { if (Position.x > _level.Right + Scale && IsMovingInDirection(Vector3.right)) @@ -136,7 +138,7 @@ public class Settings public float maxSpeed; } - public class Factory : Factory + public class Factory : PooledFactory { } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/AsteroidManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/AsteroidManager.cs index a0679636b..ca97b64f0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/AsteroidManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/AsteroidManager.cs @@ -104,7 +104,7 @@ void ResetAll() { foreach (var asteroid in _asteroids) { - asteroid.Dispose(); + _asteroidFactory.Despawn(asteroid); } _asteroids.Clear(); @@ -146,7 +146,7 @@ public void Tick() public void SpawnNext() { - var asteroid = _asteroidFactory.Create(); + var asteroid = _asteroidFactory.Spawn(); var attributes = _cachedAttributes.Dequeue(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs index 9e21afec9..9a4540fef 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -19,7 +20,7 @@ public void CommonInstall() GameSettingsInstaller.InstallFromResource(Container); var gameSettings = Container.Resolve(); Container.Bind().AsSingle(); - Container.BindFactory().FromPrefab(gameSettings.AsteroidPrefab); + Container.BindPooledFactory().FromPrefab(gameSettings.AsteroidPrefab); Container.Bind().WithId("Main").FromGameObject(); Container.Bind().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs index e3817588a..720ae723a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs @@ -60,7 +60,8 @@ void InstallAsteroids() // Here, we're defining a generic factory to create asteroid objects using the given prefab // So any classes that want to create new asteroid objects can simply include an injected field // or constructor parameter of type Asteroid.Factory, then call Create() on that - Container.BindFactory() + Container.BindPooledFactory() + .WithInitialSize(25).ExpandByDoubling() .FromPrefab(_settings.AsteroidPrefab) // We can also tell Zenject what to name the new gameobject here .WithGameObjectName("Asteroid") diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab index 56ed297bd..6fd002923 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab @@ -5,11 +5,11 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400000} - - 198: {fileID: 19800000} - - 199: {fileID: 19900000} + - component: {fileID: 400000} + - component: {fileID: 19800000} + - component: {fileID: 19900000} m_Layer: 0 m_Name: Flame1 m_TagString: Untagged @@ -22,12 +22,12 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 400002} - - 198: {fileID: 19800002} - - 199: {fileID: 19900002} - - 114: {fileID: 11436508} + - component: {fileID: 400002} + - component: {fileID: 19800002} + - component: {fileID: 19900002} + - component: {fileID: 11436508} m_Layer: 0 m_Name: Explosion07 m_TagString: Untagged @@ -47,6 +47,7 @@ Transform: m_Children: [] m_Father: {fileID: 400002} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &400002 Transform: m_ObjectHideFlags: 1 @@ -60,6 +61,7 @@ Transform: - {fileID: 400000} m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &11436508 MonoBehaviour: m_ObjectHideFlags: 1 @@ -72,6 +74,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: _lifeTime: 1 + _particleSystem: {fileID: 19800002} _sound: {fileID: 8300000, guid: 0391a139af5d8a346b18c06b476f3ffe, type: 3} _soundVolume: 0.4 --- !u!198 &19800000 @@ -80,19 +83,26 @@ ParticleSystem: m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 100000} - serializedVersion: 2 + serializedVersion: 5 lengthInSec: 1.5 + speed: 1 + looping: 0 + prewarm: 0 + playOnAwake: 1 + autoRandomSeed: 1 startDelay: scalar: 0 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -103,12 +113,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -117,27 +129,26 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - speed: 1 - randomSeed: 0 - looping: 0 - prewarm: 0 - playOnAwake: 1 - moveWithTransform: 0 + moveWithTransform: 1 + moveWithCustomTransform: {fileID: 0} scalingMode: 2 + randomSeed: 0 InitialModule: - serializedVersion: 2 + serializedVersion: 3 enabled: 1 startLifetime: scalar: 1.25 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -148,12 +159,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -167,12 +180,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -183,12 +198,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -198,6 +215,7 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 startColor: + serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -239,6 +257,7 @@ ParticleSystem: atime5: 0 atime6: 0 atime7: 0 + m_Mode: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 minGradient: @@ -282,26 +301,103 @@ ParticleSystem: atime5: 0 atime6: 0 atime7: 0 + m_Mode: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} + minMaxState: 0 + startSize: + scalar: 1 + maxCurve: serializedVersion: 2 - rgba: 4294967295 - maxColor: + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: serializedVersion: 2 - rgba: 4294967295 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 minMaxState: 0 - startSize: + startSizeY: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + startSizeZ: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -312,12 +408,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -331,12 +429,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -347,12 +447,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -366,12 +468,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -382,12 +486,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -401,12 +507,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -417,12 +525,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -432,11 +542,50 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 randomizeRotationDirection: 0 - gravityModifier: 0 maxNumParticles: 1000 + size3D: 0 rotation3D: 0 + gravityModifier: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 ShapeModule: - serializedVersion: 2 + serializedVersion: 3 enabled: 1 type: 0 radius: 0.01 @@ -452,24 +601,67 @@ ParticleSystem: m_SkinnedMeshRenderer: {fileID: 0} m_MeshMaterialIndex: 0 m_MeshNormalOffset: 0 + m_MeshScale: 1 m_UseMeshMaterialIndex: 0 m_UseMeshColors: 1 - randomDirection: 1 + alignToDirection: 0 + randomDirectionAmount: 1 + sphericalDirectionAmount: 0 EmissionModule: enabled: 1 - serializedVersion: 2 - m_Type: 0 - rate: + serializedVersion: 3 + rateOverTime: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + rateOverDistance: scalar: 0 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -480,12 +672,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -514,12 +708,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0.19377163 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 2 outSlope: 2 @@ -530,12 +726,92 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + y: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + z: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -544,6 +820,7 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 + separateAxes: 0 RotationModule: enabled: 1 x: @@ -551,12 +828,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -567,12 +846,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -586,12 +867,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -602,12 +885,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -621,7 +906,8 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0.41855192 inSlope: 0 outSlope: 0 @@ -632,7 +918,8 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: -0.41628957 inSlope: 0 outSlope: 0 @@ -645,6 +932,7 @@ ParticleSystem: ColorModule: enabled: 1 gradient: + serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -686,6 +974,7 @@ ParticleSystem: atime5: 0 atime6: 0 atime7: 0 + m_Mode: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 3 minGradient: @@ -729,28 +1018,27 @@ ParticleSystem: atime5: 0 atime6: 0 atime7: 0 + m_Mode: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: - serializedVersion: 2 - rgba: 4294967295 - maxColor: - serializedVersion: 2 - rgba: 4294967295 + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} minMaxState: 1 UVModule: enabled: 0 frameOverTime: - scalar: 1 + scalar: 0.9999 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 1 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 1 outSlope: 0 @@ -761,12 +1049,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 1 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 1 outSlope: 0 @@ -775,11 +1065,53 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 + startFrame: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 tilesX: 1 tilesY: 1 animationType: 0 rowIndex: 0 cycles: 1 + uvChannelMask: -1 + flipU: 0 + flipV: 0 randomRow: 1 VelocityModule: enabled: 0 @@ -788,12 +1120,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -804,12 +1138,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -823,12 +1159,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -839,12 +1177,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -858,12 +1198,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -874,12 +1216,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -897,12 +1241,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -913,12 +1259,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -934,7 +1282,8 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: -0.5089462 inSlope: 0 outSlope: 0 @@ -945,7 +1294,8 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0.50497 inSlope: 0 outSlope: 0 @@ -959,7 +1309,8 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: -0.5089462 inSlope: 0 outSlope: 0 @@ -970,7 +1321,8 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0.5009939 inSlope: 0 outSlope: 0 @@ -984,7 +1336,8 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: -0.5129223 inSlope: 0 outSlope: 0 @@ -995,7 +1348,8 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0.5089462 inSlope: 0 outSlope: 0 @@ -1016,12 +1370,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1032,12 +1388,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1051,12 +1409,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1067,12 +1427,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1086,12 +1448,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1102,12 +1466,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1121,12 +1487,14 @@ ParticleSystem: maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0.3979239 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 2 outSlope: 2 @@ -1137,12 +1505,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1154,19 +1524,21 @@ ParticleSystem: separateAxis: 0 inWorldSpace: 0 dampen: 1 - SizeBySpeedModule: + NoiseModule: enabled: 0 - curve: + strength: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1177,12 +1549,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1190,21 +1564,20 @@ ParticleSystem: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 1 - range: {x: 0, y: 1} - RotationBySpeedModule: - enabled: 0 - x: + minMaxState: 0 + strengthY: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1215,12 +1588,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1229,17 +1604,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - y: + strengthZ: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1250,12 +1627,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1264,17 +1643,26 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - curve: - scalar: 0.7853981 + separateAxes: 0 + frequency: 0.5 + damping: 1 + octaves: 1 + octaveMultiplier: 0.5 + octaveScale: 2 + quality: 2 + scrollSpeed: + scalar: 0 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1285,12 +1673,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1299,127 +1689,1661 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - separateAxes: 0 - range: {x: 0, y: 1} - ColorBySpeedModule: - enabled: 0 - gradient: - maxGradient: - key0: - serializedVersion: 2 - rgba: 4294967295 - key1: - serializedVersion: 2 - rgba: 4294967295 - key2: - serializedVersion: 2 - rgba: 0 - key3: - serializedVersion: 2 - rgba: 0 - key4: - serializedVersion: 2 - rgba: 0 - key5: - serializedVersion: 2 - rgba: 0 - key6: - serializedVersion: 2 - rgba: 0 - key7: - serializedVersion: 2 - rgba: 0 - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minGradient: - key0: - serializedVersion: 2 - rgba: 4294967295 - key1: - serializedVersion: 2 - rgba: 4294967295 - key2: - serializedVersion: 2 - rgba: 0 - key3: - serializedVersion: 2 - rgba: 0 - key4: - serializedVersion: 2 - rgba: 0 - key5: - serializedVersion: 2 - rgba: 0 - key6: - serializedVersion: 2 - rgba: 0 - key7: - serializedVersion: 2 - rgba: 0 - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minColor: + remap: + scalar: 1 + maxCurve: serializedVersion: 2 - rgba: 4294967295 - maxColor: + m_Curve: + - serializedVersion: 2 + time: 0 + value: -1 + inSlope: 0 + outSlope: 2 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 2 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: serializedVersion: 2 - rgba: 4294967295 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 minMaxState: 1 - range: {x: 0, y: 1} - CollisionModule: + remapY: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: -1 + inSlope: 0 + outSlope: 2 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 2 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + remapZ: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: -1 + inSlope: 0 + outSlope: 2 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 2 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + remapEnabled: 0 + SizeBySpeedModule: enabled: 0 - serializedVersion: 2 - type: 0 - collisionMode: 0 - plane0: {fileID: 0} - plane1: {fileID: 0} - plane2: {fileID: 0} - plane3: {fileID: 0} - plane4: {fileID: 0} - plane5: {fileID: 0} - m_Dampen: - scalar: 0 + curve: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + y: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + z: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + range: {x: 0, y: 1} + separateAxes: 0 + RotationBySpeedModule: + enabled: 0 + x: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + y: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + curve: + scalar: 0.7853981 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + separateAxes: 0 + range: {x: 0, y: 1} + ColorBySpeedModule: + enabled: 0 + gradient: + serializedVersion: 2 + maxGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} + minMaxState: 1 + range: {x: 0, y: 1} + CollisionModule: + enabled: 0 + serializedVersion: 3 + type: 0 + collisionMode: 0 + plane0: {fileID: 0} + plane1: {fileID: 0} + plane2: {fileID: 0} + plane3: {fileID: 0} + plane4: {fileID: 0} + plane5: {fileID: 0} + m_Dampen: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + m_Bounce: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + m_EnergyLossOnCollision: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + minKillSpeed: 0 + maxKillSpeed: 10000 + radiusScale: 1 + collidesWith: + serializedVersion: 2 + m_Bits: 4294967295 + maxCollisionShapes: 256 + quality: 0 + voxelSize: 0.5 + collisionMessages: 0 + collidesWithDynamic: 1 + interiorCollisions: 1 + TriggerModule: + enabled: 0 + collisionShape0: {fileID: 0} + collisionShape1: {fileID: 0} + collisionShape2: {fileID: 0} + collisionShape3: {fileID: 0} + collisionShape4: {fileID: 0} + collisionShape5: {fileID: 0} + inside: 1 + outside: 0 + enter: 0 + exit: 0 + radiusScale: 1 + SubModule: + serializedVersion: 2 + enabled: 0 + subEmitters: + - emitter: {fileID: 0} + type: 0 + properties: 0 + LightsModule: + enabled: 0 + ratio: 0 + light: {fileID: 0} + randomDistribution: 1 + color: 1 + range: 1 + intensity: 1 + rangeCurve: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + intensityCurve: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + maxLights: 20 + TrailModule: + enabled: 0 + ratio: 1 + lifetime: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + minVertexDistance: 0.2 + textureMode: 0 + worldSpace: 0 + dieWithParticles: 1 + sizeAffectsWidth: 1 + sizeAffectsLifetime: 0 + inheritParticleColor: 1 + colorOverLifetime: + serializedVersion: 2 + maxGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} + minMaxState: 0 + widthOverTrail: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + colorOverTrail: + serializedVersion: 2 + maxGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} + minMaxState: 0 +--- !u!198 &19800002 +ParticleSystem: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + serializedVersion: 5 + lengthInSec: 1.5 + speed: 1 + looping: 0 + prewarm: 0 + playOnAwake: 1 + autoRandomSeed: 1 + startDelay: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + moveWithTransform: 1 + moveWithCustomTransform: {fileID: 0} + scalingMode: 2 + randomSeed: 0 + InitialModule: + serializedVersion: 3 + enabled: 1 + startLifetime: + scalar: 0.3 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + startSpeed: + scalar: 25 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + startColor: + serializedVersion: 2 + maxGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} + minMaxState: 0 + startSize: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + startSizeY: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + startSizeZ: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + startRotationX: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + startRotationY: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + startRotation: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + randomizeRotationDirection: 0 + maxNumParticles: 1000 + size3D: 0 + rotation3D: 0 + gravityModifier: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + ShapeModule: + serializedVersion: 3 + enabled: 1 + type: 1 + radius: 0.01 + angle: 25 + length: 5 + boxX: 1 + boxY: 1 + boxZ: 1 + arc: 360 + placementMode: 0 + m_Mesh: {fileID: 0} + m_MeshRenderer: {fileID: 0} + m_SkinnedMeshRenderer: {fileID: 0} + m_MeshMaterialIndex: 0 + m_MeshNormalOffset: 0 + m_MeshScale: 1 + m_UseMeshMaterialIndex: 0 + m_UseMeshColors: 1 + alignToDirection: 0 + randomDirectionAmount: 1 + sphericalDirectionAmount: 0 + EmissionModule: + enabled: 1 + serializedVersion: 3 + rateOverTime: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + rateOverDistance: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + cnt0: 50 + cnt1: 30 + cnt2: 30 + cnt3: 30 + cntmax0: 50 + cntmax1: 30 + cntmax2: 30 + cntmax3: 30 + time0: 0 + time1: 0 + time2: 0 + time3: 0 + m_BurstCount: 1 + SizeModule: + enabled: 1 + curve: + scalar: 1 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0.49886876 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + y: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1430,12 +3354,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1443,18 +3369,20 @@ ParticleSystem: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 0 - m_Bounce: + minMaxState: 1 + z: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1465,12 +3393,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1478,18 +3408,23 @@ ParticleSystem: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 0 - m_EnergyLossOnCollision: - scalar: 0 + minMaxState: 1 + separateAxes: 0 + RotationModule: + enabled: 0 + x: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1500,12 +3435,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1514,89 +3451,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - minKillSpeed: 0 - radiusScale: 1 - collidesWith: - serializedVersion: 2 - m_Bits: 4294967295 - maxCollisionShapes: 256 - quality: 0 - voxelSize: 0.5 - collisionMessages: 0 - collidesWithDynamic: 1 - interiorCollisions: 1 - SubModule: - enabled: 0 - subEmitterBirth: {fileID: 0} - subEmitterBirth1: {fileID: 0} - subEmitterCollision: {fileID: 0} - subEmitterCollision1: {fileID: 0} - subEmitterDeath: {fileID: 0} - subEmitterDeath1: {fileID: 0} ---- !u!198 &19800002 -ParticleSystem: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100002} - serializedVersion: 2 - lengthInSec: 1.5 - startDelay: - scalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - speed: 1 - randomSeed: 0 - looping: 0 - prewarm: 0 - playOnAwake: 1 - moveWithTransform: 0 - scalingMode: 2 - InitialModule: - serializedVersion: 2 - enabled: 1 - startLifetime: - scalar: 0.3 + y: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1607,12 +3474,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1621,17 +3490,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - startSpeed: - scalar: 25 + curve: + scalar: 0.7853981 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1642,12 +3513,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1656,41 +3529,45 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - startColor: + separateAxes: 0 + ColorModule: + enabled: 1 + gradient: + serializedVersion: 2 maxGradient: key0: serializedVersion: 2 rgba: 4294967295 key1: serializedVersion: 2 - rgba: 4294967295 + rgba: 36607 key2: serializedVersion: 2 - rgba: 0 + rgba: 195 key3: serializedVersion: 2 - rgba: 0 + rgba: 195 key4: serializedVersion: 2 - rgba: 0 + rgba: 195 key5: serializedVersion: 2 - rgba: 0 + rgba: 195 key6: serializedVersion: 2 - rgba: 0 + rgba: 255 key7: serializedVersion: 2 - rgba: 0 - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 + rgba: 255 + ctime0: 7132 + ctime1: 36815 + ctime2: 52428 + ctime3: 52428 + ctime4: 52428 + ctime5: 52428 + ctime6: 65535 + ctime7: 65535 + atime0: 41827 atime1: 65535 atime2: 0 atime3: 0 @@ -1698,7 +3575,8 @@ ParticleSystem: atime5: 0 atime6: 0 atime7: 0 - m_NumColorKeys: 2 + m_Mode: 0 + m_NumColorKeys: 3 m_NumAlphaKeys: 2 minGradient: key0: @@ -1741,26 +3619,194 @@ ParticleSystem: atime5: 0 atime6: 0 atime7: 0 + m_Mode: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} + minMaxState: 1 + UVModule: + enabled: 0 + frameOverTime: + scalar: 0.9999 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 1 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 1 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 1 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 1 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 1 + startFrame: + scalar: 0 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + tilesX: 1 + tilesY: 1 + animationType: 0 + rowIndex: 0 + cycles: 1 + uvChannelMask: -1 + flipU: 0 + flipV: 0 + randomRow: 1 + VelocityModule: + enabled: 0 + x: + scalar: 5 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: serializedVersion: 2 - rgba: 4294967295 - maxColor: + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + y: + scalar: 5 + maxCurve: serializedVersion: 2 - rgba: 4294967295 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 minMaxState: 0 - startSize: - scalar: 1 + z: + scalar: 5 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1771,12 +3817,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1785,17 +3833,23 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - startRotationX: + inWorldSpace: 0 + InheritVelocityModule: + enabled: 0 + m_Mode: 0 + m_Curve: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1806,12 +3860,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1820,17 +3876,109 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - startRotationY: + ForceModule: + enabled: 1 + x: + scalar: 0.5 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: -1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 3 + y: + scalar: 0.5 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: -1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 3 + z: + scalar: 0.5 + maxCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 2 + time: 0 + value: -1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 3 + inWorldSpace: 0 + randomizePerFrame: 1 + ExternalForcesModule: + enabled: 0 + multiplier: 1 + ClampVelocityModule: + enabled: 0 + x: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1841,12 +3989,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1855,17 +4005,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - startRotation: - scalar: 0 + y: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1876,12 +4028,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1890,45 +4044,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - randomizeRotationDirection: 0 - gravityModifier: 0 - maxNumParticles: 1000 - rotation3D: 0 - ShapeModule: - serializedVersion: 2 - enabled: 1 - type: 1 - radius: 0.01 - angle: 25 - length: 5 - boxX: 1 - boxY: 1 - boxZ: 1 - arc: 360 - placementMode: 0 - m_Mesh: {fileID: 0} - m_MeshRenderer: {fileID: 0} - m_SkinnedMeshRenderer: {fileID: 0} - m_MeshMaterialIndex: 0 - m_MeshNormalOffset: 0 - m_UseMeshMaterialIndex: 0 - m_UseMeshColors: 1 - randomDirection: 1 - EmissionModule: - enabled: 1 - serializedVersion: 2 - m_Type: 0 - rate: - scalar: 0 + z: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -1939,12 +4067,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -1953,33 +4083,20 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - cnt0: 50 - cnt1: 30 - cnt2: 30 - cnt3: 30 - cntmax0: 50 - cntmax1: 30 - cntmax2: 30 - cntmax3: 30 - time0: 0 - time1: 0 - time2: 0 - time3: 0 - m_BurstCount: 1 - SizeModule: - enabled: 1 - curve: + magnitude: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 - value: 0.49886876 + - serializedVersion: 2 + time: 0 + value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 - value: 0 + - serializedVersion: 2 + time: 1 + value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 @@ -1989,12 +4106,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2002,20 +4121,25 @@ ParticleSystem: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 1 - RotationModule: + minMaxState: 0 + separateAxis: 0 + inWorldSpace: 0 + dampen: 1 + NoiseModule: enabled: 0 - x: + strength: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2026,12 +4150,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2040,17 +4166,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - y: + strengthY: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2061,12 +4189,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2075,17 +4205,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - curve: - scalar: 0.7853981 + strengthZ: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2096,12 +4228,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2111,117 +4245,66 @@ ParticleSystem: m_RotationOrder: 4 minMaxState: 0 separateAxes: 0 - ColorModule: - enabled: 1 - gradient: - maxGradient: - key0: - serializedVersion: 2 - rgba: 4294967295 - key1: - serializedVersion: 2 - rgba: 36607 - key2: - serializedVersion: 2 - rgba: 195 - key3: - serializedVersion: 2 - rgba: 195 - key4: - serializedVersion: 2 - rgba: 195 - key5: - serializedVersion: 2 - rgba: 195 - key6: - serializedVersion: 2 - rgba: 255 - key7: - serializedVersion: 2 - rgba: 255 - ctime0: 7132 - ctime1: 36815 - ctime2: 52428 - ctime3: 52428 - ctime4: 52428 - ctime5: 52428 - ctime6: 65535 - ctime7: 65535 - atime0: 41827 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_NumColorKeys: 3 - m_NumAlphaKeys: 2 - minGradient: - key0: - serializedVersion: 2 - rgba: 4294967295 - key1: - serializedVersion: 2 - rgba: 4294967295 - key2: - serializedVersion: 2 - rgba: 0 - key3: - serializedVersion: 2 - rgba: 0 - key4: - serializedVersion: 2 - rgba: 0 - key5: - serializedVersion: 2 - rgba: 0 - key6: - serializedVersion: 2 - rgba: 0 - key7: - serializedVersion: 2 - rgba: 0 - ctime0: 0 - ctime1: 65535 - ctime2: 0 - ctime3: 0 - ctime4: 0 - ctime5: 0 - ctime6: 0 - ctime7: 0 - atime0: 0 - atime1: 65535 - atime2: 0 - atime3: 0 - atime4: 0 - atime5: 0 - atime6: 0 - atime7: 0 - m_NumColorKeys: 2 - m_NumAlphaKeys: 2 - minColor: + frequency: 0.5 + damping: 1 + octaves: 1 + octaveMultiplier: 0.5 + octaveScale: 2 + quality: 2 + scrollSpeed: + scalar: 0 + maxCurve: serializedVersion: 2 - rgba: 4294967295 - maxColor: + m_Curve: + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minCurve: serializedVersion: 2 - rgba: 4294967295 - minMaxState: 1 - UVModule: - enabled: 0 - frameOverTime: + m_Curve: + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + minMaxState: 0 + remap: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 - value: 0 + - serializedVersion: 2 + time: 0 + value: -1 inSlope: 0 - outSlope: 1 + outSlope: 2 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 - inSlope: 1 + inSlope: 2 outSlope: 0 tangentMode: 0 m_PreInfinity: 2 @@ -2230,41 +4313,37 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 - outSlope: 1 + outSlope: 0 tangentMode: 0 - - time: 1 - value: 1 - inSlope: 1 + - serializedVersion: 2 + time: 1 + value: 0 + inSlope: 0 outSlope: 0 tangentMode: 0 m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 1 - tilesX: 1 - tilesY: 1 - animationType: 0 - rowIndex: 0 - cycles: 1 - randomRow: 1 - VelocityModule: - enabled: 0 - x: - scalar: 5 + remapY: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 - value: 1 + - serializedVersion: 2 + time: 0 + value: -1 inSlope: 0 - outSlope: 0 + outSlope: 2 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 - inSlope: 0 + inSlope: 2 outSlope: 0 tangentMode: 0 m_PreInfinity: 2 @@ -2273,12 +4352,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2286,20 +4367,22 @@ ParticleSystem: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 0 - y: - scalar: 5 + minMaxState: 1 + remapZ: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 - value: 1 + - serializedVersion: 2 + time: 0 + value: -1 inSlope: 0 - outSlope: 0 + outSlope: 2 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 - inSlope: 0 + inSlope: 2 outSlope: 0 tangentMode: 0 m_PreInfinity: 2 @@ -2308,12 +4391,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2321,18 +4406,23 @@ ParticleSystem: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 0 - z: - scalar: 5 + minMaxState: 1 + remapEnabled: 0 + SizeBySpeedModule: + enabled: 0 + curve: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2343,12 +4433,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2356,22 +4448,20 @@ ParticleSystem: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 0 - inWorldSpace: 0 - InheritVelocityModule: - enabled: 0 - m_Mode: 0 - m_Curve: + minMaxState: 1 + y: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2382,12 +4472,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2395,15 +4487,20 @@ ParticleSystem: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 0 - ForceModule: - enabled: 1 - x: - scalar: 0.5 + minMaxState: 1 + z: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2414,21 +4511,39 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 - value: -1 + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 3 - y: - scalar: 0.5 + minMaxState: 1 + range: {x: 0, y: 1} + separateAxes: 0 + RotationBySpeedModule: + enabled: 0 + x: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2439,21 +4554,35 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 - value: -1 + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 3 - z: - scalar: 0.5 + minMaxState: 0 + y: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2464,33 +4593,35 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 - value: -1 + - serializedVersion: 2 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + - serializedVersion: 2 + time: 1 + value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - minMaxState: 3 - inWorldSpace: 0 - randomizePerFrame: 1 - ExternalForcesModule: - enabled: 0 - multiplier: 1 - ClampVelocityModule: - enabled: 0 - x: - scalar: 1 + minMaxState: 0 + curve: + scalar: 0.7853981 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2501,12 +4632,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2515,17 +4648,128 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - y: - scalar: 1 + separateAxes: 0 + range: {x: 0, y: 1} + ColorBySpeedModule: + enabled: 0 + gradient: + serializedVersion: 2 + maxGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} + minMaxState: 1 + range: {x: 0, y: 1} + CollisionModule: + enabled: 0 + serializedVersion: 3 + type: 0 + collisionMode: 0 + plane0: {fileID: 0} + plane1: {fileID: 0} + plane2: {fileID: 0} + plane3: {fileID: 0} + plane4: {fileID: 0} + plane5: {fileID: 0} + m_Dampen: + scalar: 0 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2536,12 +4780,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2550,17 +4796,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - z: + m_Bounce: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2571,12 +4819,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2585,17 +4835,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - magnitude: - scalar: 1 + m_EnergyLossOnCollision: + scalar: 0 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2606,12 +4858,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2620,60 +4874,59 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - separateAxis: 0 - inWorldSpace: 0 - dampen: 1 - SizeBySpeedModule: + minKillSpeed: 0 + maxKillSpeed: 10000 + radiusScale: 1 + collidesWith: + serializedVersion: 2 + m_Bits: 4294967295 + maxCollisionShapes: 256 + quality: 0 + voxelSize: 0.5 + collisionMessages: 0 + collidesWithDynamic: 1 + interiorCollisions: 1 + TriggerModule: enabled: 0 - curve: - scalar: 1 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 1 - range: {x: 0, y: 1} - RotationBySpeedModule: + collisionShape0: {fileID: 0} + collisionShape1: {fileID: 0} + collisionShape2: {fileID: 0} + collisionShape3: {fileID: 0} + collisionShape4: {fileID: 0} + collisionShape5: {fileID: 0} + inside: 1 + outside: 0 + enter: 0 + exit: 0 + radiusScale: 1 + SubModule: + serializedVersion: 2 enabled: 0 - x: + subEmitters: + - emitter: {fileID: 0} + type: 0 + properties: 0 + LightsModule: + enabled: 0 + ratio: 0 + light: {fileID: 0} + randomDistribution: 1 + color: 1 + range: 1 + intensity: 1 + rangeCurve: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2684,12 +4937,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2698,17 +4953,19 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - y: + intensityCurve: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2719,12 +4976,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2733,17 +4992,23 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - curve: - scalar: 0.7853981 + maxLights: 20 + TrailModule: + enabled: 0 + ratio: 1 + lifetime: + scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2754,12 +5019,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2768,11 +5035,15 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - separateAxes: 0 - range: {x: 0, y: 1} - ColorBySpeedModule: - enabled: 0 - gradient: + minVertexDistance: 0.2 + textureMode: 0 + worldSpace: 0 + dieWithParticles: 1 + sizeAffectsWidth: 1 + sizeAffectsLifetime: 0 + inheritParticleColor: 1 + colorOverLifetime: + serializedVersion: 2 maxGradient: key0: serializedVersion: 2 @@ -2814,6 +5085,7 @@ ParticleSystem: atime5: 0 atime6: 0 atime7: 0 + m_Mode: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 minGradient: @@ -2857,108 +5129,25 @@ ParticleSystem: atime5: 0 atime6: 0 atime7: 0 + m_Mode: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 - minColor: - serializedVersion: 2 - rgba: 4294967295 - maxColor: - serializedVersion: 2 - rgba: 4294967295 - minMaxState: 1 - range: {x: 0, y: 1} - CollisionModule: - enabled: 0 - serializedVersion: 2 - type: 0 - collisionMode: 0 - plane0: {fileID: 0} - plane1: {fileID: 0} - plane2: {fileID: 0} - plane3: {fileID: 0} - plane4: {fileID: 0} - plane5: {fileID: 0} - m_Dampen: - scalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} minMaxState: 0 - m_Bounce: + widthOverTrail: scalar: 1 maxCurve: serializedVersion: 2 m_Curve: - - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minCurve: - serializedVersion: 2 - m_Curve: - - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - - time: 1 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - minMaxState: 0 - m_EnergyLossOnCollision: - scalar: 0 - maxCurve: - serializedVersion: 2 - m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 1 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 1 inSlope: 0 outSlope: 0 @@ -2969,12 +5158,14 @@ ParticleSystem: minCurve: serializedVersion: 2 m_Curve: - - time: 0 + - serializedVersion: 2 + time: 0 value: 0 inSlope: 0 outSlope: 0 tangentMode: 0 - - time: 1 + - serializedVersion: 2 + time: 1 value: 0 inSlope: 0 outSlope: 0 @@ -2983,27 +5174,102 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 minMaxState: 0 - minKillSpeed: 0 - radiusScale: 1 - collidesWith: + colorOverTrail: serializedVersion: 2 - m_Bits: 4294967295 - maxCollisionShapes: 256 - quality: 0 - voxelSize: 0.5 - collisionMessages: 0 - collidesWithDynamic: 1 - interiorCollisions: 1 - SubModule: - enabled: 0 - subEmitterBirth: {fileID: 0} - subEmitterBirth1: {fileID: 0} - subEmitterCollision: {fileID: 0} - subEmitterCollision1: {fileID: 0} - subEmitterDeath: {fileID: 0} - subEmitterDeath1: {fileID: 0} + maxGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minGradient: + key0: + serializedVersion: 2 + rgba: 4294967295 + key1: + serializedVersion: 2 + rgba: 4294967295 + key2: + serializedVersion: 2 + rgba: 0 + key3: + serializedVersion: 2 + rgba: 0 + key4: + serializedVersion: 2 + rgba: 0 + key5: + serializedVersion: 2 + rgba: 0 + key6: + serializedVersion: 2 + rgba: 0 + key7: + serializedVersion: 2 + rgba: 0 + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + minColor: {r: 1, g: 1, b: 1, a: 1} + maxColor: {r: 1, g: 1, b: 1, a: 1} + minMaxState: 0 --- !u!199 &19900000 ParticleSystemRenderer: + serializedVersion: 2 m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} @@ -3011,17 +5277,23 @@ ParticleSystemRenderer: m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 m_Materials: - {fileID: 2100000, guid: b1ca011c5f92d4fd4b5aeac44fd607c6, type: 2} - m_SubsetIndices: + - {fileID: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 0 - m_ReflectionProbeUsage: 0 m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 + m_SelectedEditorRenderState: 0 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -3039,12 +5311,15 @@ ParticleSystemRenderer: m_NormalDirection: 1 m_RenderAlignment: 0 m_Pivot: {x: 0, y: 0, z: 0} + m_UseCustomVertexStreams: 0 + m_VertexStreamMask: 27 m_Mesh: {fileID: 0} m_Mesh1: {fileID: 0} m_Mesh2: {fileID: 0} m_Mesh3: {fileID: 0} --- !u!199 &19900002 ParticleSystemRenderer: + serializedVersion: 2 m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} @@ -3052,17 +5327,23 @@ ParticleSystemRenderer: m_Enabled: 1 m_CastShadows: 0 m_ReceiveShadows: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 m_Materials: - {fileID: 10301, guid: 0000000000000000f000000000000000, type: 0} - m_SubsetIndices: + - {fileID: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 0 - m_ReflectionProbeUsage: 0 m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 + m_SelectedEditorRenderState: 0 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -3080,6 +5361,8 @@ ParticleSystemRenderer: m_NormalDirection: 1 m_RenderAlignment: 0 m_Pivot: {x: 0, y: 0, z: 0} + m_UseCustomVertexStreams: 0 + m_VertexStreamMask: 27 m_Mesh: {fileID: 0} m_Mesh1: {fileID: 0} m_Mesh2: {fileID: 0} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs index 3256f0aa0..2540f897f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs @@ -32,7 +32,7 @@ public void Tick() void Die() { - var explosion = _explosionFactory.Create(); + var explosion = _explosionFactory.Spawn(); explosion.transform.position = _model.Position; GameObject.Destroy(_context.gameObject); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs index 64686a2c8..4d196572c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs @@ -89,7 +89,7 @@ public void FixedUpdate() void Fire() { - var bullet = _bulletFactory.Create( + var bullet = _bulletFactory.Spawn( _settings.BulletSpeed, _settings.BulletLifetime, BulletTypes.FromEnemy); // Randomize our aim a bit diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs index 6742e900a..77cccca46 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs @@ -28,11 +28,11 @@ public override void InstallBindings() Container.Bind().AsSingle(); - Container.BindFactory() + Container.BindPooledFactory().WithInitialSize(10).ExpandByDoubling() .FromPrefab(_settings.BulletPrefab) .UnderTransformGroup("Bullets"); - Container.BindFactory() + Container.BindPooledFactory().WithInitialSize(3) .FromPrefab(_settings.ExplosionPrefab) .UnderTransformGroup("Explosions"); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs index 0f778d166..63771f919 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs @@ -10,7 +10,7 @@ public enum BulletTypes FromPlayer, } - public class Bullet : MonoBehaviour + public class Bullet : MonoBehaviour, IPoolable { float _startTime; BulletTypes _type; @@ -26,10 +26,15 @@ public class Bullet : MonoBehaviour [SerializeField] Material _enemyMaterial = null; - // Since we are a MonoBehaviour, we can't use a constructor - // So use PostInject instead + Factory _selfFactory; + [Inject] - public void Construct(float speed, float lifeTime, BulletTypes type) + void Construct(Factory selfFactory) + { + _selfFactory = selfFactory; + } + + public void OnSpawned(float speed, float lifeTime, BulletTypes type) { _type = type; _speed = speed; @@ -38,6 +43,13 @@ public void Construct(float speed, float lifeTime, BulletTypes type) _renderer.material = type == BulletTypes.FromEnemy ? _enemyMaterial : _playerMaterial; _startTime = Time.realtimeSinceStartup; + + this.gameObject.SetActive(true); + } + + public void OnDespawned() + { + this.gameObject.SetActive(false); } public BulletTypes Type @@ -62,11 +74,11 @@ public void Update() if (Time.realtimeSinceStartup - _startTime > _lifeTime) { - GameObject.Destroy(this.gameObject); + _selfFactory.Despawn(this); } } - public class Factory : Factory + public class Factory : PooledFactory { } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs index 1baed2693..e10d136f0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs @@ -6,36 +6,58 @@ namespace Zenject.SpaceFighter { - public class Explosion : MonoBehaviour + public class Explosion : MonoBehaviour, IPoolable { [SerializeField] float _lifeTime; + [SerializeField] + ParticleSystem _particleSystem; + [SerializeField] AudioClip _sound; [SerializeField] float _soundVolume; + AudioPlayer _audioPlayer; + float _startTime; + Factory _selfFactory; [Inject] - public void Construct(AudioPlayer audioPlayer) + public void Construct(AudioPlayer audioPlayer, Factory selfFactory) + { + _audioPlayer = audioPlayer; + _selfFactory = selfFactory; + } + + public void OnSpawned() { + gameObject.SetActive(true); + + _particleSystem.Clear(); + _particleSystem.Play(); + _startTime = Time.realtimeSinceStartup; - audioPlayer.Play(_sound, _soundVolume); + _audioPlayer.Play(_sound, _soundVolume); + } + + public void OnDespawned() + { + gameObject.SetActive(false); } public void Update() { if (Time.realtimeSinceStartup - _startTime > _lifeTime) { - GameObject.Destroy(this.gameObject); + _selfFactory.Despawn(this); } } - public class Factory : Factory + public class Factory : PooledFactory { } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs index 8fc4501c6..d41702611 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs @@ -32,7 +32,7 @@ void Die() { _model.IsDead = true; - var explosion = _explosionFactory.Create(); + var explosion = _explosionFactory.Spawn(); explosion.transform.position = _model.Position; _model.Renderer.enabled = false; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs index 6444616c5..78231c96f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs @@ -41,7 +41,7 @@ public void Tick() void Fire() { - var bullet = _bulletFactory.Create( + var bullet = _bulletFactory.Spawn( _settings.BulletSpeed, _settings.BulletLifetime, BulletTypes.FromPlayer); bullet.transform.position = _player.Position + _player.LookDir * _settings.BulletOffsetDistance; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity index 051861809..cf337144c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity @@ -318,7 +318,7 @@ GameObject: - component: {fileID: 534447710} - component: {fileID: 534447709} m_Layer: 0 - m_Name: SceneCompositionRoot + m_Name: SceneContext m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs deleted file mode 100644 index 49f32f24e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Collections.Generic; -using NUnit.Framework; -using Assert=ModestTree.Assert; - -namespace Zenject.Tests.Bindings -{ - [TestFixture] - public class TestPoolFactoryTo0 : ZenjectUnitTestFixture - { - [Test] - public void TestSelf() - { - Assert.IsNotNull(new Foo.Factory().Get()); - } - - [Test] - public void TestPool() - { - Foo.Factory factory = new Foo.Factory(); - - List items = new List(); - - for (int count = 4; count > 0; count--) - { - items.Add(factory.Get()); - - Assert.That(factory.TotalActive == items.Count); - Assert.That(factory.TotalInactive == count - 1); - Assert.That(factory.PoolSize == 4); - } - - items.Add(factory.Get()); - - Assert.That(factory.TotalActive == 5); - Assert.That(factory.TotalInactive == 0); - Assert.That(factory.PoolSize == 5); - - - for (int i = 0; i < items.Count; i++) - { - factory.Return(items[i]); - - Assert.That(factory.TotalActive == items.Count - (i + 1)); - Assert.That(factory.TotalInactive == i + 1); - Assert.That(factory.PoolSize == 5); - } - } - - private class Foo : IPoolItem - { - public Foo() - { - - } - - public void Reset() - { - - } - - public class Factory : PoolFactory - { - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs new file mode 100644 index 000000000..57dca4903 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs @@ -0,0 +1,211 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestPooledFactoryTo0 : ZenjectUnitTestFixture + { + [Test] + public void TestFactoryProperties() + { + Container.BindPooledFactory(); + + var factory = Container.Resolve(); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 0); + Assert.IsEqual(factory.NumInactive, 0); + + var foo = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 1); + Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumInactive, 0); + Assert.IsEqual(foo.ResetCount, 1); + + factory.Despawn(foo); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumInactive, 1); + Assert.IsEqual(foo.ResetCount, 1); + + foo = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 1); + Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumInactive, 0); + Assert.IsEqual(foo.ResetCount, 2); + + var foo2 = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 2); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 0); + Assert.IsEqual(foo2.ResetCount, 1); + + factory.Despawn(foo); + + Assert.IsEqual(factory.NumActive, 1); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 1); + Assert.IsEqual(foo.ResetCount, 2); + + factory.Despawn(foo2); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 2); + } + + [Test] + public void TestExpandDouble() + { + Container.BindPooledFactory().ExpandByDoubling(); + + var factory = Container.Resolve(); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 0); + Assert.IsEqual(factory.NumInactive, 0); + + var foo = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 1); + Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumInactive, 0); + + var foo2 = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 2); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 0); + + var foo3 = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 3); + Assert.IsEqual(factory.NumCreated, 4); + Assert.IsEqual(factory.NumInactive, 1); + + factory.Despawn(foo2); + + Assert.IsEqual(factory.NumActive, 2); + Assert.IsEqual(factory.NumCreated, 4); + Assert.IsEqual(factory.NumInactive, 2); + + var foo4 = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 3); + Assert.IsEqual(factory.NumCreated, 4); + Assert.IsEqual(factory.NumInactive, 1); + } + + [Test] + public void TestFixedSize() + { + Container.BindPooledFactory().WithFixedSize(2); + + var factory = Container.Resolve(); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 2); + + var foo = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 1); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 1); + + var foo2 = factory.Spawn(); + + Assert.IsEqual(factory.NumActive, 2); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 0); + + Assert.Throws(() => factory.Spawn()); + } + + [Test] + public void TestInitialSize() + { + Container.BindPooledFactory().WithInitialSize(5); + + var factory = Container.Resolve(); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 5); + Assert.IsEqual(factory.NumInactive, 5); + } + + class Bar + { + public Bar() + { + } + + public class Factory : Factory + { + } + } + + class Foo : IPoolable + { + public Foo() + { + } + + public int ResetCount + { + get; private set; + } + + public void OnDespawned() + { + } + + public void OnSpawned() + { + ResetCount++; + } + + public class Factory : PooledFactory + { + } + } + + [Test] + public void TestSubContainers() + { + Container.BindPooledFactory().FromSubContainerResolve().ByMethod(InstallQux).NonLazy(); + + Container.Validate(); + + var factory = Container.Resolve(); + var qux = factory.Spawn(); + } + + void InstallQux(DiContainer subContainer) + { + subContainer.Bind().AsSingle(); + } + + class Qux : IPoolable + { + public void OnDespawned() + { + } + + public void OnSpawned() + { + } + + public class Factory : PooledFactory + { + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs.meta index ca8a3d668..49e31b2a2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPoolFactoryTo0.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: a9b399b2b4f8a184eb6b6c47cd77009e -timeCreated: 1461708048 -licenseType: Pro +guid: b0a43e0c0ddc4a140869201945a9281f +timeCreated: 1484494442 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs new file mode 100644 index 000000000..71eb8f759 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestPooledFactoryTo1 : ZenjectUnitTestFixture + { + [Test] + public void TestFactoryProperties() + { + Container.BindPooledFactory(); + + var factory = Container.Resolve(); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 0); + Assert.IsEqual(factory.NumInactive, 0); + + var foo = factory.Spawn("asdf"); + + Assert.IsEqual(factory.NumActive, 1); + Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumInactive, 0); + Assert.IsEqual(foo.ResetCount, 1); + Assert.IsEqual(foo.Value, "asdf"); + + factory.Despawn(foo); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumInactive, 1); + Assert.IsEqual(foo.ResetCount, 1); + + foo = factory.Spawn("zxcv"); + + Assert.IsEqual(factory.NumActive, 1); + Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumInactive, 0); + Assert.IsEqual(foo.ResetCount, 2); + Assert.IsEqual(foo.Value, "zxcv"); + + var foo2 = factory.Spawn("qwer"); + + Assert.IsEqual(factory.NumActive, 2); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 0); + Assert.IsEqual(foo2.ResetCount, 1); + Assert.IsEqual(foo2.Value, "qwer"); + + factory.Despawn(foo); + + Assert.IsEqual(factory.NumActive, 1); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 1); + Assert.IsEqual(foo.ResetCount, 2); + + factory.Despawn(foo2); + + Assert.IsEqual(factory.NumActive, 0); + Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumInactive, 2); + } + + class Foo : IPoolable + { + public Foo() + { + } + + public string Value + { + get; + private set; + } + + public int ResetCount + { + get; private set; + } + + public void OnDespawned() + { + } + + public void OnSpawned(string value) + { + Value = value; + ResetCount++; + } + + public class Factory : PooledFactory + { + } + } + } +} + + diff --git a/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs.meta index c5e3ed392..89d951d4a 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: d843594067e131d4ab956888139fbd1f -timeCreated: 1480706812 -licenseType: Pro +guid: a059ebd93077af547b246a2dcc072524 +timeCreated: 1484522322 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/FactoryBindInfo.cs b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/FactoryBindInfo.cs new file mode 100644 index 000000000..b1b9b2347 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/FactoryBindInfo.cs @@ -0,0 +1,22 @@ +using System; + +namespace Zenject +{ + public class FactoryBindInfo + { + public FactoryBindInfo(Type factoryType) + { + FactoryType = factoryType; + } + + public Type FactoryType + { + get; private set; + } + + public Func ProviderFunc + { + get; set; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/FactoryBindInfo.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/FactoryBindInfo.cs.meta new file mode 100644 index 000000000..fe1142a93 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/FactoryBindInfo.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e69b2b4566e331e44a9f92e4e309816a +timeCreated: 1484520532 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs new file mode 100644 index 000000000..cee0448f9 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs @@ -0,0 +1,29 @@ +using System; + +namespace Zenject +{ + public enum PoolExpandMethods + { + OneAtATime, + Double, + Fixed, + } + + public class PooledFactoryBindInfo + { + public PooledFactoryBindInfo() + { + } + + public PoolExpandMethods ExpandMethod + { + get; set; + } + + public int InitialSize + { + get; set; + } + } +} + diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs.meta new file mode 100644 index 000000000..f118825b5 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a6c4ab8068bafb94ba72dc8314d8ad56 +timeCreated: 1484520532 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs index 399ef5908..30a414506 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs @@ -5,30 +5,28 @@ namespace Zenject { public class DynamicFactoryBindingFinalizer : ProviderBindingFinalizer { - readonly Func _providerFunc; - readonly Type _factoryType; + readonly FactoryBindInfo _factoryBindInfo; public DynamicFactoryBindingFinalizer( - BindInfo bindInfo, Type factoryType, Func providerFunc) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) : base(bindInfo) { // Note that it doesn't derive from Factory // when used with To<>, so we can only check IDynamicFactory - Assert.That(factoryType.DerivesFrom()); + Assert.That(factoryBindInfo.FactoryType.DerivesFrom()); - _factoryType = factoryType; - _providerFunc = providerFunc; + _factoryBindInfo = factoryBindInfo; } protected override void OnFinalizeBinding(DiContainer container) { - var provider = _providerFunc(container); + var provider = _factoryBindInfo.ProviderFunc(container); RegisterProviderForAllContracts( container, new CachedProvider( new TransientProvider( - _factoryType, + _factoryBindInfo.FactoryType, container, InjectUtil.CreateArgListExplicit( provider, diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs index 5ff68d3b8..b913de454 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs @@ -6,10 +6,8 @@ namespace Zenject public class FactoryFromBinder : FactoryFromBinderBase { public FactoryFromBinder( - BindInfo bindInfo, - Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } @@ -21,16 +19,16 @@ public ConditionCopyNonLazyBinder FromResolveGetter(Func public ConditionCopyNonLazyBinder FromResolveGetter( object subIdentifier, Func method) { - SubFinalizer = CreateFinalizer( - (container) => new GetterProvider(subIdentifier, method, container)); + FactoryBindInfo.ProviderFunc = + (container) => new GetterProvider(subIdentifier, method, container); return this; } public ConditionCopyNonLazyBinder FromMethod(Func method) { - SubFinalizer = CreateFinalizer( - (container) => new MethodProviderWithContainer(method)); + ProviderFunc = + (container) => new MethodProviderWithContainer(method); return this; } @@ -39,8 +37,8 @@ public ConditionCopyNonLazyBinder FromInstance(object instance) { BindingUtil.AssertInstanceDerivesFromOrEqual(instance, AllParentTypes); - SubFinalizer = CreateFinalizer( - (container) => new InstanceProvider(container, ContractType, instance)); + ProviderFunc = + (container) => new InstanceProvider(container, ContractType, instance); return this; } @@ -48,8 +46,8 @@ public ConditionCopyNonLazyBinder FromInstance(object instance) public ArgConditionCopyNonLazyBinder FromFactory() where TSubFactory : IFactory { - SubFinalizer = CreateFinalizer( - (container) => new FactoryProvider(container, BindInfo.Arguments)); + ProviderFunc = + (container) => new FactoryProvider(container, BindInfo.Arguments); return new ArgConditionCopyNonLazyBinder(BindInfo); } @@ -62,7 +60,7 @@ public FactorySubContainerBinder FromSubContainerResolve() public FactorySubContainerBinder FromSubContainerResolve(object subIdentifier) { return new FactorySubContainerBinder( - BindInfo, FactoryType, FinalizerWrapper, subIdentifier); + BindInfo, FactoryBindInfo, subIdentifier); } #if !NOT_UNITY3D @@ -71,8 +69,8 @@ public ConditionCopyNonLazyBinder FromResource(string resourcePath) { BindingUtil.AssertDerivesFromUnityObject(ContractType); - SubFinalizer = CreateFinalizer( - (container) => new ResourceProvider(resourcePath, ContractType)); + ProviderFunc = + (container) => new ResourceProvider(resourcePath, ContractType); return this; } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder1.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder1.cs index 2750914dc..b73b1d715 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder1.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder1.cs @@ -6,17 +6,15 @@ namespace Zenject public class FactoryFromBinder : FactoryFromBinderBase { public FactoryFromBinder( - BindInfo bindInfo, - Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } public ConditionCopyNonLazyBinder FromMethod(Func method) { - SubFinalizer = CreateFinalizer( - (container) => new MethodProviderWithContainer(method)); + ProviderFunc = + (container) => new MethodProviderWithContainer(method); return this; } @@ -24,8 +22,8 @@ public ConditionCopyNonLazyBinder FromMethod(Func() where TSubFactory : IFactory { - SubFinalizer = CreateFinalizer( - (container) => new FactoryProvider(container, new List())); + ProviderFunc = + (container) => new FactoryProvider(container, new List()); return this; } @@ -38,7 +36,7 @@ public FactorySubContainerBinder FromSubContainerResolve() public FactorySubContainerBinder FromSubContainerResolve(object subIdentifier) { return new FactorySubContainerBinder( - BindInfo, FactoryType, FinalizerWrapper, subIdentifier); + BindInfo, FactoryBindInfo, subIdentifier); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder2.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder2.cs index 437975f7d..8debd602b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder2.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder2.cs @@ -5,15 +5,16 @@ namespace Zenject { public class FactoryFromBinder : FactoryFromBinderBase { - public FactoryFromBinder(BindInfo bindInfo, Type factoryType, BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + public FactoryFromBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } public ConditionCopyNonLazyBinder FromMethod(Func method) { - SubFinalizer = CreateFinalizer( - (container) => new MethodProviderWithContainer(method)); + ProviderFunc = + (container) => new MethodProviderWithContainer(method); return this; } @@ -21,8 +22,8 @@ public ConditionCopyNonLazyBinder FromMethod(Func() where TSubFactory : IFactory { - SubFinalizer = CreateFinalizer( - (container) => new FactoryProvider(container, new List())); + ProviderFunc = + (container) => new FactoryProvider(container, new List()); return this; } @@ -35,7 +36,7 @@ public FactorySubContainerBinder FromSubContainerRe public FactorySubContainerBinder FromSubContainerResolve(object subIdentifier) { return new FactorySubContainerBinder( - BindInfo, FactoryType, FinalizerWrapper, subIdentifier); + BindInfo, FactoryBindInfo, subIdentifier); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder3.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder3.cs index 2e631358f..f674be14c 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder3.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder3.cs @@ -5,15 +5,16 @@ namespace Zenject { public class FactoryFromBinder : FactoryFromBinderBase { - public FactoryFromBinder(BindInfo bindInfo, Type factoryType, BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + public FactoryFromBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } public ConditionCopyNonLazyBinder FromMethod(Func method) { - SubFinalizer = CreateFinalizer( - (container) => new MethodProviderWithContainer(method)); + ProviderFunc = + (container) => new MethodProviderWithContainer(method); return this; } @@ -21,8 +22,8 @@ public ConditionCopyNonLazyBinder FromMethod(Func() where TSubFactory : IFactory { - SubFinalizer = CreateFinalizer( - (container) => new FactoryProvider(container, new List())); + ProviderFunc = + (container) => new FactoryProvider(container, new List()); return this; } @@ -35,7 +36,7 @@ public FactorySubContainerBinder FromSubCo public FactorySubContainerBinder FromSubContainerResolve(object subIdentifier) { return new FactorySubContainerBinder( - BindInfo, FactoryType, FinalizerWrapper, subIdentifier); + BindInfo, FactoryBindInfo, subIdentifier); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder4.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder4.cs index 910feef46..d82d9b535 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder4.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder4.cs @@ -5,15 +5,16 @@ namespace Zenject { public class FactoryFromBinder : FactoryFromBinderBase { - public FactoryFromBinder(BindInfo bindInfo, Type factoryType, BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + public FactoryFromBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } public ConditionCopyNonLazyBinder FromMethod(ModestTree.Util.Func method) { - SubFinalizer = CreateFinalizer( - (container) => new MethodProviderWithContainer(method)); + ProviderFunc = + (container) => new MethodProviderWithContainer(method); return this; } @@ -21,8 +22,8 @@ public ConditionCopyNonLazyBinder FromMethod(ModestTree.Util.Func() where TSubFactory : IFactory { - SubFinalizer = CreateFinalizer( - (container) => new FactoryProvider(container, new List())); + ProviderFunc = + (container) => new FactoryProvider(container, new List()); return this; } @@ -35,7 +36,7 @@ public FactorySubContainerBinder public FactorySubContainerBinder FromSubContainerResolve(object subIdentifier) { return new FactorySubContainerBinder( - BindInfo, FactoryType, FinalizerWrapper, subIdentifier); + BindInfo, FactoryBindInfo, subIdentifier); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder5.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder5.cs index 9ea00d719..b3fe116eb 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder5.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder5.cs @@ -3,17 +3,19 @@ namespace Zenject { - public class FactoryFromBinder : FactoryFromBinderBase + public class FactoryFromBinder + : FactoryFromBinderBase { - public FactoryFromBinder(BindInfo bindInfo, Type factoryType, BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + public FactoryFromBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } public ConditionCopyNonLazyBinder FromMethod(ModestTree.Util.Func method) { - SubFinalizer = CreateFinalizer( - (container) => new MethodProviderWithContainer(method)); + ProviderFunc = + (container) => new MethodProviderWithContainer(method); return this; } @@ -21,8 +23,8 @@ public ConditionCopyNonLazyBinder FromMethod(ModestTree.Util.Func() where TSubFactory : IFactory { - SubFinalizer = CreateFinalizer( - (container) => new FactoryProvider(container, new List())); + ProviderFunc = + (container) => new FactoryProvider(container, new List()); return this; } @@ -35,9 +37,7 @@ public FactorySubContainerBinder FromSubContainerResolve(object subIdentifier) { return new FactorySubContainerBinder( - BindInfo, FactoryType, FinalizerWrapper, subIdentifier); + BindInfo, FactoryBindInfo, subIdentifier); } } } - - diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs index bcebd3fcb..6bed8f249 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs @@ -6,19 +6,18 @@ public class FactorySubContainerBinder : FactorySubContainerBinderBase { public FactorySubContainerBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper, object subIdentifier) - : base(bindInfo, factoryType, finalizerWrapper, subIdentifier) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, object subIdentifier) + : base(bindInfo, factoryBindInfo, subIdentifier) { } public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByMethod( - container, installerMethod))); + container, installerMethod)); return new ConditionCopyNonLazyBinder(BindInfo); } @@ -31,13 +30,13 @@ public NameTransformConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefa var gameObjectInfo = new GameObjectCreationParameters(); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByPrefab( container, new PrefabProvider(prefab), - gameObjectInfo))); + gameObjectInfo)); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } @@ -48,13 +47,13 @@ public NameTransformConditionCopyNonLazyBinder ByPrefabResource(string resourceP var gameObjectInfo = new GameObjectCreationParameters(); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByPrefab( container, new PrefabProviderResource(resourcePath), - gameObjectInfo))); + gameObjectInfo)); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder1.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder1.cs index 7ee50f521..5c35e280a 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder1.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder1.cs @@ -6,19 +6,18 @@ public class FactorySubContainerBinder : FactorySubContainerBinderWithParams { public FactorySubContainerBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper, object subIdentifier) - : base(bindInfo, factoryType, finalizerWrapper, subIdentifier) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, object subIdentifier) + : base(bindInfo, factoryBindInfo, subIdentifier) { } public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByMethod( - container, installerMethod))); + container, installerMethod)); return new ConditionCopyNonLazyBinder(BindInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder2.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder2.cs index dafca5349..68995bccd 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder2.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder2.cs @@ -6,19 +6,18 @@ public class FactorySubContainerBinder : FactorySubContainerBinderWithParams { public FactorySubContainerBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper, object subIdentifier) - : base(bindInfo, factoryType, finalizerWrapper, subIdentifier) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, object subIdentifier) + : base(bindInfo, factoryBindInfo, subIdentifier) { } public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByMethod( - container, installerMethod))); + container, installerMethod)); return new ConditionCopyNonLazyBinder(BindInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder3.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder3.cs index fda8d7867..fdc7361d8 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder3.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder3.cs @@ -6,19 +6,18 @@ public class FactorySubContainerBinder : FactorySubContainerBinderWithParams { public FactorySubContainerBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper, object subIdentifier) - : base(bindInfo, factoryType, finalizerWrapper, subIdentifier) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, object subIdentifier) + : base(bindInfo, factoryBindInfo, subIdentifier) { } public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByMethod( - container, installerMethod))); + container, installerMethod)); return new ConditionCopyNonLazyBinder(BindInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder4.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder4.cs index 0a19d02d7..e4ab7b081 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder4.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder4.cs @@ -6,19 +6,18 @@ public class FactorySubContainerBinder { public FactorySubContainerBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper, object subIdentifier) - : base(bindInfo, factoryType, finalizerWrapper, subIdentifier) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, object subIdentifier) + : base(bindInfo, factoryBindInfo, subIdentifier) { } public ConditionCopyNonLazyBinder ByMethod(ModestTree.Util.Action installerMethod) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByMethod( - container, installerMethod))); + container, installerMethod)); return new ConditionCopyNonLazyBinder(BindInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder5.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder5.cs index db44b301c..933b78413 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder5.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder5.cs @@ -6,19 +6,18 @@ public class FactorySubContainerBinder { public FactorySubContainerBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper, object subIdentifier) - : base(bindInfo, factoryType, finalizerWrapper, subIdentifier) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, object subIdentifier) + : base(bindInfo, factoryBindInfo, subIdentifier) { } public ConditionCopyNonLazyBinder ByMethod(ModestTree.Util.Action installerMethod) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByMethod( - container, installerMethod))); + container, installerMethod)); return new ConditionCopyNonLazyBinder(BindInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs index 82a3acd20..0f0f7257b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs @@ -5,26 +5,26 @@ namespace Zenject { public class FactorySubContainerBinderBase { - readonly BindFinalizerWrapper _finalizerWrapper; - public FactorySubContainerBinderBase( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper, object subIdentifier) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, object subIdentifier) { + FactoryBindInfo = factoryBindInfo; SubIdentifier = subIdentifier; BindInfo = bindInfo; - FactoryType = factoryType; - - _finalizerWrapper = finalizerWrapper; // Reset so we get errors if we end here - finalizerWrapper.SubFinalizer = null; + factoryBindInfo.ProviderFunc = null; } - protected Type FactoryType + protected FactoryBindInfo FactoryBindInfo { - get; - private set; + get; private set; + } + + protected Func ProviderFunc + { + get { return FactoryBindInfo.ProviderFunc; } + set { FactoryBindInfo.ProviderFunc = value; } } protected BindInfo BindInfo @@ -47,20 +47,6 @@ protected Type ContractType } } - protected IBindingFinalizer SubFinalizer - { - set - { - _finalizerWrapper.SubFinalizer = value; - } - } - - protected IBindingFinalizer CreateFinalizer(Func providerFunc) - { - return new DynamicFactoryBindingFinalizer( - BindInfo, FactoryType, providerFunc); - } - public ArgConditionCopyNonLazyBinder ByInstaller() where TInstaller : InstallerBase { @@ -72,11 +58,11 @@ public ArgConditionCopyNonLazyBinder ByInstaller(Type installerType) Assert.That(installerType.DerivesFrom(), "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType.Name()); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByInstaller( - container, installerType, BindInfo.Arguments))); + container, installerType, BindInfo.Arguments)); return new ArgConditionCopyNonLazyBinder(BindInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs index c8af021f7..0f0c48b63 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs @@ -6,9 +6,8 @@ namespace Zenject public class FactorySubContainerBinderWithParams : FactorySubContainerBinderBase { public FactorySubContainerBinderWithParams( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper, object subIdentifier) - : base(bindInfo, factoryType, finalizerWrapper, subIdentifier) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, object subIdentifier) + : base(bindInfo, factoryBindInfo, subIdentifier) { } @@ -29,14 +28,14 @@ public NameTransformConditionCopyNonLazyBinder ByPrefab(Type installerType, Unit var gameObjectInfo = new GameObjectCreationParameters(); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByPrefabWithParams( installerType, container, new PrefabProvider(prefab), - gameObjectInfo))); + gameObjectInfo)); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } @@ -54,14 +53,14 @@ public NameTransformConditionCopyNonLazyBinder ByPrefabResource( var gameObjectInfo = new GameObjectCreationParameters(); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, new SubContainerCreatorByPrefabWithParams( installerType, container, new PrefabProviderResource(resourcePath), - gameObjectInfo))); + gameObjectInfo)); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs index 899993457..d17d8d76d 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs @@ -11,27 +11,24 @@ namespace Zenject public class FactoryFromBinderBase : ArgConditionCopyNonLazyBinder { public FactoryFromBinderBase( - BindInfo bindInfo, - Type factoryType, - BindFinalizerWrapper finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) : base(bindInfo) { - // Note that it doesn't derive from Factory - // when used with To<>, so we can only check IDynamicFactory - Assert.That(factoryType.DerivesFrom()); + FactoryBindInfo = factoryBindInfo; - FactoryType = factoryType; - FinalizerWrapper = finalizerWrapper; + factoryBindInfo.ProviderFunc = + (container) => new TransientProvider(ContractType, container, BindInfo.Arguments, null, BindInfo.ContextInfo); + } - // Default to just creating it using new - finalizerWrapper.SubFinalizer = CreateFinalizer( - (container) => new TransientProvider(ContractType, container, BindInfo.Arguments, null, BindInfo.ContextInfo)); + protected FactoryBindInfo FactoryBindInfo + { + get; private set; } - protected Type FactoryType + protected Func ProviderFunc { - get; - private set; + get { return FactoryBindInfo.ProviderFunc; } + set { FactoryBindInfo.ProviderFunc = value; } } protected Type ContractType @@ -42,20 +39,6 @@ protected Type ContractType } } - protected BindFinalizerWrapper FinalizerWrapper - { - get; - private set; - } - - protected IBindingFinalizer SubFinalizer - { - set - { - FinalizerWrapper.SubFinalizer = value; - } - } - public IEnumerable AllParentTypes { get @@ -69,12 +52,6 @@ public IEnumerable AllParentTypes } } - protected IBindingFinalizer CreateFinalizer(Func providerFunc) - { - return new DynamicFactoryBindingFinalizer( - BindInfo, FactoryType, providerFunc); - } - // Note that this isn't necessary to call since it's the default public ConditionCopyNonLazyBinder FromNew() { @@ -91,9 +68,9 @@ public ConditionCopyNonLazyBinder FromResolve() public ConditionCopyNonLazyBinder FromResolve(object subIdentifier) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new ResolveProvider( - ContractType, container, subIdentifier, false)); + ContractType, container, subIdentifier, false); return this; } @@ -106,19 +83,19 @@ public NameTransformConditionCopyNonLazyBinder FromGameObject() if (ContractType == typeof(GameObject)) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new EmptyGameObjectProvider( - container, gameObjectInfo)); + container, gameObjectInfo); } else { BindingUtil.AssertIsComponent(ContractType); BindingUtil.AssertIsNotAbstract(ContractType); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new AddToNewGameObjectComponentProvider( container, ContractType, null, - new List(), gameObjectInfo)); + new List(), gameObjectInfo); } return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); @@ -130,10 +107,10 @@ public ConditionCopyNonLazyBinder FromComponent(GameObject gameObject) BindingUtil.AssertIsComponent(ContractType); BindingUtil.AssertIsNotAbstract(ContractType); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new AddToExistingGameObjectComponentProvider( gameObject, container, ContractType, - null, new List())); + null, new List()); return this; } @@ -146,22 +123,22 @@ public NameTransformConditionCopyNonLazyBinder FromPrefab(UnityEngine.Object pre if (ContractType == typeof(GameObject)) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new PrefabGameObjectProvider( new PrefabInstantiator( container, gameObjectInfo, - new List(), new PrefabProvider(prefab)))); + new List(), new PrefabProvider(prefab))); } else { BindingUtil.AssertIsAbstractOrComponent(ContractType); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new GetFromPrefabComponentProvider( ContractType, new PrefabInstantiator( container, gameObjectInfo, - new List(), new PrefabProvider(prefab)))); + new List(), new PrefabProvider(prefab))); } return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); @@ -175,22 +152,22 @@ public NameTransformConditionCopyNonLazyBinder FromPrefabResource(string resourc if (ContractType == typeof(GameObject)) { - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new PrefabGameObjectProvider( new PrefabInstantiator( container, gameObjectInfo, - new List(), new PrefabProviderResource(resourcePath)))); + new List(), new PrefabProviderResource(resourcePath))); } else { BindingUtil.AssertIsAbstractOrComponent(ContractType); - SubFinalizer = CreateFinalizer( + ProviderFunc = (container) => new GetFromPrefabComponentProvider( ContractType, new PrefabInstantiator( container, gameObjectInfo, - new List(), new PrefabProviderResource(resourcePath)))); + new List(), new PrefabProviderResource(resourcePath))); } return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder0.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder0.cs index 41e737cdf..65d4a253b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder0.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder0.cs @@ -7,9 +7,8 @@ namespace Zenject public class FactoryToChoiceBinder : FactoryFromBinder { public FactoryToChoiceBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } @@ -29,24 +28,7 @@ public FactoryFromBinder To() typeof(TConcrete) }; - return new FactoryFromBinder( - BindInfo, FactoryType, FinalizerWrapper); - } - } - - public class FactoryToChoiceIdBinder : FactoryToChoiceBinder - { - public FactoryToChoiceIdBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) - { - } - - public FactoryToChoiceBinder WithId(object identifier) - { - BindInfo.Identifier = identifier; - return this; + return new FactoryFromBinder(BindInfo, FactoryBindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder1.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder1.cs index 805ec395a..d560ac2a8 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder1.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder1.cs @@ -7,9 +7,8 @@ namespace Zenject public class FactoryToChoiceBinder : FactoryFromBinder { public FactoryToChoiceBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } @@ -29,24 +28,7 @@ public FactoryFromBinder To() typeof(TConcrete) }; - return new FactoryFromBinder( - BindInfo, FactoryType, FinalizerWrapper); - } - } - - public class FactoryToChoiceIdBinder : FactoryToChoiceBinder - { - public FactoryToChoiceIdBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) - { - } - - public FactoryToChoiceBinder WithId(object identifier) - { - BindInfo.Identifier = identifier; - return this; + return new FactoryFromBinder(BindInfo, FactoryBindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder2.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder2.cs index 513fb6dbb..bd6359d06 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder2.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder2.cs @@ -7,9 +7,8 @@ namespace Zenject public class FactoryToChoiceBinder : FactoryFromBinder { public FactoryToChoiceBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } @@ -29,24 +28,7 @@ public FactoryFromBinder To() typeof(TConcrete) }; - return new FactoryFromBinder( - BindInfo, FactoryType, FinalizerWrapper); - } - } - - public class FactoryToChoiceIdBinder : FactoryToChoiceBinder - { - public FactoryToChoiceIdBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) - { - } - - public FactoryToChoiceBinder WithId(object identifier) - { - BindInfo.Identifier = identifier; - return this; + return new FactoryFromBinder(BindInfo, FactoryBindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder3.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder3.cs index 3fdfb2b95..f54599a4c 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder3.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder3.cs @@ -7,9 +7,8 @@ namespace Zenject public class FactoryToChoiceBinder : FactoryFromBinder { public FactoryToChoiceBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } @@ -29,24 +28,7 @@ public FactoryFromBinder To() typeof(TConcrete) }; - return new FactoryFromBinder( - BindInfo, FactoryType, FinalizerWrapper); - } - } - - public class FactoryToChoiceIdBinder : FactoryToChoiceBinder - { - public FactoryToChoiceIdBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) - { - } - - public FactoryToChoiceBinder WithId(object identifier) - { - BindInfo.Identifier = identifier; - return this; + return new FactoryFromBinder(BindInfo, FactoryBindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder4.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder4.cs index 652cfa72d..5af321944 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder4.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder4.cs @@ -7,9 +7,8 @@ namespace Zenject public class FactoryToChoiceBinder : FactoryFromBinder { public FactoryToChoiceBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } @@ -29,24 +28,7 @@ public FactoryFromBinder To( - BindInfo, FactoryType, FinalizerWrapper); - } - } - - public class FactoryToChoiceIdBinder : FactoryToChoiceBinder - { - public FactoryToChoiceIdBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) - { - } - - public FactoryToChoiceBinder WithId(object identifier) - { - BindInfo.Identifier = identifier; - return this; + return new FactoryFromBinder(BindInfo, FactoryBindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder5.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder5.cs index 142964964..f51c18f96 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder5.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceBinder/FactoryToChoiceBinder5.cs @@ -4,12 +4,12 @@ namespace Zenject { - public class FactoryToChoiceBinder : FactoryFromBinder + public class FactoryToChoiceBinder + : FactoryFromBinder { public FactoryToChoiceBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) { } @@ -29,24 +29,7 @@ public FactoryFromBinder typeof(TConcrete) }; - return new FactoryFromBinder( - BindInfo, FactoryType, FinalizerWrapper); - } - } - - public class FactoryToChoiceIdBinder : FactoryToChoiceBinder - { - public FactoryToChoiceIdBinder( - BindInfo bindInfo, Type factoryType, - BindFinalizerWrapper finalizerWrapper) - : base(bindInfo, factoryType, finalizerWrapper) - { - } - - public FactoryToChoiceBinder WithId(object identifier) - { - BindInfo.Identifier = identifier; - return this; + return new FactoryFromBinder(BindInfo, FactoryBindInfo); } } } diff --git a/UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder.meta similarity index 58% rename from UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder.meta index 9c0480f3e..7854787bb 100644 --- a/UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 -guid: 74050e4f1c20710438915ef25a0fec61 -timeCreated: 1477234561 +guid: ad3cf76cc0b1c154e868ae8b570a78b8 +folderAsset: yes +timeCreated: 1484511595 licenseType: Free DefaultImporter: userData: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder0.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder0.cs new file mode 100644 index 000000000..1924a69ea --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder0.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class FactoryToChoiceIdBinder : FactoryToChoiceBinder + { + public FactoryToChoiceIdBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) + { + } + + public FactoryToChoiceBinder WithId(object identifier) + { + BindInfo.Identifier = identifier; + return this; + } + } +} + + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder0.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder0.cs.meta new file mode 100644 index 000000000..df27539d2 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: dca817e151a0eac4480344dcf838b949 +timeCreated: 1484511596 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder1.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder1.cs new file mode 100644 index 000000000..12db37f13 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder1.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class FactoryToChoiceIdBinder : FactoryToChoiceBinder + { + public FactoryToChoiceIdBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) + { + } + + public FactoryToChoiceBinder WithId(object identifier) + { + BindInfo.Identifier = identifier; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder1.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder1.cs.meta new file mode 100644 index 000000000..74c19ba8b --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a005e8d2a91ae2647927c047c663d046 +timeCreated: 1484511596 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder2.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder2.cs new file mode 100644 index 000000000..2c614538c --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder2.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class FactoryToChoiceIdBinder : FactoryToChoiceBinder + { + public FactoryToChoiceIdBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) + { + } + + public FactoryToChoiceBinder WithId(object identifier) + { + BindInfo.Identifier = identifier; + return this; + } + } +} + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder2.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder2.cs.meta new file mode 100644 index 000000000..a665abe81 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder2.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c109e2a5fd72a004e83beae958fa888a +timeCreated: 1484511596 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder3.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder3.cs new file mode 100644 index 000000000..637f7573a --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder3.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class FactoryToChoiceIdBinder : FactoryToChoiceBinder + { + public FactoryToChoiceIdBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) + { + } + + public FactoryToChoiceBinder WithId(object identifier) + { + BindInfo.Identifier = identifier; + return this; + } + } +} + + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder3.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder3.cs.meta new file mode 100644 index 000000000..2aade6ad0 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder3.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: be02341a689ce654ab7160ce4eb5ed0e +timeCreated: 1484511596 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder4.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder4.cs new file mode 100644 index 000000000..8af5a4da1 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder4.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class FactoryToChoiceIdBinder : FactoryToChoiceBinder + { + public FactoryToChoiceIdBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) + { + } + + public FactoryToChoiceBinder WithId(object identifier) + { + BindInfo.Identifier = identifier; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder4.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder4.cs.meta new file mode 100644 index 000000000..c0280fed3 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder4.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e65744c901e080744aada3988bfdf11c +timeCreated: 1484511596 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder5.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder5.cs new file mode 100644 index 000000000..5e8a7f891 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder5.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class FactoryToChoiceIdBinder + : FactoryToChoiceBinder + { + public FactoryToChoiceIdBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo) + : base(bindInfo, factoryBindInfo) + { + } + + public FactoryToChoiceBinder WithId(object identifier) + { + BindInfo.Identifier = identifier; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder5.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder5.cs.meta new file mode 100644 index 000000000..97a6defe9 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryToChoiceIdBinder/FactoryToChoiceIdBinder5.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 20b01a4cfa147764a9e52134e2a32bb4 +timeCreated: 1484511595 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj.user.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling.meta similarity index 58% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj.user.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling.meta index 1d4665932..bb1b952cc 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj.user.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 -guid: dfa3f877dcc4abc438e9dc273b2fcfab -timeCreated: 1477234561 +guid: a019116e68c18f342995df14d6fbcf87 +folderAsset: yes +timeCreated: 1484511595 licenseType: Free DefaultImporter: userData: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs new file mode 100644 index 000000000..5f431abf7 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs @@ -0,0 +1,40 @@ +using System; +using ModestTree; + +namespace Zenject +{ + public class PooledFactoryBindingFinalizer : ProviderBindingFinalizer + { + readonly PooledFactoryBindInfo _poolBindInfo; + readonly FactoryBindInfo _factoryBindInfo; + + public PooledFactoryBindingFinalizer( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, PooledFactoryBindInfo poolBindInfo) + : base(bindInfo) + { + // Note that it doesn't derive from PooledFactory + // when used with To<>, so we can only check IDynamicPooledFactory + Assert.That(factoryBindInfo.FactoryType.DerivesFrom()); + + _factoryBindInfo = factoryBindInfo; + _poolBindInfo = poolBindInfo; + } + + protected override void OnFinalizeBinding(DiContainer container) + { + var provider = _factoryBindInfo.ProviderFunc(container); + + RegisterProviderForAllContracts( + container, + new CachedProvider( + new TransientProvider( + _factoryBindInfo.FactoryType, + container, + InjectUtil.CreateArgListExplicit( + typeof(TContract), provider, _poolBindInfo.InitialSize, _poolBindInfo.ExpandMethod), + null, + BindInfo.ContextInfo))); + } + } +} + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs.meta new file mode 100644 index 000000000..2f99449e7 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 30d358f8a701526438fa29e3509159c6 +timeCreated: 1484511595 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs new file mode 100644 index 000000000..379709b8f --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class PooledFactoryExpandBinder : FactoryToChoiceIdBinder + { + public PooledFactoryExpandBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, PooledFactoryBindInfo poolBindInfo) + : base(bindInfo, factoryBindInfo) + { + PooledFactoryBindInfo = poolBindInfo; + + ExpandByOneAtATime(); + } + + protected PooledFactoryBindInfo PooledFactoryBindInfo + { + get; private set; + } + + public FactoryToChoiceIdBinder ExpandByOneAtATime() + { + PooledFactoryBindInfo.ExpandMethod = PoolExpandMethods.OneAtATime; + return this; + } + + public FactoryToChoiceIdBinder ExpandByDoubling() + { + PooledFactoryBindInfo.ExpandMethod = PoolExpandMethods.Double; + return this; + } + } +} + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs.meta new file mode 100644 index 000000000..0d0f070ae --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ee5bad9547ef3b044826da894e166bb8 +timeCreated: 1484525028 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs new file mode 100644 index 000000000..dc13db60d --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class PooledFactoryInitialSizeBinder : PooledFactoryExpandBinder + { + public PooledFactoryInitialSizeBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, PooledFactoryBindInfo poolBindInfo) + : base(bindInfo, factoryBindInfo, poolBindInfo) + { + } + + public PooledFactoryExpandBinder WithInitialSize(int size) + { + PooledFactoryBindInfo.InitialSize = size; + return this; + } + + public FactoryToChoiceIdBinder WithFixedSize(int size) + { + PooledFactoryBindInfo.InitialSize = size; + PooledFactoryBindInfo.ExpandMethod = PoolExpandMethods.Fixed; + return this; + } + } +} + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs.meta new file mode 100644 index 000000000..ee09f5257 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9633957b51f224f4da14fbaffe29a756 +timeCreated: 1484522322 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/IGuiRenderable.cs b/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/IGuiRenderable.cs deleted file mode 100644 index 7ab9b8bb3..000000000 --- a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/IGuiRenderable.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Zenject -{ - // This is meant for use with EditorWindowContext - public interface IGuiRenderable - { - void GuiRender(); - } -} - diff --git a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs index 8861ada89..92591898a 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs @@ -16,7 +16,7 @@ public abstract class DynamicFactory : IDynamicFactory InjectContext _injectContext; [Inject] - void Init(IProvider provider, InjectContext injectContext) + void Construct(IProvider provider, InjectContext injectContext) { Assert.IsNotNull(provider); Assert.IsNotNull(injectContext); diff --git a/UnityProject/Assets/Zenject/Source/Factories/IFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/IFactory.cs index b56c300d6..1b9bbf736 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/IFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/IFactory.cs @@ -33,47 +33,5 @@ public interface IFactory : IFactory - where TValue : IPoolItem, new() - { - TValue Get(); - void Return(TValue item); - } - - public interface IPoolFactory : IFactory - where TValue : IPoolItem, new() - { - TValue Create(TParam1 param); - void Return(TValue item); - } - - public interface IPoolFactory : IFactory - where TValue : IPoolItem, new() - { - TValue Create(TParam1 param1, TParam2 param2); - void Return(TValue item); - } - - public interface IPoolFactory : IFactory - where TValue : IPoolItem, new() - { - TValue Create(TParam1 param1, TParam2 param2, TParam3 param3); - void Return(TValue item); - } - - public interface IPoolFactory : IFactory - where TValue : IPoolItem, new() - { - TValue Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4); - void Return(TValue item); - } - - public interface IPoolFactory : IFactory - where TValue : IPoolItem, new() - { - TValue Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5); - void Return(TValue item); - } } diff --git a/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs deleted file mode 100644 index 5687ff20c..000000000 --- a/UnityProject/Assets/Zenject/Source/Factories/PoolFactory.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Zenject -{ - public abstract class DynamicPoolFactory : DynamicFactory - where TValue : IPoolItem, new() - { - public int PoolSize { get { return Pool.PoolSize; } } - public int TotalActive { get { return Pool.TotalActive; } } - public int TotalInactive { get { return Pool.TotalInactive; } } - - protected ObjectPool Pool { get; set; } - } - - public class PoolFactory : DynamicPoolFactory, IPoolFactory - where TValue : IPoolItem, new() - { - // If you were hoping to override this method, use BindFactory<>.ToFactory instead - public TValue Get() - { - if (Pool == null) - { - Pool = new ObjectPool(4, CreateInternal); - } - - return Pool.Get(); - } - - public void Return(TValue item) - { - Pool.Return(item); - } - - private TValue CreateInternal() - { - return CreateInternal(new List()); - } - - protected sealed override IEnumerable ParamTypes - { - get - { - yield break; - } - } - } -} \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Pooling.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling.meta similarity index 57% rename from UnityProject/Assets/Zenject/Source/Pooling.meta rename to UnityProject/Assets/Zenject/Source/Factories/Pooling.meta index b4940fe09..6887d73e3 100644 --- a/UnityProject/Assets/Zenject/Source/Pooling.meta +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: f31b8835604036d42ba13a44763d70d6 +guid: 0f3fb191ad2b6c74c97f488543a89c82 folderAsset: yes -timeCreated: 1480708268 -licenseType: Pro +timeCreated: 1484511595 +licenseType: Free DefaultImporter: userData: assetBundleName: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs new file mode 100644 index 000000000..70f7a414f --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using ModestTree; + +namespace Zenject +{ + public class PoolExceededFixedSizeException : Exception + { + public PoolExceededFixedSizeException(string errorMessage) + : base(errorMessage) + { + } + } + + public interface IDynamicPooledFactory : IValidatable + { + } + + public abstract class DynamicPooledFactory : IDynamicPooledFactory + // don't add generic constraint 'where TContract : IPoolable' since + // we really only require that the concrete type implement that + where TContract : IPoolableBase + { + Stack _pool; + Type _concreteType; + InjectContext _injectContext; + IProvider _provider; + int _numCreated; + int _numActive; + PoolExpandMethods _expandMethod; + + [Inject] + void Construct( + Type concreteType, + IProvider provider, + DiContainer container, + int initialSize, + PoolExpandMethods expandMethod) + { + Assert.That(concreteType.DerivesFromOrEqual()); + + _expandMethod = expandMethod; + _provider = provider; + _concreteType = concreteType; + _injectContext = new InjectContext(container, concreteType); + + _pool = new Stack(initialSize); + + for (int i = 0; i < initialSize; i++) + { + _pool.Push(AllocNew()); + } + } + + public IEnumerable InactiveItems + { + get { return _pool; } + } + + public int NumCreated + { + get { return _numCreated; } + } + + public int NumActive + { + get { return _numActive; } + } + + public int NumInactive + { + get { return _pool.Count; } + } + + protected Type ConcreteType + { + get { return _concreteType; } + } + + TContract AllocNew() + { + try + { + var resultObj = _provider.GetInstance(_injectContext); + + Assert.IsNotNull(resultObj); + Assert.That(resultObj.GetType().DerivesFromOrEqual(_concreteType)); + + _numCreated++; + + var result = (TContract)resultObj; + + // While it might seem a bit weird to call OnDespawned before OnSpawned, + // this is necessary to ensure that MonoBehaviour's get a chance to deactive + // their game object + result.OnDespawned(); + + return result; + } + catch (Exception e) + { + throw new ZenjectException( + "Error during construction of type '{0}' via {1}.Create method!".Fmt( + _concreteType.Name(), this.GetType().Name()), e); + } + } + + public virtual void Validate() + { + try + { + _provider.GetInstance(_injectContext); + } + catch (Exception e) + { + throw new ZenjectException( + "Validation for factory '{0}' failed".Fmt(this.GetType().Name()), e); + } + } + + protected TContract GetInternal() + { + TContract item; + + if (_pool.IsEmpty()) + { + ExpandPool(); + Assert.That(!_pool.IsEmpty()); + } + + item = _pool.Pop(); + + _numActive++; + return item; + } + + void ExpandPool() + { + switch (_expandMethod) + { + case PoolExpandMethods.Fixed: + { + throw new PoolExceededFixedSizeException( + "Pool factory '{0}' exceeded its max size of '{1}'!" + .Fmt(this.GetType().Name(), _numCreated)); + } + case PoolExpandMethods.OneAtATime: + { + _pool.Push(AllocNew()); + break; + } + case PoolExpandMethods.Double: + { + if (_numCreated == 0) + { + _pool.Push(AllocNew()); + } + else + { + var oldSize = _numCreated; + + for (int i = 0; i < oldSize; i++) + { + _pool.Push(AllocNew()); + } + } + break; + } + default: + { + throw Assert.CreateException(); + } + } + } + + public void Despawn(TContract item) + { + Assert.That(!_pool.Contains(item), + "Tried to return an item to pool {0} twice", this.GetType()); + + _numActive--; + _pool.Push(item); + + Assert.That(_numActive >= 0, + "Tried to return an item to the pool that was not originally created in pool"); + + item.OnDespawned(); + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs.meta new file mode 100644 index 000000000..226fcc7da --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 018cad9d9bbd69d449bdef072f22845c +timeCreated: 1484511595 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs new file mode 100644 index 000000000..9d0cf2cfe --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs @@ -0,0 +1,37 @@ +namespace Zenject +{ + public interface IPoolableBase + { + void OnDespawned(); + } + + public interface IPoolable : IPoolableBase + { + void OnSpawned(); + } + + public interface IPoolable : IPoolableBase + { + void OnSpawned(TParam1 p1); + } + + public interface IPoolable : IPoolableBase + { + void OnSpawned(TParam1 p1, TParam2 p2); + } + + public interface IPoolable : IPoolableBase + { + void OnSpawned(TParam1 p1, TParam2 p2, TParam3 p3); + } + + public interface IPoolable : IPoolableBase + { + void OnSpawned(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4); + } + + public interface IPoolable : IPoolableBase + { + void OnSpawned(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TParam5 p5); + } +} diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs.meta new file mode 100644 index 000000000..5fcbd6ddf --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2865ca99e651a9748a36895660955f76 +timeCreated: 1484494442 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs new file mode 100644 index 000000000..5163ab6d1 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs @@ -0,0 +1,46 @@ +namespace Zenject +{ + public interface IPooledFactory + { + int NumCreated { get; } + int NumActive { get; } + int NumInactive { get; } + } + + public interface IPooledFactory : IPooledFactory + { + TValue Spawn(); + void Despawn(TValue item); + } + + public interface IPooledFactory : IPooledFactory + { + TValue Spawn(TParam1 param); + void Despawn(TValue item); + } + + public interface IPooledFactory : IPooledFactory + { + TValue Spawn(TParam1 param1, TParam2 param2); + void Despawn(TValue item); + } + + public interface IPooledFactory : IPooledFactory + { + TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3); + void Despawn(TValue item); + } + + public interface IPooledFactory : IPooledFactory + { + TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4); + void Despawn(TValue item); + } + + public interface IPooledFactory : IPooledFactory + { + TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5); + void Despawn(TValue item); + } +} + diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs.meta new file mode 100644 index 000000000..2e5113229 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a9da90f9975007c40951b87ea862e20c +timeCreated: 1484494442 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs new file mode 100644 index 000000000..05fe798ef --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + // Zero parameters + public class PooledFactory : DynamicPooledFactory, IPooledFactory + // This generic constraint might be undesirable if using an abstract pooled factory + // where the base class does not implement IPoolable, but this seems less important + // than catching the compiler error for the other much more common cases + where TValue : IPoolable + { + [Inject] + void Construct() + { + Assert.That(ConcreteType.DerivesFromOrEqual(), + "Expected pooled type '{0}' to derive from IPoolable", typeof(TValue)); + } + + // If you were hoping to override this method, use BindPooledFactory<>.ToFactory instead + public TValue Spawn() + { + var item = GetInternal(); + ((IPoolable)item).OnSpawned(); + return item; + } + } + + // One parameter + public class PooledFactory + : DynamicPooledFactory, IPooledFactory + // This generic constraint might be undesirable if using an abstract pooled factory + // where the base class does not implement IPoolable, but this seems less important + // than catching the compiler error for the other much more common cases + where TValue : IPoolable + { + [Inject] + void Construct() + { + Assert.That(ConcreteType.DerivesFromOrEqual>(), + "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); + } + + // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead + public TValue Spawn(TParam1 param) + { + var item = GetInternal(); + ((IPoolable)item).OnSpawned(param); + return item; + } + } + + // Two parameters + public class PooledFactory + : DynamicPooledFactory, IPooledFactory + // This generic constraint might be undesirable if using an abstract pooled factory + // where the base class does not implement IPoolable, but this seems less important + // than catching the compiler error for the other much more common cases + where TValue : IPoolable + { + [Inject] + void Construct() + { + Assert.That(ConcreteType.DerivesFromOrEqual>(), + "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); + } + + // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead + public TValue Spawn(TParam1 param1, TParam2 param2) + { + var item = GetInternal(); + ((IPoolable)item).OnSpawned(param1, param2); + return item; + } + } + + // Three parameters + public class PooledFactory + : DynamicPooledFactory, IPooledFactory + // This generic constraint might be undesirable if using an abstract pooled factory + // where the base class does not implement IPoolable, but this seems less important + // than catching the compiler error for the other much more common cases + where TValue : IPoolable + { + [Inject] + void Construct() + { + Assert.That(ConcreteType.DerivesFromOrEqual>(), + "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); + } + + // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead + public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3) + { + var item = GetInternal(); + ((IPoolable)item).OnSpawned(param1, param2, param3); + return item; + } + } + + // Four parameters + public class PooledFactory + : DynamicPooledFactory, IPooledFactory + // This generic constraint might be undesirable if using an abstract pooled factory + // where the base class does not implement IPoolable, but this seems less important + // than catching the compiler error for the other much more common cases + where TValue : IPoolable + { + [Inject] + void Construct() + { + Assert.That(ConcreteType.DerivesFromOrEqual>(), + "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); + } + + // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead + public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) + { + var item = GetInternal(); + ((IPoolable)item).OnSpawned(param1, param2, param3, param4); + return item; + } + } + + // Five parameters + public class PooledFactory + : DynamicPooledFactory, IPooledFactory + // This generic constraint might be undesirable if using an abstract pooled factory + // where the base class does not implement IPoolable, but this seems less important + // than catching the compiler error for the other much more common cases + where TValue : IPoolable + { + [Inject] + void Construct() + { + Assert.That(ConcreteType.DerivesFromOrEqual>(), + "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); + } + + // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead + public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5) + { + var item = GetInternal(); + ((IPoolable)item).OnSpawned(param1, param2, param3, param4, param5); + return item; + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs.meta new file mode 100644 index 000000000..34e6cd05a --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: dd3c2dab9a7ec5740bc90affcbd4120b +timeCreated: 1484494443 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs index 7e0e04ae0..90344ef44 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs @@ -164,7 +164,11 @@ void InstallBindings() { _container.DefaultParent = this.transform; - _container.Bind(typeof(TickableManager), typeof(InitializableManager), typeof(DisposableManager)) + // Note that adding GuiRenderableManager here doesn't instantiate it by default + // You still have to add GuiRenderer manually + // We could add the contents of GuiRenderer into MonoKernel, but this adds + // undesirable per-frame allocations. See comment in IGuiRenderable.cs for usage + _container.Bind(typeof(TickableManager), typeof(InitializableManager), typeof(DisposableManager), typeof(GuiRenderableManager)) .ToSelf().AsSingle().CopyIntoAllSubContainers(); _container.Bind().FromInstance(this); diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 542e010fe..485a56eac 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -1982,94 +1982,191 @@ public IdScopeConditionCopyNonLazyBinder BindInstance(TContract insta return new IdScopeConditionCopyNonLazyBinder(bindInfo); } - public FactoryToChoiceIdBinder BindIFactory() + FactoryToChoiceIdBinder BindFactoryInternal() + where TFactoryConcrete : TFactoryContract, IFactory + where TFactoryContract : IFactory { - var bindInfo = new BindInfo(typeof(IFactory)); + var bindInfo = new BindInfo(typeof(TFactoryContract)); + var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); + + StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + bindInfo, factoryBindInfo); + return new FactoryToChoiceIdBinder( - bindInfo, typeof(Factory), StartBinding()); + bindInfo, factoryBindInfo); + } + + public FactoryToChoiceIdBinder BindIFactory() + { + return BindFactoryInternal, Factory>(); } public FactoryToChoiceIdBinder BindFactory() where TFactory : Factory { - var bindInfo = new BindInfo(typeof(TFactory)); - return new FactoryToChoiceIdBinder( - bindInfo, typeof(TFactory), StartBinding()); + return BindFactoryInternal(); } - public FactoryToChoiceIdBinder BindIFactory() + PooledFactoryInitialSizeBinder BindPooledFactoryInternal() + where TFactoryConcrete : TFactoryContract, IPooledFactory + where TFactoryContract : IPooledFactory + { + var bindInfo = new BindInfo(typeof(TFactoryContract)); + var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); + var poolBindInfo = new PooledFactoryBindInfo(); + + StartBinding().SubFinalizer = new PooledFactoryBindingFinalizer( + bindInfo, factoryBindInfo, poolBindInfo); + + return new PooledFactoryInitialSizeBinder( + bindInfo, factoryBindInfo, poolBindInfo); + } + + public PooledFactoryInitialSizeBinder BindPooledFactory() + where TFactory : IPooledFactory + { + return BindPooledFactoryInternal(); + } + + public PooledFactoryInitialSizeBinder BindIPooledFactory() + where TContract : IPoolable + { + return BindPooledFactoryInternal, PooledFactory>(); + } + + FactoryToChoiceIdBinder BindFactoryInternal() + where TFactoryConcrete : TFactoryContract, IFactory + where TFactoryContract : IFactory { - var bindInfo = new BindInfo(typeof(IFactory)); + var bindInfo = new BindInfo(typeof(TFactoryContract)); + var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); + + StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + bindInfo, factoryBindInfo); + return new FactoryToChoiceIdBinder( - bindInfo, typeof(Factory), StartBinding()); + bindInfo, factoryBindInfo); + } + + public FactoryToChoiceIdBinder BindIFactory() + { + return BindFactoryInternal< + TParam1, TContract, IFactory, Factory>(); } public FactoryToChoiceIdBinder BindFactory() where TFactory : Factory { - var bindInfo = new BindInfo(typeof(TFactory)); - return new FactoryToChoiceIdBinder( - bindInfo, typeof(TFactory), StartBinding()); + return BindFactoryInternal< + TParam1, TContract, TFactory, TFactory>(); } - public FactoryToChoiceIdBinder BindIFactory() + FactoryToChoiceIdBinder BindFactoryInternal() + where TFactoryConcrete : TFactoryContract, IFactory + where TFactoryContract : IFactory { - var bindInfo = new BindInfo(typeof(IFactory)); + var bindInfo = new BindInfo(typeof(TFactoryContract)); + var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); + + StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + bindInfo, factoryBindInfo); + return new FactoryToChoiceIdBinder( - bindInfo, typeof(Factory), StartBinding()); + bindInfo, factoryBindInfo); + } + + public FactoryToChoiceIdBinder BindIFactory() + { + return BindFactoryInternal< + TParam1, TParam2, TContract, IFactory, Factory>(); } public FactoryToChoiceIdBinder BindFactory() where TFactory : Factory { - var bindInfo = new BindInfo(typeof(TFactory)); - return new FactoryToChoiceIdBinder( - bindInfo, typeof(TFactory), StartBinding()); + return BindFactoryInternal< + TParam1, TParam2, TContract, TFactory, TFactory>(); } - public FactoryToChoiceIdBinder BindIFactory() + FactoryToChoiceIdBinder BindFactoryInternal() + where TFactoryConcrete : TFactoryContract, IFactory + where TFactoryContract : IFactory { - var bindInfo = new BindInfo(typeof(IFactory)); + var bindInfo = new BindInfo(typeof(TFactoryContract)); + var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); + + StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + bindInfo, factoryBindInfo); + return new FactoryToChoiceIdBinder( - bindInfo, typeof(Factory), StartBinding()); + bindInfo, factoryBindInfo); + } + + public FactoryToChoiceIdBinder BindIFactory() + { + return BindFactoryInternal< + TParam1, TParam2, TParam3, TContract, IFactory, Factory>(); } public FactoryToChoiceIdBinder BindFactory() where TFactory : Factory { - var bindInfo = new BindInfo(typeof(TFactory)); - return new FactoryToChoiceIdBinder( - bindInfo, typeof(TFactory), StartBinding()); + return BindFactoryInternal< + TParam1, TParam2, TParam3, TContract, TFactory, TFactory>(); } - public FactoryToChoiceIdBinder BindIFactory() + FactoryToChoiceIdBinder BindFactoryInternal() + where TFactoryConcrete : TFactoryContract, IFactory + where TFactoryContract : IFactory { - var bindInfo = new BindInfo(typeof(IFactory)); + var bindInfo = new BindInfo(typeof(TFactoryContract)); + var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); + + StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + bindInfo, factoryBindInfo); + return new FactoryToChoiceIdBinder( - bindInfo, typeof(Factory), StartBinding()); + bindInfo, factoryBindInfo); + } + + public FactoryToChoiceIdBinder BindIFactory() + { + return BindFactoryInternal< + TParam1, TParam2, TParam3, TParam4, TContract, IFactory, Factory>(); } public FactoryToChoiceIdBinder BindFactory() where TFactory : Factory { - var bindInfo = new BindInfo(typeof(TFactory)); - return new FactoryToChoiceIdBinder( - bindInfo, typeof(TFactory), StartBinding()); + return BindFactoryInternal< + TParam1, TParam2, TParam3, TParam4, TContract, TFactory, TFactory>(); } - public FactoryToChoiceIdBinder BindIFactory() + FactoryToChoiceIdBinder BindFactoryInternal() + where TFactoryConcrete : TFactoryContract, IFactory + where TFactoryContract : IFactory { - var bindInfo = new BindInfo(typeof(IFactory)); + var bindInfo = new BindInfo(typeof(TFactoryContract)); + var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); + + StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + bindInfo, factoryBindInfo); + return new FactoryToChoiceIdBinder( - bindInfo, typeof(Factory), StartBinding()); + bindInfo, factoryBindInfo); + } + + public FactoryToChoiceIdBinder BindIFactory() + { + return BindFactoryInternal< + TParam1, TParam2, TParam3, TParam4, TParam5, TContract, IFactory, Factory>(); } public FactoryToChoiceIdBinder BindFactory() where TFactory : Factory { - var bindInfo = new BindInfo(typeof(TFactory)); - return new FactoryToChoiceIdBinder( - bindInfo, typeof(TFactory), StartBinding()); + return BindFactoryInternal< + TParam1, TParam2, TParam3, TParam4, TParam5, TContract, TFactory, TFactory>(); } ////////////// Types //////////////// diff --git a/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs b/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs deleted file mode 100644 index 5dd21179d..000000000 --- a/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Zenject -{ - public interface IPool : IDisposable - where T : IPoolItem - { - int PoolSize { get; } - int TotalActive { get; } - int TotalInactive { get; } - - T Get(); - void Return(T item); - } -} \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs.meta b/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs.meta deleted file mode 100644 index 91f6d42df..000000000 --- a/UnityProject/Assets/Zenject/Source/Pooling/IPool.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: e7c590cda0196ac4f97bc86ab73bb3a5 -timeCreated: 1480708500 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs b/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs deleted file mode 100644 index 8d32d85fc..000000000 --- a/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Zenject -{ - public interface IPoolItem - { - void Reset(); - } -} \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs.meta b/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs.meta deleted file mode 100644 index 904392260..000000000 --- a/UnityProject/Assets/Zenject/Source/Pooling/IPoolItem.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 67c2c6a336587444da40891aa0123ecc -timeCreated: 1480706967 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs b/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs deleted file mode 100644 index ac83e737c..000000000 --- a/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Zenject -{ - public class ObjectPool : IPool - where T : IPoolItem, new() - { - private Stack m_unusedItems; - private Func m_createItemAction; - - public int PoolSize { get; private set; } - public int TotalActive { get { return PoolSize - TotalInactive; } } - public int TotalInactive { get { return m_unusedItems.Count; } } - - public ObjectPool() : this(4) { } - - public ObjectPool(int initalialSize) - { - m_createItemAction = CreateNew; - - InitialisePool(initalialSize); - } - - public ObjectPool(int initalialSize, Func createItemAction) - { - m_createItemAction = createItemAction; - - InitialisePool(initalialSize); - } - - public void Dispose() - { - // ToDo: Should we mark IPoolItem as IDisposable? Or should we check if T is IDisposable and call dispose? - - m_unusedItems.Clear(); - m_unusedItems = null; - } - - public T Get() - { - T item; - - if (m_unusedItems.Count == 0) - { - PoolSize++; - - item = m_createItemAction.Invoke(); - } - else - { - item = m_unusedItems.Pop(); - } - - // Reset the item when it's requested. This is like Initialise. - // ToDo: Should this be changed to Initialise? - item.Reset(); - - return item; - } - - public void Return(T item) - { - // Check to make sure someone hasn't released twice. - if (m_unusedItems.Count > 0 && ReferenceEquals(m_unusedItems.Peek(), item)) - { - throw new InvalidPoolReleaseException(); - } - - m_unusedItems.Push(item); - } - - private void InitialisePool(int initalialSize) - { - m_unusedItems = new Stack(initalialSize); - PoolSize = initalialSize; - - for (int i = 0; i < initalialSize; i++) - { - m_unusedItems.Push(m_createItemAction.Invoke()); - } - } - - private T CreateNew() - { - return new T(); - } - } - - public class InvalidPoolReleaseException : Exception - { - public InvalidPoolReleaseException() - : base("Can not release item that's already released.") - { - } - } -} \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs.meta b/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs.meta deleted file mode 100644 index 9e26aaed2..000000000 --- a/UnityProject/Assets/Zenject/Source/Pooling/ObjectPool.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 77782f76bfdd943488f3f475944806a6 -timeCreated: 1480708272 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/GuiRenderableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs similarity index 90% rename from UnityProject/Assets/Zenject/Source/Editor/EditorWindow/GuiRenderableManager.cs rename to UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs index ff7835461..1bd16713a 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/GuiRenderableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs @@ -6,9 +6,7 @@ namespace Zenject { - // This class is only used inside EditorWindowDependencyRoot, since in most cases - // people aren't going to want it - // However, you can include it yourself if you want to use it + // See comment in IGuiRenderable.cs for usage public class GuiRenderableManager { List _renderables; @@ -29,7 +27,7 @@ public GuiRenderableManager( .Where(x => renderable.GetType().DerivesFromOrEqual(x.First)) .Select(x => x.Second).ToList(); - int priority = matches.IsEmpty() ? 0 : matches.Single(); + int priority = matches.IsEmpty() ? 0 : matches.Distinct().Single(); _renderables.Add( new RenderableInfo(renderable, priority)); diff --git a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/GuiRenderableManager.cs.meta b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Editor/EditorWindow/GuiRenderableManager.cs.meta rename to UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs.meta index c07ab6cb6..cd04998c6 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/GuiRenderableManager.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 40a43d864a711ab449d5684f5efe5fc4 -timeCreated: 1461708049 -licenseType: Pro +guid: 5ca4a43d84d9d554080d313280363783 +timeCreated: 1484528928 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs new file mode 100644 index 000000000..3c45b42be --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using ModestTree; +using ModestTree.Util; +using UnityEngine; + +namespace Zenject +{ + public class GuiRenderer : MonoBehaviour + { + GuiRenderableManager _renderableManager; + + [Inject] + void Construct(GuiRenderableManager renderableManager) + { + _renderableManager = renderableManager; + } + + public void OnGUI() + { + _renderableManager.OnGui(); + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs.meta b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs.meta new file mode 100644 index 000000000..a396d2632 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d6ee197c5aed3b048b76b82a9be3d094 +timeCreated: 1484530704 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: -9996 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs b/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs new file mode 100644 index 000000000..874c1006a --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs @@ -0,0 +1,14 @@ +namespace Zenject +{ + // Note that if you want to bind to this class to have GuiRender called on + // your non-MonoBehaviour classes, you also need to add + // `Container.Bind().FromGameObject().NonLazy()` to an installer somewhere + // Or, if you always want this to be supported in all scenes, then add the following inside + // an installer that is attached to the ProjectContext: + // `Container.Bind().FromGameObject().AsSingle().NonLazy().CopyIntoAllSubContainers()` + public interface IGuiRenderable + { + void GuiRender(); + } +} + diff --git a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/IGuiRenderable.cs.meta b/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Editor/EditorWindow/IGuiRenderable.cs.meta rename to UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs.meta index be89d46cb..e10eadd49 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/IGuiRenderable.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 004b43cb4cf34624580a94c8df4eb18d -timeCreated: 1461708048 -licenseType: Pro +guid: b90847f8da5fb2a4a9bdf577aa2b52e7 +timeCreated: 1484528928 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Util/PoolableMonoBehaviour.meta b/UnityProject/Assets/Zenject/Source/Util/PoolableMonoBehaviour.meta new file mode 100644 index 000000000..d2086e7a0 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Util/PoolableMonoBehaviour.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fc30cf7244a134e47ba111138ac4de48 +folderAsset: yes +timeCreated: 1484532912 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: From 26755d2c139ecefec264e46097dd167d2e5e777f Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Tue, 17 Jan 2017 14:26:20 -0400 Subject: [PATCH 17/62] - Made coding convention a bit more consistent with properties - Added optional PoolCleanupChecker class - Minor fixes to memory pooling in samples --- .../Scripts/Enemy/EnemyCollisionHandler.cs | 2 +- .../Scripts/Installers/GameInstaller.cs | 2 - .../Installers/GameSettingsInstaller.cs | 2 - .../Scripts/Misc/Bullet.cs | 7 ++- .../Scripts/Misc/CameraHandler.cs | 40 ----------------- .../Scripts/Player/PlayerBulletHitHandler.cs | 2 +- .../FactorySubContainerBinderBase.cs | 5 +-- .../Binders/Factory/FactoryFromBinderBase.cs | 5 +-- .../Binding/Binders/FromBinders/FromBinder.cs | 10 +---- .../Binding/Binders/SubContainerBinder.cs | 5 +-- .../Finalizers/BindFinalizerWrapper.cs | 10 +---- .../Finalizers/ProviderBindingFinalizer.cs | 5 +-- .../EditorWindow/ZenjectEditorWindow.cs | 5 +-- .../Testing/ZenjectIntegrationTestFixture.cs | 5 +-- .../Editor/Testing/ZenjectUnitTestFixture.cs | 5 +-- .../Zenject/Source/Factories/Factory.cs | 10 +---- .../Zenject/Source/Factories/KeyedFactory.cs | 30 +++---------- .../Factories/Pooling/DynamicPooledFactory.cs | 31 ++++++++++++- .../Source/Install/Contexts/Context.cs | 20 ++------- .../Install/Contexts/GameObjectContext.cs | 5 +-- .../Source/Install/Contexts/ProjectContext.cs | 14 +++--- .../Source/Install/Contexts/SceneContext.cs | 25 +++-------- .../Install/Contexts/SceneDecoratorContext.cs | 5 +-- .../Source/Install/Contexts/StaticContext.cs | 5 +-- .../Zenject/Source/Install/InstallerBase.cs | 10 +---- .../Source/Install/MonoInstallerBase.cs | 10 +---- .../Install/ScriptableObjectInstallerBase.cs | 10 +---- .../Zenject/Source/Install/ZenjectBinding.cs | 20 ++------- .../Assets/Zenject/Source/Main/DiContainer.cs | 39 +++++------------ .../Source/Main/LazyInstanceInjector.cs | 5 +-- ...AddToCurrentGameObjectComponentProvider.cs | 15 ++----- .../AddToGameObjectComponentProviderBase.cs | 15 ++----- .../PrefabCreators/PrefabInstantiator.cs | 10 +---- .../PrefabInstantiatorCached.cs | 10 +---- .../SubContainerCreatorByPrefabWithParams.cs | 5 +-- .../Source/Runtime/DisposableManager.cs | 1 + .../Source/Runtime/InitializableManager.cs | 1 + .../Source/Runtime/Kernels/MonoKernel.cs | 11 ++--- .../Zenject/Source/Runtime/TaskUpdater.cs | 10 +---- .../Zenject/Source/Runtime/TickableManager.cs | 10 +++-- .../Zenject/Source/Usage/IGuiRenderable.cs | 2 +- .../Zenject/Source/Util/PoolCleanupChecker.cs | 30 +++++++++++++ .../Util/PoolCleanupChecker.cs.meta} | 4 +- .../Source/Util/PoolableMonoBehaviour.meta | 9 ---- .../Assets/Zenject/Source/Util/UnityUtil.cs | 30 +++---------- .../Zenject/Source/Util/ZenjectTypeInfo.cs | 43 +++++-------------- 46 files changed, 171 insertions(+), 384 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/CameraHandler.cs create mode 100644 UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs rename UnityProject/Assets/Zenject/{OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/CameraHandler.cs.meta => Source/Util/PoolCleanupChecker.cs.meta} (76%) delete mode 100644 UnityProject/Assets/Zenject/Source/Util/PoolableMonoBehaviour.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs index b035aad37..e82ea5405 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs @@ -45,7 +45,7 @@ void OnHit(EnemyModel enemy, Bullet bullet) _model.AddForce(-bullet.MoveDirection * _settings.HitForce); _model.TakeDamage(_settings.HealthLoss); - GameObject.Destroy(bullet.gameObject); + bullet.Despawn(); } [Serializable] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs index 77cccca46..4b21883e9 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs @@ -13,8 +13,6 @@ public class GameInstaller : MonoInstaller public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); - Container.Bind().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs index 9dfdfe034..0e423455f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs @@ -23,7 +23,6 @@ namespace Zenject.SpaceFighter //[CreateAssetMenu(menuName = "Space Fighter/Game Settings")] public class GameSettingsInstaller : ScriptableObjectInstaller { - public CameraHandler.Settings CameraHandler; public EnemySpawner.Settings EnemySpawner; public GameDifficultyHandler.Settings GameDifficultyHandler; public GameRestartHandler.Settings GameRestartHandler; @@ -32,7 +31,6 @@ public class GameSettingsInstaller : ScriptableObjectInstaller _lifeTime) { - _selfFactory.Despawn(this); + Despawn(); } } + public void Despawn() + { + _selfFactory.Despawn(this); + } + public class Factory : PooledFactory { } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/CameraHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/CameraHandler.cs deleted file mode 100644 index 1f2c8c1bf..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/CameraHandler.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using UnityEngine; -using Zenject; - -namespace Zenject.SpaceFighter -{ - // Have the camera follow the player around - public class CameraHandler : ITickable - { - readonly Settings _settings; - readonly Camera _camera; - readonly PlayerFacade _player; - - public CameraHandler( - PlayerFacade player, - Camera camera, - Settings settings) - { - _settings = settings; - _camera = camera; - _player = player; - } - - public void Tick() - { - var currentPos = _camera.transform.position; - - var desiredPos = new Vector3( - _player.Position.x, _player.Position.y, currentPos.z); - - _camera.transform.position = Vector3.Lerp(currentPos, desiredPos, _settings.FollowSpeed); - } - - [Serializable] - public class Settings - { - public float FollowSpeed; - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs index 4eced4e11..8afe2b6c8 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs @@ -41,7 +41,7 @@ void OnHit(Bullet bullet) _model.TakeDamage(_settings.HealthLoss); - GameObject.Destroy(bullet.gameObject); + bullet.Despawn(); } [Serializable] diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs index 0f0f7257b..3ee7b9742 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs @@ -41,10 +41,7 @@ protected object SubIdentifier protected Type ContractType { - get - { - return typeof(TContract); - } + get { return typeof(TContract); } } public ArgConditionCopyNonLazyBinder ByInstaller() diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs index d17d8d76d..b8b50bd07 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs @@ -33,10 +33,7 @@ protected Func ProviderFunc protected Type ContractType { - get - { - return typeof(TContract); - } + get { return typeof(TContract); } } public IEnumerable AllParentTypes diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index e1b8e0e0a..c451759a3 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -29,18 +29,12 @@ protected BindFinalizerWrapper FinalizerWrapper protected IBindingFinalizer SubFinalizer { - set - { - FinalizerWrapper.SubFinalizer = value; - } + set { FinalizerWrapper.SubFinalizer = value; } } protected IEnumerable AllParentTypes { - get - { - return BindInfo.ContractTypes.Concat(BindInfo.ToTypes); - } + get { return BindInfo.ContractTypes.Concat(BindInfo.ToTypes); } } protected IEnumerable ConcreteTypes diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs index 72fe32166..afc5babfa 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs @@ -24,10 +24,7 @@ public SubContainerBinder( protected IBindingFinalizer SubFinalizer { - set - { - _finalizerWrapper.SubFinalizer = value; - } + set { _finalizerWrapper.SubFinalizer = value; } } public ScopeConditionCopyNonLazyBinder ByInstaller() diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/BindFinalizerWrapper.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/BindFinalizerWrapper.cs index d57881d4e..a943ecea6 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/BindFinalizerWrapper.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/BindFinalizerWrapper.cs @@ -8,18 +8,12 @@ public class BindFinalizerWrapper : IBindingFinalizer public IBindingFinalizer SubFinalizer { - set - { - _subFinalizer = value; - } + set { _subFinalizer = value; } } public bool CopyIntoAllSubContainers { - get - { - return _subFinalizer.CopyIntoAllSubContainers; - } + get { return _subFinalizer.CopyIntoAllSubContainers; } } public void FinalizeBinding(DiContainer container) diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs index 9ad0e8504..b1ff4f55c 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs @@ -14,10 +14,7 @@ public ProviderBindingFinalizer(BindInfo bindInfo) public bool CopyIntoAllSubContainers { - get - { - return BindInfo.CopyIntoAllSubContainers; - } + get { return BindInfo.CopyIntoAllSubContainers; } } protected BindInfo BindInfo diff --git a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/ZenjectEditorWindow.cs b/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/ZenjectEditorWindow.cs index 4ccd27d66..a20281216 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/ZenjectEditorWindow.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/EditorWindow/ZenjectEditorWindow.cs @@ -26,10 +26,7 @@ public abstract class ZenjectEditorWindow : EditorWindow protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } public virtual void OnEnable() diff --git a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs index 5284eb99c..55ef29105 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs @@ -24,10 +24,7 @@ public abstract class ZenjectIntegrationTestFixture protected DiContainer Container { - get - { - return _sceneContext.Container; - } + get { return _sceneContext.Container; } } [SetUp] diff --git a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectUnitTestFixture.cs b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectUnitTestFixture.cs index 60e7ce121..f7b7de055 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectUnitTestFixture.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectUnitTestFixture.cs @@ -21,10 +21,7 @@ public abstract class ZenjectUnitTestFixture protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } [SetUp] diff --git a/UnityProject/Assets/Zenject/Source/Factories/Factory.cs b/UnityProject/Assets/Zenject/Source/Factories/Factory.cs index ed7ddfa16..ce716be7d 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Factory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Factory.cs @@ -14,10 +14,7 @@ public TValue Create() protected sealed override IEnumerable ParamTypes { - get - { - yield break; - } + get { yield break; } } } @@ -37,10 +34,7 @@ public TValue Create(TParam1 param) protected sealed override IEnumerable ParamTypes { - get - { - yield return typeof(TParam1); - } + get { yield return typeof(TParam1); } } } diff --git a/UnityProject/Assets/Zenject/Source/Factories/KeyedFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/KeyedFactory.cs index 2276cf628..4b6fe9a13 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/KeyedFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/KeyedFactory.cs @@ -20,10 +20,7 @@ public abstract class KeyedFactoryBase : IValidatable protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } protected abstract IEnumerable ProvidedTypes @@ -99,10 +96,7 @@ public class KeyedFactory : KeyedFactoryBase { protected override IEnumerable ProvidedTypes { - get - { - return new Type[0]; - } + get { return new Type[0]; } } public virtual TBase Create(TKey key) @@ -117,10 +111,7 @@ public class KeyedFactory : KeyedFactoryBase { protected override IEnumerable ProvidedTypes { - get - { - return new Type[] { typeof(TParam1) }; - } + get { return new Type[] { typeof(TParam1) }; } } public virtual TBase Create(TKey key, TParam1 param1) @@ -139,10 +130,7 @@ public class KeyedFactory : KeyedFactoryBase ProvidedTypes { - get - { - return new Type[] { typeof(TParam1), typeof(TParam2) }; - } + get { return new Type[] { typeof(TParam1), typeof(TParam2) }; } } public virtual TBase Create(TKey key, TParam1 param1, TParam2 param2) @@ -162,10 +150,7 @@ public class KeyedFactory : KeyedFactory { protected override IEnumerable ProvidedTypes { - get - { - return new Type[] { typeof(TParam1), typeof(TParam2), typeof(TParam3) }; - } + get { return new Type[] { typeof(TParam1), typeof(TParam2), typeof(TParam3) }; } } public virtual TBase Create(TKey key, TParam1 param1, TParam2 param2, TParam3 param3) @@ -186,10 +171,7 @@ public class KeyedFactory : Key { protected override IEnumerable ProvidedTypes { - get - { - return new Type[] { typeof(TParam1), typeof(TParam2), typeof(TParam3), typeof(TParam4) }; - } + get { return new Type[] { typeof(TParam1), typeof(TParam2), typeof(TParam3), typeof(TParam4) }; } } public virtual TBase Create(TKey key, TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs index 70f7a414f..6c834d415 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs @@ -15,6 +15,30 @@ public PoolExceededFixedSizeException(string errorMessage) public interface IDynamicPooledFactory : IValidatable { + int NumCreated + { + get; + } + + int NumActive + { + get; + } + + int NumInactive + { + get; + } + + Type ContractType + { + get; + } + + Type ConcreteType + { + get; + } } public abstract class DynamicPooledFactory : IDynamicPooledFactory @@ -73,7 +97,12 @@ public int NumInactive get { return _pool.Count; } } - protected Type ConcreteType + public Type ContractType + { + get { return typeof(TContract); } + } + + public Type ConcreteType { get { return _concreteType; } } diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs index f98b66d32..f29e32073 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs @@ -30,10 +30,7 @@ public abstract class Context : MonoBehaviour public IEnumerable Installers { - get - { - return _installers; - } + get { return _installers; } set { _installers.Clear(); @@ -43,10 +40,7 @@ public IEnumerable Installers public IEnumerable InstallerPrefabs { - get - { - return _installerPrefabs; - } + get { return _installerPrefabs; } set { _installerPrefabs.Clear(); @@ -56,10 +50,7 @@ public IEnumerable InstallerPrefabs public IEnumerable ScriptableObjectInstallers { - get - { - return _scriptableObjectInstallers; - } + get { return _scriptableObjectInstallers; } set { _scriptableObjectInstallers.Clear(); @@ -70,10 +61,7 @@ public IEnumerable ScriptableObjectInstallers // Unlike other installer types this has to be set through code public IEnumerable NormalInstallers { - get - { - return _normalInstallers; - } + get { return _normalInstallers; } set { _normalInstallers.Clear(); diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs index 0a193d673..2bc519c5d 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs @@ -25,10 +25,7 @@ public class GameObjectContext : Context public override DiContainer Container { - get - { - return _container; - } + get { return _container; } } [Inject] diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs index 90344ef44..4567844eb 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs @@ -26,18 +26,12 @@ public class ProjectContext : Context public override DiContainer Container { - get - { - return _container; - } + get { return _container; } } public static bool HasInstance { - get - { - return _instance != null; - } + get { return _instance != null; } } public static ProjectContext Instance @@ -168,6 +162,10 @@ void InstallBindings() // You still have to add GuiRenderer manually // We could add the contents of GuiRenderer into MonoKernel, but this adds // undesirable per-frame allocations. See comment in IGuiRenderable.cs for usage + // + // Short answer is if you want to use IGuiRenderable then + // you need to include the following in project context installer: + // `Container.Bind().FromGameObject().AsSingle().CopyIntoAllSubContainers().NonLazy();` _container.Bind(typeof(TickableManager), typeof(InitializableManager), typeof(DisposableManager), typeof(GuiRenderableManager)) .ToSelf().AsSingle().CopyIntoAllSubContainers(); diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs index 2904205e1..1ede36c61 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs @@ -46,10 +46,7 @@ public class SceneContext : Context public override DiContainer Container { - get - { - return _container; - } + get { return _container; } } public bool IsValidating @@ -66,10 +63,7 @@ public bool IsValidating public IEnumerable ContractNames { - get - { - return _contractNames; - } + get { return _contractNames; } set { _contractNames.Clear(); @@ -79,10 +73,7 @@ public IEnumerable ContractNames public string ParentContractName { - get - { - return _parentContractName; - } + get { return _parentContractName; } set { _parentContractName = value; @@ -91,14 +82,8 @@ public string ParentContractName public bool ParentNewObjectsUnderRoot { - get - { - return _parentNewObjectsUnderRoot; - } - set - { - _parentNewObjectsUnderRoot = value; - } + get { return _parentNewObjectsUnderRoot; } + set { _parentNewObjectsUnderRoot = value; } } public void Awake() diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs index 523681d00..53978687e 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs @@ -19,10 +19,7 @@ public class SceneDecoratorContext : Context public string DecoratedContractName { - get - { - return _decoratedContractName; - } + get { return _decoratedContractName; } } public override DiContainer Container diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/StaticContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/StaticContext.cs index fa2d07738..4fa38c5fc 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/StaticContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/StaticContext.cs @@ -18,10 +18,7 @@ static StaticContext() public static DiContainer Container { - get - { - return _container; - } + get { return _container; } } } } diff --git a/UnityProject/Assets/Zenject/Source/Install/InstallerBase.cs b/UnityProject/Assets/Zenject/Source/Install/InstallerBase.cs index 70fb2d5c3..7a4d2c1d1 100644 --- a/UnityProject/Assets/Zenject/Source/Install/InstallerBase.cs +++ b/UnityProject/Assets/Zenject/Source/Install/InstallerBase.cs @@ -12,18 +12,12 @@ public abstract class InstallerBase : IInstaller protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } public virtual bool IsEnabled { - get - { - return true; - } + get { return true; } } public abstract void InstallBindings(); diff --git a/UnityProject/Assets/Zenject/Source/Install/MonoInstallerBase.cs b/UnityProject/Assets/Zenject/Source/Install/MonoInstallerBase.cs index 79e885585..d634e95da 100644 --- a/UnityProject/Assets/Zenject/Source/Install/MonoInstallerBase.cs +++ b/UnityProject/Assets/Zenject/Source/Install/MonoInstallerBase.cs @@ -18,18 +18,12 @@ public class MonoInstallerBase : MonoBehaviour, IInstaller protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } public virtual bool IsEnabled { - get - { - return this.enabled; - } + get { return this.enabled; } } public virtual void Start() diff --git a/UnityProject/Assets/Zenject/Source/Install/ScriptableObjectInstallerBase.cs b/UnityProject/Assets/Zenject/Source/Install/ScriptableObjectInstallerBase.cs index 7fe116040..cdbea14e6 100644 --- a/UnityProject/Assets/Zenject/Source/Install/ScriptableObjectInstallerBase.cs +++ b/UnityProject/Assets/Zenject/Source/Install/ScriptableObjectInstallerBase.cs @@ -17,18 +17,12 @@ public class ScriptableObjectInstallerBase : ScriptableObject, IInstaller protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } bool IInstaller.IsEnabled { - get - { - return true; - } + get { return true; } } public virtual void InstallBindings() diff --git a/UnityProject/Assets/Zenject/Source/Install/ZenjectBinding.cs b/UnityProject/Assets/Zenject/Source/Install/ZenjectBinding.cs index 4799ab27a..4f0a477b2 100644 --- a/UnityProject/Assets/Zenject/Source/Install/ZenjectBinding.cs +++ b/UnityProject/Assets/Zenject/Source/Install/ZenjectBinding.cs @@ -26,34 +26,22 @@ public class ZenjectBinding : MonoBehaviour public Context Context { - get - { - return _context; - } + get { return _context; } } public Component[] Components { - get - { - return _components; - } + get { return _components; } } public string Identifier { - get - { - return _identifier; - } + get { return _identifier; } } public BindTypes BindType { - get - { - return _bindType; - } + get { return _bindType; } } public void Start() diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 485a56eac..8125c126a 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -109,10 +109,7 @@ public DiContainer(DiContainer parentContainer) public LazyInstanceInjector LazyInstanceInjector { - get - { - return _lazyInjector; - } + get { return _lazyInjector; } } // When true, this will throw exceptions whenever we create new game objects @@ -126,18 +123,12 @@ public bool AssertOnNewGameObjects public SingletonMarkRegistry SingletonMarkRegistry { - get - { - return _singletonMarkRegistry; - } + get { return _singletonMarkRegistry; } } public SingletonProviderCreator SingletonProviderCreator { - get - { - return _singletonProviderCreator; - } + get { return _singletonProviderCreator; } } #if !NOT_UNITY3D @@ -151,10 +142,7 @@ public Transform DefaultParent public DiContainer ParentContainer { - get - { - return _parentContainer; - } + get { return _parentContainer; } } public bool ChecksForCircularDependencies @@ -173,10 +161,7 @@ public bool ChecksForCircularDependencies public bool IsValidating { - get - { - return _isValidating; - } + get { return _isValidating; } } // When this is true, it will log warnings when Resolve or Instantiate @@ -187,14 +172,8 @@ public bool IsValidating // unexpected behaviour can occur public bool IsInstalling { - get - { - return _isInstalling; - } - set - { - _isInstalling = value; - } + get { return _isInstalling; } + set { _isInstalling = value; } } public IEnumerable AllContracts @@ -2012,6 +1991,10 @@ PooledFactoryInitialSizeBinder BindPooledFactoryInternal Instances { - get - { - return _instancesToInject; - } + get { return _instancesToInject; } } public void AddInstances(IEnumerable instances) diff --git a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs index 31f6ab88e..2054da452 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs @@ -30,26 +30,17 @@ public AddToCurrentGameObjectComponentProvider( protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } protected Type ComponentType { - get - { - return _componentType; - } + get { return _componentType; } } protected object ConcreteIdentifier { - get - { - return _concreteIdentifier; - } + get { return _concreteIdentifier; } } public Type GetInstanceType(InjectContext context) diff --git a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToGameObjectComponentProviderBase.cs b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToGameObjectComponentProviderBase.cs index fdb5ad315..e905619d2 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToGameObjectComponentProviderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToGameObjectComponentProviderBase.cs @@ -29,26 +29,17 @@ public AddToGameObjectComponentProviderBase( protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } protected Type ComponentType { - get - { - return _componentType; - } + get { return _componentType; } } protected object ConcreteIdentifier { - get - { - return _concreteIdentifier; - } + get { return _concreteIdentifier; } } public Type GetInstanceType(InjectContext context) diff --git a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs index 08c6050fb..91a247ed9 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs @@ -28,18 +28,12 @@ public PrefabInstantiator( public GameObjectCreationParameters GameObjectCreationParameters { - get - { - return _gameObjectBindInfo; - } + get { return _gameObjectBindInfo; } } public List ExtraArguments { - get - { - return _extraArguments; - } + get { return _extraArguments; } } public UnityEngine.Object GetPrefab() diff --git a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiatorCached.cs b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiatorCached.cs index 3fd368846..e99a9c26a 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiatorCached.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiatorCached.cs @@ -19,18 +19,12 @@ public PrefabInstantiatorCached(IPrefabInstantiator subInstantiator) public List ExtraArguments { - get - { - return _subInstantiator.ExtraArguments; - } + get { return _subInstantiator.ExtraArguments; } } public GameObjectCreationParameters GameObjectCreationParameters { - get - { - return _subInstantiator.GameObjectCreationParameters; - } + get { return _subInstantiator.GameObjectCreationParameters; } } public UnityEngine.Object GetPrefab() diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs index 4d9f2b348..1f36595ca 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs @@ -25,10 +25,7 @@ public SubContainerCreatorByPrefabWithParams( protected DiContainer Container { - get - { - return _container; - } + get { return _container; } } DiContainer CreateTempContainer(List args) diff --git a/UnityProject/Assets/Zenject/Source/Runtime/DisposableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/DisposableManager.cs index dfe71e2ea..701e979fe 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/DisposableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/DisposableManager.cs @@ -12,6 +12,7 @@ public class DisposableManager : IDisposable bool _disposed; bool _lateDisposed; + [Inject] public DisposableManager( [Inject(Optional = true, Source = InjectSources.Local)] List disposables, diff --git a/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs index a5b0bea6e..1ae4eaea4 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs @@ -12,6 +12,7 @@ public class InitializableManager { List _initializables; + [Inject] public InitializableManager( [Inject(Optional = true, Source = InjectSources.Local)] List initializables, diff --git a/UnityProject/Assets/Zenject/Source/Runtime/Kernels/MonoKernel.cs b/UnityProject/Assets/Zenject/Source/Runtime/Kernels/MonoKernel.cs index 140320a4d..ddf64674f 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/Kernels/MonoKernel.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/Kernels/MonoKernel.cs @@ -21,17 +21,14 @@ public abstract class MonoKernel : MonoBehaviour bool _isDestroyed; - public virtual void Start() + protected bool IsDestroyed { - _initializableManager.Initialize(); + get { return _isDestroyed; } } - protected bool IsDestroyed + public virtual void Start() { - get - { - return _isDestroyed; - } + _initializableManager.Initialize(); } public virtual void Update() diff --git a/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs b/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs index 4d1378ad6..4126c6fb2 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs @@ -14,18 +14,12 @@ public abstract class TaskUpdater IEnumerable AllTasks { - get - { - return ActiveTasks.Concat(_queuedTasks); - } + get { return ActiveTasks.Concat(_queuedTasks); } } IEnumerable ActiveTasks { - get - { - return _tasks; - } + get { return _tasks; } } public void AddTask(TTask task, int priority) diff --git a/UnityProject/Assets/Zenject/Source/Runtime/TickableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/TickableManager.cs index 60126e469..b2d7fca52 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/TickableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/TickableManager.cs @@ -31,12 +31,14 @@ public class TickableManager bool _isPaused; + [Inject] + public TickableManager() + { + } + public IEnumerable Tickables { - get - { - return _tickables; - } + get { return _tickables; } } [Inject] diff --git a/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs b/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs index 874c1006a..a828229dd 100644 --- a/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs +++ b/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs @@ -5,7 +5,7 @@ namespace Zenject // `Container.Bind().FromGameObject().NonLazy()` to an installer somewhere // Or, if you always want this to be supported in all scenes, then add the following inside // an installer that is attached to the ProjectContext: - // `Container.Bind().FromGameObject().AsSingle().NonLazy().CopyIntoAllSubContainers()` + // `Container.Bind().FromGameObject().AsSingle().CopyIntoAllSubContainers().NonLazy()` public interface IGuiRenderable { void GuiRender(); diff --git a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs new file mode 100644 index 000000000..6438a45de --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + // If you want to ensure that all items are always returned to the pool, include the following + // line in an installer on project context: + // Container.BindAllInterfaces().To().AsSingle().CopyIntoAllSubContainers().NonLazy() + public class PoolCleanupChecker : ILateDisposable + { + readonly List _poolFactories; + + public PoolCleanupChecker( + [Inject(Optional = true, Source = InjectSources.Local)] + List poolFactories) + { + _poolFactories = poolFactories; + } + + public void LateDispose() + { + foreach (var pool in _poolFactories) + { + Assert.IsEqual(pool.NumActive, 0, + "Found active objects in pool '{0}' during dispose. Did you forget to despawn an object of type '{1}'?", pool.GetType(), pool.ContractType); + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/CameraHandler.cs.meta b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/CameraHandler.cs.meta rename to UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs.meta index efe8f5fbc..c9fc62898 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/CameraHandler.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 64f9b7e594794344c82f2b95325b319f -timeCreated: 1456416097 +guid: 3560183e1df5b99428bd2c950055a7b7 +timeCreated: 1484674362 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Util/PoolableMonoBehaviour.meta b/UnityProject/Assets/Zenject/Source/Util/PoolableMonoBehaviour.meta deleted file mode 100644 index d2086e7a0..000000000 --- a/UnityProject/Assets/Zenject/Source/Util/PoolableMonoBehaviour.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: fc30cf7244a134e47ba111138ac4de48 -folderAsset: yes -timeCreated: 1484532912 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Util/UnityUtil.cs b/UnityProject/Assets/Zenject/Source/Util/UnityUtil.cs index d3d873e21..470673eaf 100644 --- a/UnityProject/Assets/Zenject/Source/Util/UnityUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Util/UnityUtil.cs @@ -22,50 +22,32 @@ public static IEnumerable AllScenes public static IEnumerable AllLoadedScenes { - get - { - return AllScenes.Where(scene => scene.isLoaded); - } + get { return AllScenes.Where(scene => scene.isLoaded); } } public static bool IsAltKeyDown { - get - { - return Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt); - } + get { return Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt); } } public static bool IsControlKeyDown { - get - { - return Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); - } + get { return Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); } } public static bool IsShiftKeyDown { - get - { - return Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift); - } + get { return Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift); } } public static bool WasShiftKeyJustPressed { - get - { - return Input.GetKeyDown(KeyCode.LeftShift) || Input.GetKeyDown(KeyCode.RightShift); - } + get { return Input.GetKeyDown(KeyCode.LeftShift) || Input.GetKeyDown(KeyCode.RightShift); } } public static bool WasAltKeyJustPressed { - get - { - return Input.GetKeyDown(KeyCode.LeftAlt) || Input.GetKeyDown(KeyCode.RightAlt); - } + get { return Input.GetKeyDown(KeyCode.LeftAlt) || Input.GetKeyDown(KeyCode.RightAlt); } } public static int GetDepthLevel(Transform transform) diff --git a/UnityProject/Assets/Zenject/Source/Util/ZenjectTypeInfo.cs b/UnityProject/Assets/Zenject/Source/Util/ZenjectTypeInfo.cs index 483019082..e0507f1cc 100644 --- a/UnityProject/Assets/Zenject/Source/Util/ZenjectTypeInfo.cs +++ b/UnityProject/Assets/Zenject/Source/Util/ZenjectTypeInfo.cs @@ -19,18 +19,12 @@ public PostInjectableInfo( public MethodInfo MethodInfo { - get - { - return _methodInfo; - } + get { return _methodInfo; } } public IEnumerable InjectableInfo { - get - { - return _injectableInfo; - } + get { return _injectableInfo; } } } @@ -61,59 +55,42 @@ public ZenjectTypeInfo( public Type Type { - get - { - return _typeAnalyzed; - } + get { return _typeAnalyzed; } } public IEnumerable PostInjectMethods { - get - { - return _postInjectMethods; - } + get { return _postInjectMethods; } } public IEnumerable AllInjectables { get { - return _constructorInjectables.Concat(_fieldInjectables).Concat(_propertyInjectables).Concat(_postInjectMethods.SelectMany(x => x.InjectableInfo)); + return _constructorInjectables.Concat(_fieldInjectables).Concat(_propertyInjectables) + .Concat(_postInjectMethods.SelectMany(x => x.InjectableInfo)); } } public IEnumerable FieldInjectables { - get - { - return _fieldInjectables; - } + get { return _fieldInjectables; } } public IEnumerable PropertyInjectables { - get - { - return _propertyInjectables; - } + get { return _propertyInjectables; } } public IEnumerable ConstructorInjectables { - get - { - return _constructorInjectables; - } + get { return _constructorInjectables; } } // May be null public ConstructorInfo InjectConstructor { - get - { - return _injectConstructor; - } + get { return _injectConstructor; } } } } From b78d65f4afcda8d5ad74bdd8df4cc7947814a454 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Tue, 17 Jan 2017 14:59:58 -0400 Subject: [PATCH 18/62] Changed to use Type.ToString() instead of Type.Name() in error messages so that it prints out the namespace and generic arguments --- .../FactorySubContainerBinderBase.cs | 2 +- .../FactorySubContainerBinderWithParams.cs | 2 +- .../Binding/Binders/FromBinders/FromBinder.cs | 2 +- .../Binding/Binders/SubContainerBinder.cs | 2 +- .../Zenject/Source/Binding/BindingUtil.cs | 16 ++++---- .../Source/Factories/DynamicFactory.cs | 4 +- .../Factories/Pooling/DynamicPooledFactory.cs | 6 +-- .../Source/Install/Contexts/Context.cs | 4 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 40 +++++++++---------- .../AddToNewGameObjectComponentProvider.cs | 2 +- .../Source/Providers/IProviderExtensions.cs | 4 +- .../SubContainerCreatorByInstaller.cs | 2 +- .../Source/Runtime/DisposableManager.cs | 4 +- .../Source/Runtime/GuiRenderableManager.cs | 4 +- .../Source/Runtime/InitializableManager.cs | 4 +- .../Zenject/Source/Runtime/TaskUpdater.cs | 6 +-- .../Zenject/Source/Runtime/TickableManager.cs | 6 +-- .../Source/Util/ExecutionOrderExtensions.cs | 14 +++---- .../Zenject/Source/Util/TypeAnalyzer.cs | 6 +-- 19 files changed, 65 insertions(+), 65 deletions(-) diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs index 3ee7b9742..c0985b080 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderBase.cs @@ -53,7 +53,7 @@ public ArgConditionCopyNonLazyBinder ByInstaller() public ArgConditionCopyNonLazyBinder ByInstaller(Type installerType) { Assert.That(installerType.DerivesFrom(), - "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType.Name()); + "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType); ProviderFunc = (container) => new SubContainerDependencyProvider( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs index 0f0c48b63..796d624ff 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs @@ -24,7 +24,7 @@ public NameTransformConditionCopyNonLazyBinder ByPrefab(Type installerType, Unit BindingUtil.AssertIsValidPrefab(prefab); Assert.That(installerType.DerivesFrom(), - "Invalid installer type given during bind command. Expected type '{0}' to derive from 'MonoInstaller'", installerType.Name()); + "Invalid installer type given during bind command. Expected type '{0}' to derive from 'MonoInstaller'", installerType); var gameObjectInfo = new GameObjectCreationParameters(); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index c451759a3..2c4c1936b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -272,7 +272,7 @@ protected ScopeConditionCopyNonLazyBinder FromInstanceBase(object instance, bool { Assert.That(!ZenUtilInternal.IsNull(instance), "Found null instance for type '{0}' in FromInstance method", - ConcreteTypes.First().Name()); + ConcreteTypes.First()); } BindingUtil.AssertInstanceDerivesFromOrEqual(instance, AllParentTypes); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs index afc5babfa..e6def4e73 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs @@ -36,7 +36,7 @@ public ScopeConditionCopyNonLazyBinder ByInstaller() public ScopeConditionCopyNonLazyBinder ByInstaller(Type installerType) { Assert.That(installerType.DerivesFrom(), - "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType.Name()); + "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType); SubFinalizer = new SubContainerInstallerBindingFinalizer( _bindInfo, installerType, _subIdentifier); diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs b/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs index efd48b4cb..2c62ba75d 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs @@ -56,7 +56,7 @@ public static void AssertIsNotComponent() public static void AssertIsNotComponent(Type type) { Assert.That(!type.DerivesFrom(typeof(Component)), - "Invalid type given during bind command. Expected type '{0}' to NOT derive from UnityEngine.Component", type.Name()); + "Invalid type given during bind command. Expected type '{0}' to NOT derive from UnityEngine.Component", type); } public static void AssertDerivesFromUnityObject(IEnumerable types) @@ -75,7 +75,7 @@ public static void AssertDerivesFromUnityObject() public static void AssertDerivesFromUnityObject(Type type) { Assert.That(type.DerivesFrom(), - "Invalid type given during bind command. Expected type '{0}' to derive from UnityEngine.Object", type.Name()); + "Invalid type given during bind command. Expected type '{0}' to derive from UnityEngine.Object", type); } public static void AssertTypesAreNotComponents(IEnumerable types) @@ -110,7 +110,7 @@ public static void AssertIsAbstractOrComponent() public static void AssertIsAbstractOrComponent(Type type) { Assert.That(type.DerivesFrom(typeof(Component)) || type.IsInterface(), - "Invalid type given during bind command. Expected type '{0}' to either derive from UnityEngine.Component or be an interface", type.Name()); + "Invalid type given during bind command. Expected type '{0}' to either derive from UnityEngine.Component or be an interface", type); } public static void AssertIsAbstractOrComponentOrGameObject(IEnumerable types) @@ -129,7 +129,7 @@ public static void AssertIsAbstractOrComponentOrGameObject() public static void AssertIsAbstractOrComponentOrGameObject(Type type) { Assert.That(type.DerivesFrom(typeof(Component)) || type.IsInterface() || type == typeof(GameObject) || type == typeof(UnityEngine.Object), - "Invalid type given during bind command. Expected type '{0}' to either derive from UnityEngine.Component or be an interface or be GameObject", type.Name()); + "Invalid type given during bind command. Expected type '{0}' to either derive from UnityEngine.Component or be an interface or be GameObject", type); } public static void AssertIsComponent(IEnumerable types) @@ -148,7 +148,7 @@ public static void AssertIsComponent() public static void AssertIsComponent(Type type) { Assert.That(type.DerivesFrom(typeof(Component)), - "Invalid type given during bind command. Expected type '{0}' to derive from UnityEngine.Component", type.Name()); + "Invalid type given during bind command. Expected type '{0}' to derive from UnityEngine.Component", type); } public static void AssertIsComponentOrGameObject(IEnumerable types) @@ -167,7 +167,7 @@ public static void AssertIsComponentOrGameObject() public static void AssertIsComponentOrGameObject(Type type) { Assert.That(type.DerivesFrom(typeof(Component)) || type == typeof(GameObject), - "Invalid type given during bind command. Expected type '{0}' to derive from UnityEngine.Component", type.Name()); + "Invalid type given during bind command. Expected type '{0}' to derive from UnityEngine.Component", type); } #else public static void AssertTypesAreNotComponents(IEnumerable types) @@ -217,7 +217,7 @@ public static void AssertIsNotAbstract(Type type) public static void AssertIsDerivedFromType(Type concreteType, Type parentType) { Assert.That(concreteType.DerivesFromOrEqual(parentType), - "Invalid type given during bind command. Expected type '{0}' to derive from type '{1}'", concreteType.Name(), parentType.Name()); + "Invalid type given during bind command. Expected type '{0}' to derive from type '{1}'", concreteType, parentType.Name()); } public static void AssertConcreteTypeListIsNotEmpty(IEnumerable concreteTypes) @@ -271,7 +271,7 @@ public static void AssertInstanceDerivesFromOrEqual(object instance, Type baseTy if (!ZenUtilInternal.IsNull(instance)) { Assert.That(instance.GetType().DerivesFromOrEqual(baseType), - "Invalid type given during bind command. Expected type '{0}' to derive from type '{1}'", instance.GetType().Name(), baseType.Name()); + "Invalid type given during bind command. Expected type '{0}' to derive from type '{1}'", instance.GetType(), baseType.Name()); } } } diff --git a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs index 92591898a..8438a6c17 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs @@ -38,7 +38,7 @@ protected TValue CreateInternal(List extraArgs) catch (Exception e) { throw new ZenjectException( - "Error during construction of type '{0}' via {1}.Create method!".Fmt(typeof(TValue).Name(), this.GetType().Name()), e); + "Error during construction of type '{0}' via {1}.Create method!".Fmt(typeof(TValue), this.GetType().Name()), e); } } @@ -52,7 +52,7 @@ public virtual void Validate() catch (Exception e) { throw new ZenjectException( - "Validation for factory '{0}' failed".Fmt(this.GetType().Name()), e); + "Validation for factory '{0}' failed".Fmt(this.GetType()), e); } } diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs index 6c834d415..0385b85a0 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs @@ -131,7 +131,7 @@ TContract AllocNew() { throw new ZenjectException( "Error during construction of type '{0}' via {1}.Create method!".Fmt( - _concreteType.Name(), this.GetType().Name()), e); + _concreteType, this.GetType().Name()), e); } } @@ -144,7 +144,7 @@ public virtual void Validate() catch (Exception e) { throw new ZenjectException( - "Validation for factory '{0}' failed".Fmt(this.GetType().Name()), e); + "Validation for factory '{0}' failed".Fmt(this.GetType()), e); } } @@ -172,7 +172,7 @@ void ExpandPool() { throw new PoolExceededFixedSizeException( "Pool factory '{0}' exceeded its max size of '{1}'!" - .Fmt(this.GetType().Name(), _numCreated)); + .Fmt(this.GetType(), _numCreated)); } case PoolExpandMethods.OneAtATime: { diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs index f29e32073..78f8095e7 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs @@ -132,7 +132,7 @@ protected void InstallInstallers() foreach (var installerPrefab in _installerPrefabs) { - Assert.IsNotNull(installerPrefab, "Found null installer prefab in '{0}'", this.GetType().Name()); + Assert.IsNotNull(installerPrefab, "Found null installer prefab in '{0}'", this.GetType()); var installerGameObject = GameObject.Instantiate(installerPrefab.gameObject); installerGameObject.transform.SetParent(this.transform, false); @@ -146,7 +146,7 @@ protected void InstallInstallers() foreach (var installer in allInstallers) { Assert.IsNotNull(installer, - "Found null installer in '{0}'", this.GetType().Name()); + "Found null installer in '{0}'", this.GetType()); Container.Inject(installer); installer.InstallBindings(); diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 8125c126a..ce8b09dff 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -255,7 +255,7 @@ public void ValidateIValidatables() { Assert.That(IsValidating); -#if !NOT_UNITY3D +#if !NOT_UNITY3D && !ZEN_TESTS_OUTSIDE_UNITY Assert.That(Application.isEditor); #endif @@ -416,7 +416,7 @@ public IList ResolveAll(InjectContext context) } Assert.That(context.Optional, - "Could not find required dependency with type '{0}' \nObject graph:\n {1}", context.MemberType.Name(), context.GetObjectGraphString()); + "Could not find required dependency with type '{0}' \nObject graph:\n {1}", context.MemberType, context.GetObjectGraphString()); return ReflectionUtil.CreateGenericList(context.MemberType, new object[] {}); } @@ -451,7 +451,7 @@ void CheckForInstallWarning(InjectContext context) _hasDisplayedInstallWarning = true; // Feel free to comment this out if you are comfortable with this practice - Log.Warn("Zenject Warning: It is bad practice to call Inject/Resolve/Instantiate before all the Installers have completed! This is important to ensure that all bindings have properly been installed in case they are needed when injecting/instantiating/resolving. Detected when operating on type '{0}'. If you don't care about this, you can just remove this warning.", rootContext.MemberType.Name()); + Log.Warn("Zenject Warning: It is bad practice to call Inject/Resolve/Instantiate before all the Installers have completed! This is important to ensure that all bindings have properly been installed in case they are needed when injecting/instantiating/resolving. Detected when operating on type '{0}'. If you don't care about this, you can just remove this warning.", rootContext.MemberType); #endif } @@ -486,16 +486,16 @@ public Type ResolveType(InjectContext context) Assert.That(result != ProviderLookupResult.Multiple, "Found multiple matches when only one was expected for type '{0}'{1}. \nObject graph:\n {2}", - context.MemberType.Name(), - (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType.Name())), + context.MemberType, + (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), context.GetObjectGraphString()); if (result != ProviderLookupResult.Success) { throw Assert.CreateException( "Unable to resolve type '{0}'{1}. \nObject graph:\n{2}", - context.MemberType.Name() + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), - (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType.Name())), + context.MemberType.ToString() + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), + (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), context.GetObjectGraphString()); } @@ -594,8 +594,8 @@ public object Resolve(InjectContext context) Assert.That(result != ProviderLookupResult.Multiple, "Found multiple matches when only one was expected for type '{0}'{1}. \nObject graph:\n {2}", - context.MemberType.Name(), - (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType.Name())), + context.MemberType, + (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), context.GetObjectGraphString()); if (result == ProviderLookupResult.None) @@ -617,8 +617,8 @@ public object Resolve(InjectContext context) } throw Assert.CreateException("Unable to resolve type '{0}'{1}. \nObject graph:\n{2}", - context.MemberType.Name() + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), - (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType.Name())), + context.MemberType.ToString() + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), + (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), context.GetObjectGraphString()); } @@ -758,7 +758,7 @@ object InstantiateInternal(Type concreteType, bool autoInject, InjectArgs args) { #if !NOT_UNITY3D Assert.That(!concreteType.DerivesFrom(), - "Error occurred while instantiating object of type '{0}'. Instantiator should not be used to create new mono behaviours. Must use InstantiatePrefabForComponent, InstantiatePrefab, or InstantiateComponent.", concreteType.Name()); + "Error occurred while instantiating object of type '{0}'. Instantiator should not be used to create new mono behaviours. Must use InstantiatePrefabForComponent, InstantiatePrefab, or InstantiateComponent.", concreteType); #endif Assert.That(!concreteType.IsAbstract(), "Expected type '{0}' to be non-abstract", concreteType); @@ -818,7 +818,7 @@ object InstantiateInternal(Type concreteType, bool autoInject, InjectArgs args) if (!IsValidating || CanCreateOrInjectDuringValidation(concreteType)) { - //Log.Debug("Zenject: Instantiating type '{0}'", concreteType.Name()); + //Log.Debug("Zenject: Instantiating type '{0}'", concreteType); try { #if PROFILING_ENABLED @@ -831,7 +831,7 @@ object InstantiateInternal(Type concreteType, bool autoInject, InjectArgs args) catch (Exception e) { throw Assert.CreateException( - e, "Error occurred while instantiating object with type '{0}'", concreteType.Name()); + e, "Error occurred while instantiating object with type '{0}'", concreteType); } } else @@ -848,7 +848,7 @@ object InstantiateInternal(Type concreteType, bool autoInject, InjectArgs args) { throw Assert.CreateException( "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}", - newObj.GetType().Name(), String.Join(",", args.ExtraArgs.Select(x => x.Type.Name()).ToArray()), args.Context.GetObjectGraphString()); + newObj.GetType(), String.Join(",", args.ExtraArgs.Select(x => x.Type.Name()).ToArray()), args.Context.GetObjectGraphString()); } return newObj; @@ -991,7 +991,7 @@ public void InjectExplicit( { throw Assert.CreateException( "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}", - injectableType.Name(), String.Join(",", args.ExtraArgs.Select(x => x.Type.Name()).ToArray()), args.Context.GetObjectGraphString()); + injectableType, String.Join(",", args.ExtraArgs.Select(x => x.Type.Name()).ToArray()), args.Context.GetObjectGraphString()); } } @@ -1182,7 +1182,7 @@ public object InstantiatePrefabForComponentExplicit( Assert.That(prefab != null, "Null prefab found when instantiating game object"); Assert.That(componentType.IsInterface() || componentType.DerivesFrom(), - "Expected type '{0}' to derive from UnityEngine.Component", componentType.Name()); + "Expected type '{0}' to derive from UnityEngine.Component", componentType); GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); @@ -1542,7 +1542,7 @@ public void InjectGameObjectExplicit( { throw Assert.CreateException( "Passed unnecessary parameters when injecting into game object '{0}'. \nExtra Parameters: {1}", - gameObject.name, string.Join(",", extraArgs.Select(x => x.Type.Name()).ToArray())); + gameObject.name, string.Join(",", extraArgs.Select(x => x.Type.ToString()).ToArray())); } } @@ -1912,7 +1912,7 @@ public ConcreteIdBinderNonGeneric BindAllInterfaces(Type type) { // We must only have one dependency root per container // We need this when calling this with a GameObjectContext - return BindInternal(type.Interfaces().ToArray(), "BindAllInterfaces({0})".Fmt(type.Name())); + return BindInternal(type.Interfaces().ToArray(), "BindAllInterfaces({0})".Fmt(type)); } // Same as BindAllInterfaces except also binds to self @@ -1948,7 +1948,7 @@ public IdScopeConditionCopyNonLazyBinder BindInstance(TContract insta if (!allowNull) { Assert.That(!ZenUtilInternal.IsNull(instance), - "Found null instance with type '{0}' in BindInstance method", typeof(TContract).Name()); + "Found null instance with type '{0}' in BindInstance method", typeof(TContract)); } var bindInfo = new BindInfo(typeof(TContract)); diff --git a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToNewGameObjectComponentProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToNewGameObjectComponentProvider.cs index 5165f7959..507dcbf26 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToNewGameObjectComponentProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToNewGameObjectComponentProvider.cs @@ -23,7 +23,7 @@ protected override GameObject GetGameObject(InjectContext context) { if (_gameObjectBindInfo.Name == null) { - _gameObjectBindInfo.Name = ConcreteIdentifier as string ?? ComponentType.Name(); + _gameObjectBindInfo.Name = ConcreteIdentifier as string ?? ComponentType.Name; } return Container.CreateEmptyGameObject(_gameObjectBindInfo); diff --git a/UnityProject/Assets/Zenject/Source/Providers/IProviderExtensions.cs b/UnityProject/Assets/Zenject/Source/Providers/IProviderExtensions.cs index 7e15bc050..975f02fae 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/IProviderExtensions.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/IProviderExtensions.cs @@ -75,10 +75,10 @@ public static object GetInstance( var allInstances = creator.GetAllInstances(context, args); Assert.That(!allInstances.IsEmpty(), - "Provider returned zero instances when one was expected when looking up type '{0}'", context.MemberType.Name()); + "Provider returned zero instances when one was expected when looking up type '{0}'", context.MemberType); Assert.That(allInstances.Count == 1, - "Provider returned multiple instances when only one was expected when looking up type '{0}'", context.MemberType.Name()); + "Provider returned multiple instances when only one was expected when looking up type '{0}'", context.MemberType); return allInstances[0]; } diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs index 73281148d..b7c1875c7 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs @@ -19,7 +19,7 @@ public SubContainerCreatorByInstaller( _extraArgs = extraArgs; Assert.That(installerType.DerivesFrom(), - "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType.Name()); + "Invalid installer type given during bind command. Expected type '{0}' to derive from 'Installer<>'", installerType); } public SubContainerCreatorByInstaller( diff --git a/UnityProject/Assets/Zenject/Source/Runtime/DisposableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/DisposableManager.cs index 701e979fe..751aec567 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/DisposableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/DisposableManager.cs @@ -87,7 +87,7 @@ public void LateDispose() catch (Exception e) { throw Assert.CreateException( - e, "Error occurred while late disposing ILateDisposable with type '{0}'", disposable.LateDisposable.GetType().Name()); + e, "Error occurred while late disposing ILateDisposable with type '{0}'", disposable.LateDisposable.GetType()); } } @@ -118,7 +118,7 @@ public void Dispose() catch (Exception e) { throw Assert.CreateException( - e, "Error occurred while disposing IDisposable with type '{0}'", disposable.Disposable.GetType().Name()); + e, "Error occurred while disposing IDisposable with type '{0}'", disposable.Disposable.GetType()); } } diff --git a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs index 1bd16713a..c8ec09559 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs @@ -48,7 +48,7 @@ public void OnGui() try { #if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.Initialize()", renderable.Renderable.GetType().Name())) + using (ProfileBlock.Start("{0}.Initialize()", renderable.Renderable.GetType())) #endif { renderable.Renderable.GuiRender(); @@ -57,7 +57,7 @@ public void OnGui() catch (Exception e) { throw Assert.CreateException( - e, "Error occurred while initializing IGuiRenderable with type '{0}'", renderable.Renderable.GetType().Name()); + e, "Error occurred while initializing IGuiRenderable with type '{0}'", renderable.Renderable.GetType()); } } } diff --git a/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs index 1ae4eaea4..0febc8441 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs @@ -48,7 +48,7 @@ public void Initialize() try { #if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.Initialize()", initializable.Initializable.GetType().Name())) + using (ProfileBlock.Start("{0}.Initialize()", initializable.Initializable.GetType())) #endif { initializable.Initializable.Initialize(); @@ -57,7 +57,7 @@ public void Initialize() catch (Exception e) { throw Assert.CreateException( - e, "Error occurred while initializing IInitializable with type '{0}'", initializable.Initializable.GetType().Name()); + e, "Error occurred while initializing IInitializable with type '{0}'", initializable.Initializable.GetType()); } } } diff --git a/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs b/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs index 4126c6fb2..0ff168256 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs @@ -147,7 +147,7 @@ public class TickablesTaskUpdater : TaskUpdater protected override void UpdateItem(ITickable task) { #if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.Tick()".Fmt(task.GetType().Name()))) + using (ProfileBlock.Start("{0}.Tick()".Fmt(task.GetType()))) #endif { task.Tick(); @@ -160,7 +160,7 @@ public class LateTickablesTaskUpdater : TaskUpdater protected override void UpdateItem(ILateTickable task) { #if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.LateTick()".Fmt(task.GetType().Name()))) + using (ProfileBlock.Start("{0}.LateTick()".Fmt(task.GetType()))) #endif { task.LateTick(); @@ -173,7 +173,7 @@ public class FixedTickablesTaskUpdater : TaskUpdater protected override void UpdateItem(IFixedTickable task) { #if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.FixedTick()".Fmt(task.GetType().Name()))) + using (ProfileBlock.Start("{0}.FixedTick()".Fmt(task.GetType()))) #endif { task.FixedTick(); diff --git a/UnityProject/Assets/Zenject/Source/Runtime/TickableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/TickableManager.cs index b2d7fca52..8a27acb73 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/TickableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/TickableManager.cs @@ -54,7 +54,7 @@ void InitFixedTickables() foreach (var type in _fixedPriorities.Select(x => x.First)) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to drive from IFixedTickable while checking priorities in TickableHandler", type.Name()); + "Expected type '{0}' to drive from IFixedTickable while checking priorities in TickableHandler", type); } foreach (var tickable in _fixedTickables) @@ -73,7 +73,7 @@ void InitTickables() foreach (var type in _priorities.Select(x => x.First)) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to drive from ITickable while checking priorities in TickableHandler", type.Name()); + "Expected type '{0}' to drive from ITickable while checking priorities in TickableHandler", type); } foreach (var tickable in _tickables) @@ -92,7 +92,7 @@ void InitLateTickables() foreach (var type in _latePriorities.Select(x => x.First)) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to drive from ILateTickable while checking priorities in TickableHandler", type.Name()); + "Expected type '{0}' to drive from ILateTickable while checking priorities in TickableHandler", type); } foreach (var tickable in _lateTickables) diff --git a/UnityProject/Assets/Zenject/Source/Util/ExecutionOrderExtensions.cs b/UnityProject/Assets/Zenject/Source/Util/ExecutionOrderExtensions.cs index 8f6ea79f6..d9b7764f9 100644 --- a/UnityProject/Assets/Zenject/Source/Util/ExecutionOrderExtensions.cs +++ b/UnityProject/Assets/Zenject/Source/Util/ExecutionOrderExtensions.cs @@ -15,7 +15,7 @@ public static void BindExecutionOrder( this DiContainer container, Type type, int order) { Assert.That(type.DerivesFrom() || type.DerivesFrom() || type.DerivesFrom() || type.DerivesFrom() || type.DerivesFrom() || type.DerivesFrom(), - "Expected type '{0}' to derive from one or more of the following interfaces: ITickable, IInitializable, ILateTickable, IFixedTickable, IDisposable, ILateDisposable", type.Name()); + "Expected type '{0}' to derive from one or more of the following interfaces: ITickable, IInitializable, ILateTickable, IFixedTickable, IDisposable, ILateDisposable", type); if (type.DerivesFrom()) { @@ -59,7 +59,7 @@ public static void BindTickableExecutionOrder( this DiContainer container, Type type, int order) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to derive from ITickable", type.Name()); + "Expected type '{0}' to derive from ITickable", type); container.BindInstance( ModestTree.Util.ValuePair.New(type, order)).WhenInjectedInto(); @@ -76,7 +76,7 @@ public static void BindInitializableExecutionOrder( this DiContainer container, Type type, int order) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to derive from IInitializable", type.Name()); + "Expected type '{0}' to derive from IInitializable", type); container.BindInstance( ModestTree.Util.ValuePair.New(type, order)).WhenInjectedInto(); @@ -100,7 +100,7 @@ public static void BindDisposableExecutionOrder( this DiContainer container, Type type, int order) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to derive from IDisposable", type.Name()); + "Expected type '{0}' to derive from IDisposable", type); container.BindInstance( ModestTree.Util.ValuePair.New(type, order)).WhenInjectedInto(); @@ -110,7 +110,7 @@ public static void BindLateDisposableExecutionOrder( this DiContainer container, Type type, int order) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to derive from ILateDisposable", type.Name()); + "Expected type '{0}' to derive from ILateDisposable", type); container.BindInstance( ModestTree.Util.ValuePair.New(type, order)).WithId("Late").WhenInjectedInto(); @@ -127,7 +127,7 @@ public static void BindFixedTickableExecutionOrder( this DiContainer container, Type type, int order) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to derive from IFixedTickable", type.Name()); + "Expected type '{0}' to derive from IFixedTickable", type); container.Bind>().WithId("Fixed") .FromInstance(ModestTree.Util.ValuePair.New(type, order)).WhenInjectedInto(); @@ -144,7 +144,7 @@ public static void BindLateTickableExecutionOrder( this DiContainer container, Type type, int order) { Assert.That(type.DerivesFrom(), - "Expected type '{0}' to derive from ILateTickable", type.Name()); + "Expected type '{0}' to derive from ILateTickable", type); container.Bind>().WithId("Late") .FromInstance(ModestTree.Util.ValuePair.New(type, order)).WhenInjectedInto(); diff --git a/UnityProject/Assets/Zenject/Source/Util/TypeAnalyzer.cs b/UnityProject/Assets/Zenject/Source/Util/TypeAnalyzer.cs index 91cbb9ad8..5a061c7a1 100644 --- a/UnityProject/Assets/Zenject/Source/Util/TypeAnalyzer.cs +++ b/UnityProject/Assets/Zenject/Source/Util/TypeAnalyzer.cs @@ -18,7 +18,7 @@ public static ZenjectTypeInfo GetInfo() public static ZenjectTypeInfo GetInfo(Type type) { Assert.That(!type.IsAbstract(), - "Tried to analyze abstract type '{0}'. This is not currently allowed.", type.Name()); + "Tried to analyze abstract type '{0}'. This is not currently allowed.", type); ZenjectTypeInfo info; @@ -66,7 +66,7 @@ static InjectableInfo CreateInjectableInfoForParam( var injectAttributes = paramInfo.AllAttributes().ToList(); Assert.That(injectAttributes.Count <= 1, - "Found multiple 'Inject' attributes on type parameter '{0}' of type '{1}'. Parameter should only have one", paramInfo.Name, parentType.Name()); + "Found multiple 'Inject' attributes on type parameter '{0}' of type '{1}'. Parameter should only have one", paramInfo.Name, parentType); var injectAttr = injectAttributes.SingleOrDefault(); @@ -156,7 +156,7 @@ static InjectableInfo CreateForMember(MemberInfo memInfo, Type parentType) var injectAttributes = memInfo.AllAttributes().ToList(); Assert.That(injectAttributes.Count <= 1, - "Found multiple 'Inject' attributes on type field '{0}' of type '{1}'. Field should only container one Inject attribute", memInfo.Name, parentType.Name()); + "Found multiple 'Inject' attributes on type field '{0}' of type '{1}'. Field should only container one Inject attribute", memInfo.Name, parentType); var injectAttr = injectAttributes.SingleOrDefault(); From fd841b0b722abb2067a308a80accb3639b09b45a Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Wed, 18 Jan 2017 01:59:40 -0400 Subject: [PATCH 19/62] Changes to the space fighter sample to be much simpler and use memory pooling better --- .../Installers/GameSettingsInstaller.asset | 69 ++++++-- .../Media/Materials/LaserSight.mat | 118 ++++++++++++++ .../Media/Materials/LaserSight.mat.meta | 8 + .../Media/Prefabs/Bullet.prefab | 134 ++++++++-------- .../Media/Prefabs/Enemy.prefab | 86 +++------- .../Media/Sounds/damage.mp3 | Bin 14839 -> 0 bytes .../Media/Sounds/damage.wav | Bin 0 -> 12408 bytes .../{damage.mp3.meta => damage.wav.meta} | 0 .../Media/Sounds/explosion.aiff | Bin 0 -> 95372 bytes .../{laser.mp3.meta => explosion.aiff.meta} | 4 +- .../Media/Sounds/explosion.mp3 | Bin 79992 -> 0 bytes .../Media/Sounds/laser.mp3 | Bin 5595 -> 0 bytes .../Media/Sounds/laser.wav | Bin 0 -> 368172 bytes .../{explosion.mp3.meta => laser.wav.meta} | 4 +- .../Media/Sounds/laser2.wav | Bin 0 -> 19634 bytes .../Media/Sounds/laser2.wav.meta | 22 +++ .../Scripts/Enemy/Enemy.cs | 87 ++++++++++ ...emyHealthWatcher.cs.meta => Enemy.cs.meta} | 4 +- .../Scripts/Enemy/EnemyCollisionDetector.cs | 30 ---- .../Scripts/Enemy/EnemyCollisionHandler.cs | 59 ------- .../Scripts/Enemy/EnemyCommonSettings.cs | 10 ++ ...or.cs.meta => EnemyCommonSettings.cs.meta} | 4 +- .../Scripts/Enemy/EnemyDeathHandler.cs | 47 ++++++ ...odel.cs.meta => EnemyDeathHandler.cs.meta} | 4 +- .../Scripts/Enemy/EnemyFacade.cs | 63 ++++---- .../Scripts/Enemy/EnemyHealthWatcher.cs | 43 ----- .../Scripts/Enemy/EnemyModel.cs | 148 ------------------ .../Scripts/Enemy/EnemyRegistry.cs | 35 ----- .../Scripts/Enemy/EnemyRegistry.cs.meta | 12 -- .../Scripts/Enemy/EnemyRotationHandler.cs | 12 +- .../Scripts/Enemy/EnemyStateCommon.cs | 54 ------- .../Scripts/Enemy/EnemyStateCommon.cs.meta | 12 -- .../Scripts/Enemy/EnemyStateFactory.cs | 68 -------- .../Scripts/Enemy/EnemyStateFactory.cs.meta | 12 -- .../Scripts/Enemy/EnemyStateManager.cs | 60 ++++--- .../Scripts/Enemy/EnemyTunables.cs | 10 -- .../Scripts/Enemy/GameEvents.cs | 4 +- .../Scripts/Enemy/States/EnemyStateAttack.cs | 36 +++-- .../Scripts/Enemy/States/EnemyStateFollow.cs | 35 +++-- .../Scripts/Enemy/States/EnemyStateIdle.cs | 55 ++----- .../Scripts/Enemy/States/EnemyStateRunAway.cs | 66 -------- .../Enemy/States/EnemyStateRunAway.cs.meta | 12 -- .../Scripts/Installers/EnemyInstaller.cs | 44 +----- .../Scripts/Installers/GameInstaller.cs | 10 +- .../Installers/GameSettingsInstaller.cs | 39 ++++- .../Scripts/Installers/PlayerInstaller.cs | 15 +- .../Scripts/Misc/Bullet.cs | 29 +++- .../Scripts/Misc/EnemySpawner.cs | 101 +++++++++--- .../Scripts/Misc/Explosion.cs | 2 - .../Scripts/Misc/GameDifficultyHandler.cs | 42 ----- .../Misc/GameDifficultyHandler.cs.meta | 12 -- .../Scripts/Misc/LevelBoundary.cs | 59 +++++++ .../LevelBoundary.cs.meta} | 4 +- .../Scripts/Player/PlayerBulletHitHandler.cs | 22 +-- .../Scripts/Player/PlayerCollisionDetector.cs | 27 ---- .../Player/PlayerCollisionDetector.cs.meta | 12 -- .../Scripts/Player/PlayerDirectionHandler.cs | 4 +- .../Scripts/Player/PlayerFacade.cs | 24 ++- .../Scripts/Player/PlayerHealthDisplay.cs | 2 +- .../Scripts/Player/PlayerHealthWatcher.cs | 17 +- .../Scripts/Player/PlayerInputEvents.cs.meta | 12 -- ...ayerInputEvents.cs => PlayerInputState.cs} | 0 .../Scripts/Player/PlayerInputState.cs.meta | 12 ++ .../Scripts/Player/PlayerModel.cs | 40 +---- .../Scripts/Player/PlayerMoveHandler.cs | 40 ++++- .../Scripts/Player/PlayerShootHandler.cs | 10 +- .../SampleGame2 (Advanced)/SpaceFighter.unity | 108 +------------ .../Zenject/Source/Util/PoolCleanupChecker.cs | 2 +- .../Zenject/Source/Zenject.csproj.user.meta | 8 + .../ProjectSettings/GraphicsSettings.asset | 2 +- 70 files changed, 898 insertions(+), 1228 deletions(-) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.mp3 create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.wav rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/{damage.mp3.meta => damage.wav.meta} (100%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.aiff rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/{laser.mp3.meta => explosion.aiff.meta} (86%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.mp3 delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser.mp3 create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser.wav rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/{explosion.mp3.meta => laser.wav.meta} (86%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser2.wav create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser2.wav.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/Enemy.cs rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/{EnemyHealthWatcher.cs.meta => Enemy.cs.meta} (76%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionDetector.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCommonSettings.cs rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/{EnemyCollisionDetector.cs.meta => EnemyCommonSettings.cs.meta} (76%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/{EnemyModel.cs.meta => EnemyDeathHandler.cs.meta} (76%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyModel.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRegistry.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRegistry.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateFactory.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateFactory.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateRunAway.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateRunAway.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameDifficultyHandler.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameDifficultyHandler.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/LevelBoundary.cs rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/{Enemy/EnemyCollisionHandler.cs.meta => Misc/LevelBoundary.cs.meta} (76%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputEvents.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/{PlayerInputEvents.cs => PlayerInputState.cs} (100%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputState.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset index b267145c7..59347d78c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Installers/GameSettingsInstaller.asset @@ -11,26 +11,69 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 1db4d8ab51ca4ad48844c113bfbd80fa, type: 3} m_Name: GameSettingsInstaller m_EditorClassIdentifier: - CameraHandler: - FollowSpeed: 0.05 EnemySpawner: SpeedMin: 30 SpeedMax: 100 AccuracyMin: 0 AccuracyMax: 1 - AttackDistanceMin: 13 - AttackDistanceMax: 17 - SpawnDistanceMin: 40 - SpawnDistanceMax: 80 - GameDifficultyHandler: - NumAttackingIncreaseRate: 0.025 - NumEnemiesIncreaseRate: 0.05 + NumEnemiesIncreaseRate: 0.06 + NumEnemiesStartAmount: 1.5 + MinDelayBetweenSpawns: 0.3 GameRestartHandler: RestartDelay: 3 - EnemyGlobalTunables: - NumAttacking: 2 - DesiredNumEnemies: 7 GameInstaller: EnemyFacadePrefab: {fileID: 158650, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - BulletPrefab: {fileID: 118180, guid: 4d22825d6393b964f90d550dd2acc50f, type: 2} + BulletPrefab: {fileID: 1211991173579106, guid: 4d22825d6393b964f90d550dd2acc50f, + type: 2} ExplosionPrefab: {fileID: 100002, guid: 93a60ba8e409947b1a0334537c8b38c8, type: 2} + Player: + PlayerMoveHandler: + BoundaryBuffer: 4 + BoundaryAdjustForce: 70 + MoveSpeed: 250 + SlowDownSpeed: 0.2 + PlayerShootHandler: + Laser: {fileID: 8300000, guid: 34c638d8d99ccfd44a261f13505ab317, type: 3} + LaserVolume: 0.7 + BulletLifetime: 1 + BulletSpeed: 130 + MaxShootInterval: 0.15 + BulletOffsetDistance: 2 + PlayerCollisionHandler: + HealthLoss: 15 + HitForce: 1000 + HitSound: {fileID: 8300000, guid: f9517356afb533a41b9e7cb6f155031e, type: 3} + HitSoundVolume: 1 + PlayerHealthWatcher: + DeathSound: {fileID: 8300000, guid: 9cb65eb2505fbf443ac876ba177374f9, type: 3} + DeathSoundVolume: 1 + Enemy: + DefaultSettings: + Accuracy: 1 + Speed: 25 + EnemyStateIdle: + Amplitude: 0.5 + Frequency: 4 + EnemyRotationHandler: + TurnSpeed: 10 + EnemyStateFollow: + StrafeMultiplier: 0.5 + StrafeChangeInterval: 0.8 + TeleportDistance: 80 + TeleportNewDistance: 40 + EnemyStateAttack: + ShootSound: {fileID: 8300000, guid: aa66f043685a31e4bb90d0b6128bc3e1, type: 3} + ShootSoundVolume: 0.8 + BulletLifetime: 5 + BulletSpeed: 30 + BulletOffsetDistance: 2 + ShootInterval: 0.4 + ErrorRangeTheta: 30 + AttackRangeBuffer: 8 + StrafeMultiplier: 0.5 + StrafeChangeInterval: 0.8 + EnemyHealthWatcher: + DeathSound: {fileID: 8300000, guid: 9cb65eb2505fbf443ac876ba177374f9, type: 3} + DeathSoundVolume: 0.5 + EnemyCommonSettings: + AttackDistance: 15 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat new file mode 100644 index 000000000..1113f908c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat @@ -0,0 +1,118 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: LaserSight + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MetallicGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _OcclusionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _BumpScale + second: 1 + - first: + name: _Cutoff + second: 0.5 + - first: + name: _DetailNormalMapScale + second: 1 + - first: + name: _DstBlend + second: 0 + - first: + name: _Glossiness + second: 0.5 + - first: + name: _InvFade + second: 1 + - first: + name: _Metallic + second: 0 + - first: + name: _Mode + second: 0 + - first: + name: _OcclusionStrength + second: 1 + - first: + name: _Parallax + second: 0.02 + - first: + name: _SrcBlend + second: 1 + - first: + name: _UVSec + second: 0 + - first: + name: _ZWrite + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 0.7352941, g: 0, b: 0, a: 1} + - first: + name: _EmissionColor + second: {r: 0, g: 0, b: 0, a: 1} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat.meta new file mode 100644 index 000000000..ce76e4219 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ff629f1f83352ae4a88e72f9cefa2770 +timeCreated: 1456628383 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Bullet.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Bullet.prefab index 61398de77..e787511ad 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Bullet.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Bullet.prefab @@ -1,103 +1,42 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: ---- !u!1 &118180 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 - m_Component: - - 4: {fileID: 446406} - - 33: {fileID: 3365334} - - 65: {fileID: 6517372} - - 23: {fileID: 2318970} - - 114: {fileID: 11481176} - - 54: {fileID: 5465176} - m_Layer: 0 - m_Name: Bullet - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &446406 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 118180} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -1.474, y: 1.83, z: 0} - m_LocalScale: {x: 1.9560189, y: 0.13736466, z: 0.31226227} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 --- !u!23 &2318970 MeshRenderer: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 118180} + m_GameObject: {fileID: 1211991173579106} m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 1 - m_ReflectionProbeUsage: 1 m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 m_SortingOrder: 0 ---- !u!33 &3365334 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 118180} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!54 &5465176 -Rigidbody: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 118180} - serializedVersion: 2 - m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 - m_UseGravity: 0 - m_IsKinematic: 0 - m_Interpolate: 0 - m_Constraints: 40 - m_CollisionDetection: 0 ---- !u!65 &6517372 -BoxCollider: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 118180} - m_Material: {fileID: 0} - m_IsTrigger: 1 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} --- !u!114 &11481176 MonoBehaviour: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 118180} + m_GameObject: {fileID: 1211991173579106} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 4bcfdc0e00dba5645b88ed3608c61161, type: 3} @@ -123,5 +62,56 @@ Prefab: objectReference: {fileID: 0} m_RemovedComponents: [] m_ParentPrefab: {fileID: 0} - m_RootGameObject: {fileID: 118180} + m_RootGameObject: {fileID: 1211991173579106} m_IsPrefabParent: 1 +--- !u!1 &1211991173579106 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4081474240255722} + - component: {fileID: 33606203387721046} + - component: {fileID: 65837712711271418} + - component: {fileID: 2318970} + - component: {fileID: 11481176} + m_Layer: 0 + m_Name: Bullet + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4081474240255722 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1211991173579106} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -1.3316879, y: 1.6117618, z: -0.07171571} + m_LocalScale: {x: 2, y: 0.25, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &33606203387721046 +MeshFilter: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1211991173579106} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!65 &65837712711271418 +BoxCollider: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1211991173579106} + m_Material: {fileID: 0} + m_IsTrigger: 1 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Enemy.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Enemy.prefab index ee881be7d..12dd1f9ff 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Enemy.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Enemy.prefab @@ -5,17 +5,16 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 463158} - - 114: {fileID: 11469920} - - 114: {fileID: 11462742} - - 114: {fileID: 11412842} - - 33: {fileID: 3388348} - - 23: {fileID: 2329700} - - 54: {fileID: 5458816} - - 65: {fileID: 6529106} - - 114: {fileID: 11414686} + - component: {fileID: 463158} + - component: {fileID: 11469920} + - component: {fileID: 11462742} + - component: {fileID: 11412842} + - component: {fileID: 3388348} + - component: {fileID: 2329700} + - component: {fileID: 5458816} + - component: {fileID: 6529106} m_Layer: 8 m_Name: Enemy m_TagString: Untagged @@ -28,10 +27,10 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 471460} - - 114: {fileID: 11453994} + - component: {fileID: 471460} + - component: {fileID: 11453994} m_Layer: 8 m_Name: Installer m_TagString: Untagged @@ -47,11 +46,12 @@ Transform: m_GameObject: {fileID: 158650} m_LocalRotation: {x: 0, y: 0, z: 0.39402217, w: 0.91910094} m_LocalPosition: {x: 41.7, y: 4.7, z: 0} - m_LocalScale: {x: 0.79406416, y: 0.794064, z: 0.79406404} + m_LocalScale: {x: 1.3, y: 1.3, z: 1.3} m_Children: - {fileID: 471460} m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &471460 Transform: m_ObjectHideFlags: 1 @@ -64,6 +64,7 @@ Transform: m_Children: [] m_Father: {fileID: 463158} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &2329700 MeshRenderer: m_ObjectHideFlags: 1 @@ -73,17 +74,22 @@ MeshRenderer: m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 2100000, guid: 50755dee91b8d2142a777c6b00ad6923, type: 2} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 1 - m_ReflectionProbeUsage: 1 m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 @@ -138,19 +144,8 @@ MonoBehaviour: _components: - {fileID: 11462742} _identifier: - _compositionRoot: {fileID: 0} + _context: {fileID: 0} _bindType: 0 ---- !u!114 &11414686 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 158650} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3229cbdaa20864545965fa8b687edbcb, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!114 &11453994 MonoBehaviour: m_ObjectHideFlags: 1 @@ -167,37 +162,6 @@ MonoBehaviour: Rigidbody: {fileID: 5458816} Collider: {fileID: 6529106} Renderer: {fileID: 2329700} - DefaultSettings: - Accuracy: 1 - Speed: 25 - AttackDistance: 25 - EnemyCollisionHandler: - HealthLoss: 55 - HitForce: 500 - HitSound: {fileID: 8300000, guid: d2509c8879c3e514485098af04449f3e, type: 3} - EnemyStateIdle: - Amplitude: 0.5 - Frequency: 4 - AttackDistance: 20 - WaitTime: 5 - EnemyStateRunAway: - SafeDistance: 80 - EnemyRotationHandler: - TurnSpeed: 10 - EnemyStateFollow: - StrafeMultiplier: 0.5 - StrafeChangeInterval: 0.8 - TeleportDistance: 80 - TeleportNewDistance: 40 - EnemyStateAttack: - BulletLifetime: 5 - BulletSpeed: 30 - BulletOffsetDistance: 2 - ShootInterval: 0.4 - ErrorRangeTheta: 30 - AttackRangeBuffer: 8 - StrafeMultiplier: 0.5 - StrafeChangeInterval: 0.8 --- !u!114 &11462742 MonoBehaviour: m_ObjectHideFlags: 1 @@ -224,7 +188,7 @@ MonoBehaviour: - {fileID: 11453994} _installerPrefabs: [] _scriptableObjectInstallers: [] - _facade: {fileID: 0} + _kernel: {fileID: 0} --- !u!1001 &100100000 Prefab: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.mp3 b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.mp3 deleted file mode 100644 index 0e0c9a104abaed5c3e9ba36f58979017b5366e9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14839 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 W!5@l0_@B=w|HkJ(@&CWU|Nj7qO;OkY diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.wav b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.wav new file mode 100644 index 0000000000000000000000000000000000000000..7825700a0c301ae7918fdf067f7e5cfca02fdd06 GIT binary patch literal 12408 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 Nekbrdf&cFW{s%>83UmMf literal 0 HcmV?d00001 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.mp3.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.wav.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.mp3.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/damage.wav.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.aiff b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.aiff new file mode 100644 index 0000000000000000000000000000000000000000..5e1febcb7d7e8ec2ab7d651bd8e4981e2dd697b8 GIT binary patch literal 95372 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

X>ATa{O3zAfr{+%0 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 NC_lN~DQ*0T{Xh67i75a8 literal 0 HcmV?d00001 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser.mp3.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.aiff.meta similarity index 86% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser.mp3.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.aiff.meta index 662d220fe..d8eafc78e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser.mp3.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.aiff.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: d2509c8879c3e514485098af04449f3e -timeCreated: 1456615202 +guid: 9cb65eb2505fbf443ac876ba177374f9 +timeCreated: 1484707267 licenseType: Free AudioImporter: serializedVersion: 6 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.mp3 b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/explosion.mp3 deleted file mode 100644 index bc397a67e5d53a97a6dc1ebe572cdfa75541f8fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79992 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
_0;-5Vc}q5!k9&S;L`{Nc)EhCsRdqCGzgaY1 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 W_2sT#X)%?ux&N{LrS$*lVgCc(p%XO# diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser.wav b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Sounds/laser.wav new file mode 100644 index 0000000000000000000000000000000000000000..6873309bda696d70d4be94daffd0c707b645fe4f GIT binary patch literal 368172 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 z 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≠ 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%0AN3u+&_lBI<61FGqx7R@F=4~>tZxE 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 - - if (bullet != null && bullet.Type != BulletTypes.FromEnemy) - { - _gameEvents.EnemyHit(_enemy, bullet); - } - } - } -} - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs deleted file mode 100644 index e82ea5405..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using UnityEngine; -using Zenject; - -namespace Zenject.SpaceFighter -{ - public class EnemyCollisionHandler : IInitializable, IDisposable - { - readonly AudioPlayer _audioPlayer; - readonly Settings _settings; - readonly EnemyModel _model; - - GameEvents _gameEvents; - - public EnemyCollisionHandler( - EnemyModel model, - Settings settings, - AudioPlayer audioPlayer, - GameEvents gameEvents) - { - _gameEvents = gameEvents; - _audioPlayer = audioPlayer; - _settings = settings; - _model = model; - } - - public void Initialize() - { - _gameEvents.EnemyHit += OnHit; - } - - public void Dispose() - { - _gameEvents.EnemyHit -= OnHit; - } - - void OnHit(EnemyModel enemy, Bullet bullet) - { - if (enemy != _model) - { - return; - } - - _audioPlayer.Play(_settings.HitSound); - _model.AddForce(-bullet.MoveDirection * _settings.HitForce); - _model.TakeDamage(_settings.HealthLoss); - - bullet.Despawn(); - } - - [Serializable] - public class Settings - { - public float HealthLoss; - public float HitForce; - public AudioClip HitSound; - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCommonSettings.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCommonSettings.cs new file mode 100644 index 000000000..401a6ca0c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCommonSettings.cs @@ -0,0 +1,10 @@ +using System; + +namespace Zenject.SpaceFighter +{ + [Serializable] + public class EnemyCommonSettings + { + public float AttackDistance = 15.0f; + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionDetector.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCommonSettings.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionDetector.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCommonSettings.cs.meta index b9caff659..01e665858 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionDetector.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCommonSettings.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 3229cbdaa20864545965fa8b687edbcb -timeCreated: 1457197635 +guid: 28bfa2b5275427041ae8782a2fa41625 +timeCreated: 1484712200 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs new file mode 100644 index 000000000..57cdae37b --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs @@ -0,0 +1,47 @@ +using System; +using UnityEngine; +using Zenject; + +namespace Zenject.SpaceFighter +{ + public class EnemyDeathHandler + { + readonly GameEvents _gameEvents; + readonly Settings _settings; + readonly Explosion.Factory _explosionFactory; + readonly AudioPlayer _audioPlayer; + readonly Enemy _enemy; + + public EnemyDeathHandler( + Enemy enemy, + AudioPlayer audioPlayer, + Explosion.Factory explosionFactory, + Settings settings, + GameEvents gameEvents) + { + _gameEvents = gameEvents; + _settings = settings; + _explosionFactory = explosionFactory; + _audioPlayer = audioPlayer; + _enemy = enemy; + } + + public void Die() + { + var explosion = _explosionFactory.Spawn(); + explosion.transform.position = _enemy.Position; + + _audioPlayer.Play(_settings.DeathSound, _settings.DeathSoundVolume); + + _gameEvents.EnemyKilled(); + } + + [Serializable] + public class Settings + { + public AudioClip DeathSound; + public float DeathSoundVolume = 1.0f; + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyModel.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyModel.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs.meta index 62a6b0bb9..ce905c20e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyModel.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: aba86cce7fb204c4b8cd625086875503 -timeCreated: 1456617036 +guid: 3e69d618f7492e1408cd595325667663 +timeCreated: 1484711332 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs index 4eac0772f..4aa5d5db9 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs @@ -4,58 +4,57 @@ namespace Zenject.SpaceFighter { - public class EnemyFacade : MonoBehaviour + public class EnemyFacade : MonoBehaviour, IPoolable { - EnemyModel _model; - EnemyRegistry _enemyRegistry; - EnemyStateManager _stateManager; + Enemy _enemy; + EnemyTunables _tunables; + Factory _selfFactory; + EnemyDeathHandler _deathHandler; // We can't use a constructor here because MonoFacade derives from // MonoBehaviour [Inject] public void Construct( - EnemyModel model, EnemyRegistry registry, EnemyStateManager stateManager) + Enemy enemy, EnemyTunables tunables, + Factory selfFactory, EnemyDeathHandler deathHandler) { - _model = model; - _enemyRegistry = registry; - _stateManager = stateManager; - - registry.AddEnemy(this); + _enemy = enemy; + _tunables = tunables; + _selfFactory = selfFactory; + _deathHandler = deathHandler; } // Here we can add some high-level methods to give some info to other // parts of the codebase outside of our enemy facade - public bool IsAttacking + public Vector3 Position { - get - { - return _stateManager.CurrentState == EnemyStates.Attack; - } + get { return _enemy.Position; } + set { _enemy.Position = value; } } - public bool IsChasing + public void OnDespawned() { - get - { - return _stateManager.CurrentState == EnemyStates.Follow; - } + gameObject.SetActive(false); } - public Vector3 Position + public void Update() { - get - { - return _model.Position; - } - set - { - _model.Position = value; - } + // Always ensure we are on the main plane + _enemy.Position = new Vector3(_enemy.Position.x, _enemy.Position.y, 0); + } + + public void OnSpawned(EnemyTunables tunables) + { + _tunables.Accuracy = tunables.Accuracy; + _tunables.Speed = tunables.Speed; + + gameObject.SetActive(true); } - public void OnDestroy() + public void Die() { - _enemyRegistry.RemoveEnemy(this); + _deathHandler.Die(); + _selfFactory.Despawn(this); } // Here we declare a parameter to our facade factory of type EnemyTunables @@ -63,7 +62,7 @@ public void OnDestroy() // an installer instead of the EnemyFacade class itself // It's done this way because in some cases we want to add the arguments // to the container for use by other classes within the facade - public class Factory : Factory + public class Factory : PooledFactory { } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs deleted file mode 100644 index 2540f897f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyHealthWatcher.cs +++ /dev/null @@ -1,43 +0,0 @@ -using UnityEngine; -using Zenject; - -namespace Zenject.SpaceFighter -{ - public class EnemyHealthWatcher : ITickable - { - readonly GameEvents _gameEvents; - readonly Explosion.Factory _explosionFactory; - readonly Context _context; - readonly EnemyModel _model; - - public EnemyHealthWatcher( - EnemyModel model, - Context context, - Explosion.Factory explosionFactory, - GameEvents gameEvents) - { - _gameEvents = gameEvents; - _explosionFactory = explosionFactory; - _context = context; - _model = model; - } - - public void Tick() - { - if (_model.Health <= 0) - { - Die(); - } - } - - void Die() - { - var explosion = _explosionFactory.Spawn(); - explosion.transform.position = _model.Position; - - GameObject.Destroy(_context.gameObject); - - _gameEvents.EnemyKilled(_model); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyModel.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyModel.cs deleted file mode 100644 index 4ebe81b07..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyModel.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using UnityEngine; - -namespace Zenject.SpaceFighter -{ - public class EnemyModel - { - readonly float _speed; - readonly MeshRenderer _renderer; - readonly Collider _collider; - readonly Rigidbody _rigidBody; - - float _health = 100.0f; - - public EnemyModel( - Rigidbody rigidBody, - Collider collider, - MeshRenderer renderer, - EnemyTunables tunables) - { - _speed = tunables.Speed; - _renderer = renderer; - _collider = collider; - _rigidBody = rigidBody; - } - - public Vector3 LookDir - { - get - { - return -_rigidBody.transform.right; - } - } - - public Vector3 DesiredLookDir - { - get; - set; - } - - public float MoveSpeed - { - get - { - return _speed; - } - } - - public Vector3 RightDir - { - get - { - return _rigidBody.transform.up; - } - } - - public Vector3 ForwardDir - { - get - { - return _rigidBody.transform.right; - } - } - - public float Health - { - get - { - return _health; - } - } - - public Vector3 Position - { - get - { - return _rigidBody.transform.position; - } - set - { - _rigidBody.transform.position = value; - } - } - - public Quaternion Rotation - { - get - { - return _rigidBody.rotation; - } - set - { - _rigidBody.rotation = value; - } - } - - public Vector3 Velocity - { - get - { - return _rigidBody.velocity; - } - } - - public Collider Collider - { - get - { - return _collider; - } - } - - public MeshRenderer Renderer - { - get - { - return _renderer; - } - } - - public Vector3 AngularVelocity - { - get - { - return _rigidBody.angularVelocity; - } - set - { - _rigidBody.angularVelocity = value; - } - } - - public void AddForce(Vector3 force) - { - _rigidBody.AddForce(force); - } - - public void AddTorque(float value) - { - _rigidBody.AddTorque(Vector3.forward * value); - } - - public void TakeDamage(float healthLoss) - { - _health -= healthLoss; - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRegistry.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRegistry.cs deleted file mode 100644 index bfcc31836..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRegistry.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; - -namespace Zenject.SpaceFighter -{ - public class EnemyRegistry - { - readonly List _enemies = new List(); - - public IEnumerable Enemies - { - get - { - return _enemies; - } - } - - public int NumEnemies - { - get - { - return _enemies.Count; - } - } - - public void AddEnemy(EnemyFacade facade) - { - _enemies.Add(facade); - } - - public void RemoveEnemy(EnemyFacade facade) - { - _enemies.Remove(facade); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRegistry.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRegistry.cs.meta deleted file mode 100644 index 55d57681f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRegistry.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 15435c63d52db77468028f6e00c65ed7 -timeCreated: 1456668446 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRotationHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRotationHandler.cs index ec34930cb..2d18b4208 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRotationHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyRotationHandler.cs @@ -10,20 +10,20 @@ namespace Zenject.SpaceFighter public class EnemyRotationHandler : IFixedTickable { readonly Settings _settings; - readonly EnemyModel _model; + readonly Enemy _enemy; public EnemyRotationHandler( - EnemyModel model, + Enemy enemy, Settings settings) { _settings = settings; - _model = model; + _enemy = enemy; } public void FixedTick() { - var lookDir = _model.LookDir; - var goalDir = _model.DesiredLookDir; + var lookDir = _enemy.LookDir; + var goalDir = _enemy.DesiredLookDir; var error = Vector3.Angle(lookDir, goalDir); @@ -32,7 +32,7 @@ public void FixedTick() error *= -1; } - _model.AddTorque(error * _settings.TurnSpeed); + _enemy.AddTorque(error * _settings.TurnSpeed); } [Serializable] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs deleted file mode 100644 index 36bb88b39..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using UnityEngine; -using Zenject; - -namespace Zenject.SpaceFighter -{ - // Any behaviour that is common regardless of what state the enemy is in - // goes here - public class EnemyStateCommon : IInitializable, IDisposable, ITickable - { - readonly EnemyModel _model; - readonly EnemyStateManager _stateManager; - - GameEvents _gameEvents; - - public EnemyStateCommon( - GameEvents gameEvents, - EnemyStateManager stateManager, - EnemyModel model) - { - _model = model; - _stateManager = stateManager; - _gameEvents = gameEvents; - } - - public void Initialize() - { - _gameEvents.EnemyHit += OnHit; - } - - public void Dispose() - { - _gameEvents.EnemyHit -= OnHit; - } - - public void Tick() - { - // Always ensure we are on the main plane - _model.Position = new Vector3(_model.Position.x, _model.Position.y, 0); - } - - void OnHit(EnemyModel model, Bullet bullet) - { - if (model != _model) - { - return; - } - - // Run away to fight another day - _stateManager.ChangeState(EnemyStates.RunAway); - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs.meta deleted file mode 100644 index 28a43fc23..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateCommon.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4e5725c274db63448bda1746c233df26 -timeCreated: 1457195017 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateFactory.cs deleted file mode 100644 index f0db6e06d..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateFactory.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Collections.Generic; -using ModestTree.Util; -using UnityEngine; -using Zenject; -using System.Linq; -using ModestTree; - -namespace Zenject.SpaceFighter -{ - public enum EnemyStates - { - None, - Idle, - RunAway, - Attack, - Follow, - Dead, - } - - public class EnemyStateFactory : IValidatable - { - readonly DiContainer _container; - - public EnemyStateFactory(DiContainer container) - { - _container = container; - } - - public IEnemyState Create(EnemyStates state) - { - switch (state) - { - case EnemyStates.Idle: - { - return _container.Instantiate(); - } - case EnemyStates.RunAway: - { - return _container.Instantiate(); - } - case EnemyStates.Attack: - { - return _container.Instantiate(); - } - case EnemyStates.Follow: - { - return _container.Instantiate(); - } - } - - throw Assert.CreateException(); - } - - // If we were using a factory then we wouldn't need to do this - // However, since we are instantiating these classes directly - // we need to (if we care enough about validating the state classes) - public void Validate() - { - // Validation is only called in unity editor when user presses CTRL+SHIFT+V - Assert.That(Application.isEditor); - - foreach (var state in new [] { EnemyStates.Idle, EnemyStates.RunAway, EnemyStates.Attack, EnemyStates.Follow }) - { - Create(state); - } - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateFactory.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateFactory.cs.meta deleted file mode 100644 index 26420f8bf..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateFactory.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: dad7e030d3dca4a48adb3786a613e4c5 -timeCreated: 1456619466 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateManager.cs index 9e099adbc..84c895538 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyStateManager.cs @@ -1,48 +1,60 @@ -using System; -using Zenject; +using System.Collections.Generic; using ModestTree; +using Zenject; namespace Zenject.SpaceFighter { - public interface IEnemyState : IDisposable + public interface IEnemyState { - void Initialize(); + void EnterState(); + void ExitState(); void Update(); void FixedUpdate(); } + public enum EnemyStates + { + Idle, + Attack, + Follow, + None, + } + // This class controls the basic "AI" of our enemy - // Which works as a finite state machine, between four states: + // Which works as a finite state machine, between three states: // - Attack // - Follow/Chase // - Idle - // - RunAway public class EnemyStateManager : ITickable, IFixedTickable, IInitializable { - readonly EnemyStateFactory _stateFactory; - - IEnemyState _stateHandler; + IEnemyState _currentStateHandler; EnemyStates _currentState = EnemyStates.None; - public EnemyStateManager(EnemyStateFactory stateFactory) + List _states; + + // We can't use a constructor due to a circular dependency issue + [Inject] + public void Construct( + EnemyStateIdle idle, EnemyStateAttack attack, EnemyStateFollow follow) { - _stateFactory = stateFactory; + _states = new List() + { + // This needs to follow the enum order + idle, attack, follow + }; } public EnemyStates CurrentState { - get - { - return _currentState; - } + get { return _currentState; } } public void Initialize() { Assert.IsEqual(_currentState, EnemyStates.None); - Assert.IsNull(_stateHandler); + Assert.IsNull(_currentStateHandler); - ChangeState(EnemyStates.Idle); + ChangeState(EnemyStates.Follow); } public void ChangeState(EnemyStates state) @@ -57,24 +69,24 @@ public void ChangeState(EnemyStates state) _currentState = state; - if (_stateHandler != null) + if (_currentStateHandler != null) { - _stateHandler.Dispose(); - _stateHandler = null; + _currentStateHandler.ExitState(); + _currentStateHandler = null; } - _stateHandler = _stateFactory.Create(state); - _stateHandler.Initialize(); + _currentStateHandler = _states[(int)state]; + _currentStateHandler.EnterState(); } public void Tick() { - _stateHandler.Update(); + _currentStateHandler.Update(); } public void FixedTick() { - _stateHandler.FixedUpdate(); + _currentStateHandler.FixedUpdate(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyTunables.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyTunables.cs index 00119c876..4b0e3775a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyTunables.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyTunables.cs @@ -10,15 +10,5 @@ public class EnemyTunables { public float Accuracy; public float Speed; - public float AttackDistance; - } - - // These values are global and used to ramp up the difficulty of our game - // over time - [Serializable] - public class EnemyGlobalTunables - { - public int NumAttacking; - public int DesiredNumEnemies; } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs index 8bd03c306..b196df2e6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs @@ -4,9 +4,7 @@ namespace Zenject.SpaceFighter { public class GameEvents { - public Action EnemyHit = delegate {}; - public Action PlayerHit = delegate {}; public Action PlayerKilled = delegate {}; - public Action EnemyKilled = delegate {}; + public Action EnemyKilled = delegate {}; } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs index 4d196572c..6fd2d900b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using ModestTree; using UnityEngine; using Random = UnityEngine.Random; @@ -7,11 +8,13 @@ namespace Zenject.SpaceFighter { public class EnemyStateAttack : IEnemyState { + readonly EnemyCommonSettings _commonSettings; + readonly AudioPlayer _audioPlayer; readonly EnemyTunables _tunables; readonly EnemyStateManager _stateManager; readonly PlayerFacade _player; readonly Settings _settings; - readonly EnemyModel _model; + readonly Enemy _enemy; readonly Bullet.Factory _bulletFactory; float _lastShootTime; @@ -20,26 +23,30 @@ public class EnemyStateAttack : IEnemyState public EnemyStateAttack( Bullet.Factory bulletFactory, - EnemyModel model, + Enemy enemy, Settings settings, PlayerFacade player, EnemyStateManager stateManager, - EnemyTunables tunables) + EnemyTunables tunables, + AudioPlayer audioPlayer, + EnemyCommonSettings commonSettings) { + _commonSettings = commonSettings; + _audioPlayer = audioPlayer; _tunables = tunables; _stateManager = stateManager; _player = player; _settings = settings; - _model = model; + _enemy = enemy; _bulletFactory = bulletFactory; _strafeRight = Random.Range(0.0f, 1.0f) < 0.5f; } - public void Initialize() + public void EnterState() { } - public void Dispose() + public void ExitState() { } @@ -51,7 +58,7 @@ public void Update() return; } - _model.DesiredLookDir = (_player.Position - _model.Position).normalized; + _enemy.DesiredLookDir = (_player.Position - _enemy.Position).normalized; // Strafe back and forth over the given interval if (Time.realtimeSinceStartup - _lastStrafeChangeTime > _settings.StrafeChangeInterval) @@ -68,7 +75,7 @@ public void Update() } // If the player runs away then chase them - if ((_player.Position - _model.Position).magnitude > _tunables.AttackDistance + _settings.AttackRangeBuffer) + if ((_player.Position - _enemy.Position).magnitude > _commonSettings.AttackDistance + _settings.AttackRangeBuffer) { _stateManager.ChangeState(EnemyStates.Follow); } @@ -79,11 +86,11 @@ public void FixedUpdate() // Strafe to avoid getting hit too easily if (_strafeRight) { - _model.AddForce(_model.RightDir * _settings.StrafeMultiplier * _model.MoveSpeed); + _enemy.AddForce(_enemy.RightDir * _settings.StrafeMultiplier * _tunables.Speed); } else { - _model.AddForce(-_model.RightDir * _settings.StrafeMultiplier * _model.MoveSpeed); + _enemy.AddForce(-_enemy.RightDir * _settings.StrafeMultiplier * _tunables.Speed); } } @@ -104,13 +111,18 @@ void Fire() var thetaError = error * _settings.ErrorRangeTheta; - bullet.transform.position = _model.Position + _model.LookDir * _settings.BulletOffsetDistance; - bullet.transform.rotation = Quaternion.AngleAxis(thetaError, Vector3.forward) * _model.Rotation; + bullet.transform.position = _enemy.Position + _enemy.LookDir * _settings.BulletOffsetDistance; + bullet.transform.rotation = Quaternion.AngleAxis(thetaError, Vector3.forward) * _enemy.Rotation; + + _audioPlayer.Play(_settings.ShootSound, _settings.ShootSoundVolume); } [Serializable] public class Settings { + public AudioClip ShootSound; + public float ShootSoundVolume = 1.0f; + public float BulletLifetime; public float BulletSpeed; public float BulletOffsetDistance; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs index 54bfbe76d..a9dc30016 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs @@ -6,10 +6,11 @@ namespace Zenject.SpaceFighter { public class EnemyStateFollow : IEnemyState { + readonly EnemyCommonSettings _commonSettings; readonly Settings _settings; readonly EnemyTunables _tunables; readonly EnemyStateManager _stateManager; - readonly EnemyModel _model; + readonly Enemy _enemy; readonly PlayerFacade _player; bool _strafeRight; @@ -17,23 +18,27 @@ public class EnemyStateFollow : IEnemyState public EnemyStateFollow( PlayerFacade player, - EnemyModel model, + Enemy enemy, EnemyStateManager stateManager, EnemyTunables tunables, - Settings settings) + Settings settings, + EnemyCommonSettings commonSettings) { + _commonSettings = commonSettings; _settings = settings; _tunables = tunables; _stateManager = stateManager; - _model = model; + _enemy = enemy; _player = player; } - public void Initialize() + public void EnterState() { + _strafeRight = UnityEngine.Random.Range(0, 1) == 0; + _lastStrafeChangeTime = Time.realtimeSinceStartup; } - public void Dispose() + public void ExitState() { } @@ -45,7 +50,7 @@ public void Update() return; } - var distanceToPlayer = (_player.Position - _model.Position).magnitude; + var distanceToPlayer = (_player.Position - _enemy.Position).magnitude; Assert.That(_settings.TeleportDistance > _settings.TeleportNewDistance); @@ -54,12 +59,12 @@ public void Update() // and it gets boring if (distanceToPlayer > _settings.TeleportDistance) { - var playerDir = (_player.Position - _model.Position).normalized; - _model.Position = _player.Position + playerDir * _settings.TeleportNewDistance; + var playerDir = (_player.Position - _enemy.Position).normalized; + _enemy.Position = _player.Position + playerDir * _settings.TeleportNewDistance; } // Always look towards the player - _model.DesiredLookDir = (_player.Position - _model.Position).normalized; + _enemy.DesiredLookDir = (_player.Position - _enemy.Position).normalized; // Strafe back and forth over the given interval // This helps avoiding being too easy a target @@ -69,7 +74,7 @@ public void Update() _strafeRight = !_strafeRight; } - if (distanceToPlayer < _tunables.AttackDistance) + if (distanceToPlayer < _commonSettings.AttackDistance) { _stateManager.ChangeState(EnemyStates.Attack); } @@ -86,19 +91,19 @@ void Strafe() // Strafe to avoid getting hit too easily if (_strafeRight) { - _model.AddForce(_model.RightDir * _settings.StrafeMultiplier * _model.MoveSpeed); + _enemy.AddForce(_enemy.RightDir * _settings.StrafeMultiplier * _tunables.Speed); } else { - _model.AddForce(-_model.RightDir * _settings.StrafeMultiplier * _model.MoveSpeed); + _enemy.AddForce(-_enemy.RightDir * _settings.StrafeMultiplier * _tunables.Speed); } } void MoveTowardsPlayer() { - var playerDir = (_player.Position - _model.Position).normalized; + var playerDir = (_player.Position - _enemy.Position).normalized; - _model.AddForce(playerDir * _model.MoveSpeed); + _enemy.AddForce(playerDir * _tunables.Speed); } [Serializable] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateIdle.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateIdle.cs index 5d6506dd3..a14b07801 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateIdle.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateIdle.cs @@ -6,40 +6,28 @@ namespace Zenject.SpaceFighter { public class EnemyStateIdle : IEnemyState { - readonly EnemyGlobalTunables _globalTunables; - readonly PlayerFacade _player; - readonly EnemyRegistry _registry; - readonly EnemyStateManager _stateManager; readonly Settings _settings; - readonly EnemyModel _model; + readonly Enemy _enemy; Vector3 _startPos; float _theta; Vector3 _startLookDir; public EnemyStateIdle( - EnemyModel model, Settings settings, - EnemyStateManager stateManager, - EnemyRegistry registry, - PlayerFacade player, - EnemyGlobalTunables globalTunables) + Enemy enemy, Settings settings) { - _globalTunables = globalTunables; - _player = player; - _registry = registry; - _stateManager = stateManager; _settings = settings; - _model = model; + _enemy = enemy; } - public void Initialize() + public void EnterState() { - _startPos = _model.Position; - _theta = 0; - _startLookDir = _model.LookDir; + _startPos = _enemy.Position; + _theta = UnityEngine.Random.Range(0, 2.0f * Mathf.PI); + _startLookDir = _enemy.LookDir; } - public void Dispose() + public void ExitState() { } @@ -48,29 +36,8 @@ public void Update() { _theta += Time.deltaTime * _settings.Frequency; - _model.Position = _startPos + _model.RightDir * _settings.Amplitude * Mathf.Sin(_theta); - - if (_player.IsDead) - { - _model.DesiredLookDir = _startLookDir; - } - else - { - // look away from player - _model.DesiredLookDir = -(_player.Position - _model.Position).normalized; - } - - if (!_player.IsDead) - { - if (_registry.Enemies.Where(x => x.IsAttacking || x.IsChasing).Count() < _globalTunables.NumAttacking) - { - _stateManager.ChangeState(EnemyStates.Follow); - } - else if ((_player.Position - _model.Position).magnitude < _settings.AttackDistance) - { - _stateManager.ChangeState(EnemyStates.Attack); - } - } + _enemy.Position = _startPos + _enemy.RightDir * _settings.Amplitude * Mathf.Sin(_theta); + _enemy.DesiredLookDir = _startLookDir; } public void FixedUpdate() @@ -82,8 +49,6 @@ public class Settings { public float Amplitude; public float Frequency; - public float AttackDistance; - public float WaitTime; } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateRunAway.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateRunAway.cs deleted file mode 100644 index 29303552c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateRunAway.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using UnityEngine; - -namespace Zenject.SpaceFighter -{ - public class EnemyStateRunAway : IEnemyState - { - readonly EnemyStateManager _stateManager; - readonly Settings _settings; - readonly EnemyModel _model; - readonly PlayerFacade _player; - - public EnemyStateRunAway( - PlayerFacade player, - EnemyModel model, - Settings settings, - EnemyStateManager stateManager) - { - _stateManager = stateManager; - _settings = settings; - _model = model; - _player = player; - } - - public void Initialize() - { - } - - public void Dispose() - { - } - - public void Update() - { - if (_player.IsDead) - { - _stateManager.ChangeState(EnemyStates.Idle); - return; - } - - // look away from player - _model.DesiredLookDir = -(_player.Position - _model.Position).normalized; - - if ((_player.Position - _model.Position).magnitude > _settings.SafeDistance) - { - _stateManager.ChangeState(EnemyStates.Idle); - } - } - - public void FixedUpdate() - { - MoveAwayFromPlayer(); - } - - void MoveAwayFromPlayer() - { - _model.AddForce(_model.LookDir * _model.MoveSpeed); - } - - [Serializable] - public class Settings - { - public float SafeDistance; - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateRunAway.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateRunAway.cs.meta deleted file mode 100644 index 1e52fb63f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateRunAway.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: bd27b9e12c466aa49a691a6ca23d8253 -timeCreated: 1456620041 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs index eab052cc1..53b218972 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs @@ -9,43 +9,21 @@ public class EnemyInstaller : MonoInstaller [SerializeField] Settings _settings = null; - [InjectOptional] - EnemyTunables _settingsOverride = null; - public override void InstallBindings() { - // Doing it this way allows us to drop enemies into the scene and set these settings - // directly but also allow creating enemies dynamically and injecting these settings instead - Container.BindInstance(_settingsOverride != null ? _settingsOverride : _settings.DefaultSettings); - - Container.BindInstance(_settings.Rigidbody).WhenInjectedInto(); - Container.BindInstance(_settings.Collider).WhenInjectedInto(); - Container.BindInstance(_settings.Renderer).WhenInjectedInto(); - - Container.Bind().AsSingle(); + Container.Bind().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); + Container.Bind().AsSingle() + .WithArguments(_settings.Renderer, _settings.Collider, _settings.Rigidbody); Container.BindAllInterfacesAndSelf().To().AsSingle(); - Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); - - Container.BindAllInterfaces().To().AsSingle(); + Container.BindAllInterfacesAndSelf().To().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); - - InstallSettings(); - } - - void InstallSettings() - { - Container.BindInstance(_settings.EnemyCollisionHandler); - Container.BindInstance(_settings.EnemyStateIdle); - Container.BindInstance(_settings.EnemyStateRunAway); - Container.BindInstance(_settings.EnemyRotationHandler); - Container.BindInstance(_settings.EnemyStateFollow); - Container.BindInstance(_settings.EnemyStateAttack); } [Serializable] @@ -55,14 +33,6 @@ public class Settings public Rigidbody Rigidbody; public Collider Collider; public MeshRenderer Renderer; - - public EnemyTunables DefaultSettings; - public EnemyCollisionHandler.Settings EnemyCollisionHandler; - public EnemyStateIdle.Settings EnemyStateIdle; - public EnemyStateRunAway.Settings EnemyStateRunAway; - public EnemyRotationHandler.Settings EnemyRotationHandler; - public EnemyStateFollow.Settings EnemyStateFollow; - public EnemyStateAttack.Settings EnemyStateAttack; } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs index 4b21883e9..3691ab0ed 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs @@ -17,19 +17,17 @@ public override void InstallBindings() Container.BindAllInterfaces().To().AsSingle(); - Container.BindFactory() + Container.BindPooledFactory() .FromSubContainerResolve() - .ByPrefab(_settings.EnemyFacadePrefab) + .ByPrefab(_settings.EnemyFacadePrefab) .UnderTransformGroup("Enemies"); - Container.BindAllInterfaces().To().AsSingle(); - - Container.Bind().AsSingle(); - Container.BindPooledFactory().WithInitialSize(10).ExpandByDoubling() .FromPrefab(_settings.BulletPrefab) .UnderTransformGroup("Bullets"); + Container.Bind().AsSingle(); + Container.BindPooledFactory().WithInitialSize(3) .FromPrefab(_settings.ExplosionPrefab) .UnderTransformGroup("Explosions"); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs index 0e423455f..a17fbef1b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs @@ -24,18 +24,49 @@ namespace Zenject.SpaceFighter public class GameSettingsInstaller : ScriptableObjectInstaller { public EnemySpawner.Settings EnemySpawner; - public GameDifficultyHandler.Settings GameDifficultyHandler; public GameRestartHandler.Settings GameRestartHandler; - public EnemyGlobalTunables EnemyGlobalTunables; public GameInstaller.Settings GameInstaller; + public PlayerSettings Player; + public EnemySettings Enemy; + + [Serializable] + public class PlayerSettings + { + public PlayerMoveHandler.Settings PlayerMoveHandler; + public PlayerShootHandler.Settings PlayerShootHandler; + public PlayerBulletHitHandler.Settings PlayerCollisionHandler; + public PlayerHealthWatcher.Settings PlayerHealthWatcher; + } + + [Serializable] + public class EnemySettings + { + public EnemyTunables DefaultSettings; + public EnemyStateIdle.Settings EnemyStateIdle; + public EnemyRotationHandler.Settings EnemyRotationHandler; + public EnemyStateFollow.Settings EnemyStateFollow; + public EnemyStateAttack.Settings EnemyStateAttack; + public EnemyDeathHandler.Settings EnemyHealthWatcher; + public EnemyCommonSettings EnemyCommonSettings; + } public override void InstallBindings() { Container.BindInstance(EnemySpawner); - Container.BindInstance(GameDifficultyHandler); Container.BindInstance(GameRestartHandler); - Container.BindInstance(EnemyGlobalTunables); Container.BindInstance(GameInstaller); + + Container.BindInstance(Player.PlayerMoveHandler); + Container.BindInstance(Player.PlayerShootHandler); + Container.BindInstance(Player.PlayerCollisionHandler); + Container.BindInstance(Player.PlayerHealthWatcher); + + Container.BindInstance(Enemy.EnemyStateIdle); + Container.BindInstance(Enemy.EnemyRotationHandler); + Container.BindInstance(Enemy.EnemyStateFollow); + Container.BindInstance(Enemy.EnemyStateAttack); + Container.BindInstance(Enemy.EnemyHealthWatcher); + Container.BindInstance(Enemy.EnemyCommonSettings); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs index 68740ac2a..60ee1fde7 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs @@ -17,22 +17,13 @@ public override void InstallBindings() Container.BindAllInterfaces().To().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); + Container.BindAllInterfacesAndSelf().To().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); Container.Bind().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); - - InstallSettings(); - } - - void InstallSettings() - { - Container.BindInstance(_settings.PlayerMoveHandler); - Container.BindInstance(_settings.PlayerShootHandler); - Container.BindInstance(_settings.PlayerCollisionHandler); } [Serializable] @@ -40,10 +31,6 @@ public class Settings { public Rigidbody Rigidbody; public MeshRenderer MeshRenderer; - - public PlayerMoveHandler.Settings PlayerMoveHandler; - public PlayerShootHandler.Settings PlayerShootHandler; - public PlayerBulletHitHandler.Settings PlayerCollisionHandler; } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs index 319e36996..2227f3a8a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs @@ -27,11 +27,13 @@ public class Bullet : MonoBehaviour, IPoolable Material _enemyMaterial = null; Factory _selfFactory; + GameEvents _gameEvents; [Inject] - void Construct(Factory selfFactory) + void Construct(Factory selfFactory, GameEvents gameEvents) { _selfFactory = selfFactory; + _gameEvents = gameEvents; } public void OnSpawned(float speed, float lifeTime, BulletTypes type) @@ -54,17 +56,30 @@ public void OnDespawned() public BulletTypes Type { - get - { - return _type; - } + get { return _type; } } public Vector3 MoveDirection { - get + get { return transform.right; } + } + + public void OnTriggerEnter(Collider other) + { + var enemy = other.GetComponent(); + + if (enemy != null && _type == BulletTypes.FromPlayer) + { + enemy.Die(); + this.Despawn(); + } + + var player = other.GetComponent(); + + if (player != null && _type == BulletTypes.FromEnemy) { - return transform.right; + player.TakeDamage(this.MoveDirection); + this.Despawn(); } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/EnemySpawner.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/EnemySpawner.cs index 90bafc2c0..3dc6d7427 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/EnemySpawner.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/EnemySpawner.cs @@ -1,59 +1,113 @@ using System; +using ModestTree; +using ModestTree.Util; using UnityEngine; using Zenject; using Random = UnityEngine.Random; namespace Zenject.SpaceFighter { - public class EnemySpawner : ITickable + public class EnemySpawner : ITickable, IInitializable { - readonly EnemyGlobalTunables _globalTunables; - readonly EnemyRegistry _enemyRegistry; + readonly GameEvents _gameEvents; + readonly LevelBoundary _levelBoundary; readonly EnemyFacade.Factory _enemyFactory; readonly Settings _settings; - readonly PlayerFacade _player; + + float _desiredNumEnemies; + int _enemyCount; + float _lastSpawnTime; public EnemySpawner( - PlayerFacade player, Settings settings, EnemyFacade.Factory enemyFactory, - EnemyRegistry enemyRegistry, - EnemyGlobalTunables globalTunables) + LevelBoundary levelBoundary, + GameEvents gameEvents) { - _globalTunables = globalTunables; - _enemyRegistry = enemyRegistry; + _gameEvents = gameEvents; + _levelBoundary = levelBoundary; _enemyFactory = enemyFactory; _settings = settings; - _player = player; + + _desiredNumEnemies = settings.NumEnemiesStartAmount; + } + + public void Initialize() + { + _gameEvents.EnemyKilled += OnEnemyKilled; + } + + void OnEnemyKilled() + { + _enemyCount--; } public void Tick() { - if (_enemyRegistry.NumEnemies < _globalTunables.DesiredNumEnemies) + _desiredNumEnemies += _settings.NumEnemiesIncreaseRate * Time.deltaTime; + + if (_enemyCount < (int)_desiredNumEnemies + && Time.realtimeSinceStartup - _lastSpawnTime > _settings.MinDelayBetweenSpawns) { SpawnEnemy(); + _enemyCount++; } } void SpawnEnemy() { - var settings = new EnemyTunables() + var tunables = new EnemyTunables() { Speed = Random.Range(_settings.SpeedMin, _settings.SpeedMax), Accuracy = Random.Range(_settings.AccuracyMin, _settings.AccuracyMax), - AttackDistance = Random.Range(_settings.AttackDistanceMin, _settings.AttackDistanceMax), }; - var enemyFacade = _enemyFactory.Create(settings); + var enemyFacade = _enemyFactory.Spawn(tunables); + enemyFacade.Position = ChooseRandomStartPosition(); + + _lastSpawnTime = Time.realtimeSinceStartup; + } - // Spawn from a random direction - var startTheta = Random.Range(0, 2 * Mathf.PI); + Vector3 ChooseRandomStartPosition() + { + var side = Random.Range(0, 3); + var posOnSide = Random.Range(0, 1.0f); - var spawnDistance = Random.Range(_settings.SpawnDistanceMin, _settings.SpawnDistanceMax); + float buffer = 2.0f; + + switch (side) + { + case 0: + // top + { + return new Vector3( + _levelBoundary.Left + posOnSide * _levelBoundary.Width, + _levelBoundary.Top + buffer, 0); + } + case 1: + // right + { + return new Vector3( + _levelBoundary.Right + buffer, + _levelBoundary.Top - posOnSide * _levelBoundary.Height, 0); + } + case 2: + // bottom + { + return new Vector3( + _levelBoundary.Left + posOnSide * _levelBoundary.Width, + _levelBoundary.Bottom - buffer, 0); + } + case 3: + // left + { + return new Vector3( + _levelBoundary.Left - buffer, + _levelBoundary.Top - posOnSide * _levelBoundary.Height, 0); + } + } - enemyFacade.Position = _player.Position - + Vector3.right * spawnDistance * Mathf.Cos(startTheta) - + Vector3.up * spawnDistance * Mathf.Sin(startTheta); + throw Assert.CreateException(); } [Serializable] @@ -65,11 +119,10 @@ public class Settings public float AccuracyMin; public float AccuracyMax; - public float AttackDistanceMin; - public float AttackDistanceMax; + public float NumEnemiesIncreaseRate; + public float NumEnemiesStartAmount; - public float SpawnDistanceMin; - public float SpawnDistanceMax; + public float MinDelayBetweenSpawns = 0.5f; } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs index e10d136f0..b30d93e22 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs @@ -40,8 +40,6 @@ public void OnSpawned() _particleSystem.Play(); _startTime = Time.realtimeSinceStartup; - - _audioPlayer.Play(_sound, _soundVolume); } public void OnDespawned() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameDifficultyHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameDifficultyHandler.cs deleted file mode 100644 index 130d38bba..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameDifficultyHandler.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using UnityEngine; -using Zenject; - -namespace Zenject.SpaceFighter -{ - public class GameDifficultyHandler : ITickable - { - readonly Settings _settings; - readonly EnemyGlobalTunables _globalTunables; - - float _numAttacking; - float _numEnemies; - - public GameDifficultyHandler( - EnemyGlobalTunables globalTunables, - Settings settings) - { - _settings = settings; - _globalTunables = globalTunables; - - _numAttacking = globalTunables.NumAttacking; - _numEnemies = globalTunables.DesiredNumEnemies; - } - - public void Tick() - { - _numEnemies += _settings.NumEnemiesIncreaseRate * Time.deltaTime; - _numAttacking += _settings.NumAttackingIncreaseRate * Time.deltaTime; - - _globalTunables.DesiredNumEnemies = (int)_numEnemies; - _globalTunables.NumAttacking = (int)_numAttacking; - } - - [Serializable] - public class Settings - { - public float NumAttackingIncreaseRate; - public float NumEnemiesIncreaseRate; - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameDifficultyHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameDifficultyHandler.cs.meta deleted file mode 100644 index 1fa2ffa04..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameDifficultyHandler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 31209e5043e6cd34db11ec00b77f1bba -timeCreated: 1456675331 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/LevelBoundary.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/LevelBoundary.cs new file mode 100644 index 000000000..dc822ff2d --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/LevelBoundary.cs @@ -0,0 +1,59 @@ +using System; +using UnityEngine; +using System.Collections; +using Zenject; +using Random=UnityEngine.Random; + +namespace Zenject.SpaceFighter +{ + public class LevelBoundary + { + readonly Camera _camera; + + public LevelBoundary(Camera camera) + { + _camera = camera; + } + + public float Bottom + { + get { return -ExtentHeight; } + } + + public float Top + { + get { return ExtentHeight; } + } + + public float Left + { + get { return -ExtentWidth; } + } + + public float Right + { + get { return ExtentWidth; } + } + + public float ExtentHeight + { + get { return _camera.orthographicSize; } + } + + public float Height + { + get { return ExtentHeight * 2.0f; } + } + + public float ExtentWidth + { + get { return _camera.aspect * _camera.orthographicSize; } + } + + public float Width + { + get { return ExtentWidth * 2.0f; } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/LevelBoundary.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/LevelBoundary.cs.meta index eb485e5bf..643eac038 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyCollisionHandler.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/LevelBoundary.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 9d4346da381d5b245bf9701821e2315d -timeCreated: 1456421198 +guid: 6307c1ccd85f4f7478da6f3ec5a63996 +timeCreated: 1484693361 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs index 8afe2b6c8..84ca7a426 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs @@ -4,7 +4,7 @@ namespace Zenject.SpaceFighter { - public class PlayerBulletHitHandler : IInitializable, IDisposable + public class PlayerBulletHitHandler { readonly AudioPlayer _audioPlayer; readonly Settings _settings; @@ -24,24 +24,13 @@ public PlayerBulletHitHandler( _model = model; } - public void Initialize() + public void TakeDamage(Vector3 moveDirection) { - _gameEvents.PlayerHit += OnHit; - } + _audioPlayer.Play(_settings.HitSound, _settings.HitSoundVolume); - public void Dispose() - { - _gameEvents.PlayerHit -= OnHit; - } - - void OnHit(Bullet bullet) - { - _audioPlayer.Play(_settings.HitSound, _settings.HitVolume); - _model.AddForce(-bullet.MoveDirection * _settings.HitForce); + _model.AddForce(-moveDirection * _settings.HitForce); _model.TakeDamage(_settings.HealthLoss); - - bullet.Despawn(); } [Serializable] @@ -49,8 +38,9 @@ public class Settings { public float HealthLoss; public float HitForce; + public AudioClip HitSound; - public float HitVolume; + public float HitSoundVolume = 1.0f; } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs deleted file mode 100644 index 5311c4a8c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs +++ /dev/null @@ -1,27 +0,0 @@ -using UnityEngine; -using Zenject; - -namespace Zenject.SpaceFighter -{ - public class PlayerCollisionDetector : MonoBehaviour - { - GameEvents _gameEvents; - - [Inject] - public void Construct(GameEvents gameEvents) - { - _gameEvents = gameEvents; - } - - public void OnTriggerEnter(Collider other) - { - var bullet = other.GetComponent(); - - if (bullet != null && bullet.Type != BulletTypes.FromPlayer) - { - _gameEvents.PlayerHit(bullet); - } - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs.meta deleted file mode 100644 index ad8b01791..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerCollisionDetector.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 236c9a6d21ec53543bacb91e5ea84aa1 -timeCreated: 1456680240 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDirectionHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDirectionHandler.cs index 153f904f7..1633c9d1b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDirectionHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDirectionHandler.cs @@ -4,7 +4,7 @@ namespace Zenject.SpaceFighter { - public class PlayerDirectionHandler : ITickable + public class PlayerDirectionHandler : ILateTickable { readonly PlayerModel _player; readonly Camera _mainCamera; @@ -17,7 +17,7 @@ public PlayerDirectionHandler( _mainCamera = mainCamera; } - public void Tick() + public void LateTick() { var mouseRay = _mainCamera.ScreenPointToRay(Input.mousePosition); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerFacade.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerFacade.cs index 0945c73cd..539b0c373 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerFacade.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerFacade.cs @@ -6,35 +6,33 @@ namespace Zenject.SpaceFighter public class PlayerFacade : MonoBehaviour { PlayerModel _model; + PlayerBulletHitHandler _hitHandler; [Inject] - public void Construct(PlayerModel player) + public void Construct(PlayerModel player, PlayerBulletHitHandler hitHandler) { _model = player; + _hitHandler = hitHandler; } public bool IsDead { - get - { - return _model.IsDead; - } + get { return _model.IsDead; } } public Vector3 Position { - get - { - return _model.Position; - } + get { return _model.Position; } } public Quaternion Rotation { - get - { - return _model.Rotation; - } + get { return _model.Rotation; } + } + + public void TakeDamage(Vector3 moveDirection) + { + _hitHandler.TakeDamage(moveDirection); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs index 7f3145e49..c846303fc 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs @@ -51,7 +51,7 @@ public void Construct(PlayerModel model, GameEvents gameEvents) gameEvents.EnemyKilled += OnEnemyKilled; } - void OnEnemyKilled(EnemyModel enemy) + void OnEnemyKilled() { _killCount++; } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs index d41702611..94a3c07b8 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs @@ -6,6 +6,8 @@ namespace Zenject.SpaceFighter { public class PlayerHealthWatcher : ITickable { + readonly AudioPlayer _audioPlayer; + readonly Settings _settings; readonly GameEvents _gameEvents; readonly Explosion.Factory _explosionFactory; readonly PlayerModel _model; @@ -13,8 +15,12 @@ public class PlayerHealthWatcher : ITickable public PlayerHealthWatcher( PlayerModel model, Explosion.Factory explosionFactory, - GameEvents gameEvents) + GameEvents gameEvents, + Settings settings, + AudioPlayer audioPlayer) { + _audioPlayer = audioPlayer; + _settings = settings; _gameEvents = gameEvents; _explosionFactory = explosionFactory; _model = model; @@ -38,6 +44,15 @@ void Die() _model.Renderer.enabled = false; _gameEvents.PlayerKilled(); + + _audioPlayer.Play(_settings.DeathSound, _settings.DeathSoundVolume); + } + + [Serializable] + public class Settings + { + public AudioClip DeathSound; + public float DeathSoundVolume = 1.0f; } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputEvents.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputEvents.cs.meta deleted file mode 100644 index 288831340..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputEvents.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f57bdf0e20bfbd8439659c1bdb87e92f -timeCreated: 1456593836 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputEvents.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputState.cs similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputEvents.cs rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputState.cs diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputState.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputState.cs.meta new file mode 100644 index 000000000..f193ec30e --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerInputState.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9f9f53db91ff64e40af5b30b70927e13 +timeCreated: 1484693045 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerModel.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerModel.cs index 761e1e187..2d5b586f5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerModel.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerModel.cs @@ -19,10 +19,7 @@ public PlayerModel( public MeshRenderer Renderer { - get - { - return _renderer; - } + get { return _renderer; } } public bool IsDead @@ -33,50 +30,29 @@ public bool IsDead public float Health { - get - { - return _health; - } + get { return _health; } } public Vector3 LookDir { - get - { - return -_rigidBody.transform.right; - } + get { return -_rigidBody.transform.right; } } public Quaternion Rotation { - get - { - return _rigidBody.rotation; - } - set - { - _rigidBody.rotation = value; - } + get { return _rigidBody.rotation; } + set { _rigidBody.rotation = value; } } public Vector3 Position { - get - { - return _rigidBody.position; - } - set - { - _rigidBody.position = value; - } + get { return _rigidBody.position; } + set { _rigidBody.position = value; } } public Vector3 Velocity { - get - { - return _rigidBody.velocity; - } + get { return _rigidBody.velocity; } } public void TakeDamage(float healthLoss) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerMoveHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerMoveHandler.cs index 82df70236..0c024a40f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerMoveHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerMoveHandler.cs @@ -7,6 +7,7 @@ namespace Zenject.SpaceFighter { public class PlayerMoveHandler : IFixedTickable { + readonly LevelBoundary _levelBoundary; readonly Settings _settings; readonly PlayerModel _player; readonly PlayerInputState _inputState; @@ -14,8 +15,10 @@ public class PlayerMoveHandler : IFixedTickable public PlayerMoveHandler( PlayerInputState inputState, PlayerModel player, - Settings settings) + Settings settings, + LevelBoundary levelBoundary) { + _levelBoundary = levelBoundary; _settings = settings; _player = player; _inputState = inputState; @@ -54,11 +57,46 @@ public void FixedTick() // Always ensure we are on the main plane _player.Position = new Vector3(_player.Position.x, _player.Position.y, 0); + + KeepPlayerOnScreen(); + } + + void KeepPlayerOnScreen() + { + var extentLeft = (_levelBoundary.Left + _settings.BoundaryBuffer) - _player.Position.x; + var extentRight = _player.Position.x - (_levelBoundary.Right - _settings.BoundaryBuffer); + + if (extentLeft > 0) + { + _player.AddForce( + Vector3.right * _settings.BoundaryAdjustForce * extentLeft); + } + else if (extentRight > 0) + { + _player.AddForce( + Vector3.left * _settings.BoundaryAdjustForce * extentRight); + } + + var extentTop = _player.Position.y - (_levelBoundary.Top - _settings.BoundaryBuffer); + var extentBottom = (_levelBoundary.Bottom + _settings.BoundaryBuffer) - _player.Position.y; + + if (extentTop > 0) + { + _player.AddForce( + Vector3.down * _settings.BoundaryAdjustForce * extentTop); + } + else if (extentBottom > 0) + { + _player.AddForce( + Vector3.up * _settings.BoundaryAdjustForce * extentBottom); + } } [Serializable] public class Settings { + public float BoundaryBuffer; + public float BoundaryAdjustForce; public float MoveSpeed; public float SlowDownSpeed; } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs index 78231c96f..7573f30c2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs @@ -6,6 +6,7 @@ namespace Zenject.SpaceFighter { public class PlayerShootHandler : ITickable { + readonly AudioPlayer _audioPlayer; readonly PlayerModel _player; readonly Settings _settings; readonly Bullet.Factory _bulletFactory; @@ -17,8 +18,10 @@ public PlayerShootHandler( PlayerInputState inputState, Bullet.Factory bulletFactory, Settings settings, - PlayerModel player) + PlayerModel player, + AudioPlayer audioPlayer) { + _audioPlayer = audioPlayer; _player = player; _settings = settings; _bulletFactory = bulletFactory; @@ -41,6 +44,8 @@ public void Tick() void Fire() { + _audioPlayer.Play(_settings.Laser, _settings.LaserVolume); + var bullet = _bulletFactory.Spawn( _settings.BulletSpeed, _settings.BulletLifetime, BulletTypes.FromPlayer); @@ -51,6 +56,9 @@ void Fire() [Serializable] public class Settings { + public AudioClip Laser; + public float LaserVolume = 1.0f; + public float BulletLifetime; public float BulletSpeed; public float MaxShootInterval; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity index cf337144c..8b0e01f73 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity @@ -205,7 +205,7 @@ Transform: m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 414693287} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -1.0086417, y: 2.105907, z: -17.09} + m_LocalPosition: {x: 0, y: 0, z: -17.09} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} @@ -493,7 +493,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 5 + m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &724552920 GameObject: @@ -601,19 +601,6 @@ MonoBehaviour: _settings: Rigidbody: {fileID: 1303116749} MeshRenderer: {fileID: 1303116744} - PlayerMoveHandler: - MoveSpeed: 180 - SlowDownSpeed: 0.2 - PlayerShootHandler: - BulletLifetime: 2 - BulletSpeed: 50 - MaxShootInterval: 0.15 - BulletOffsetDistance: 2 - PlayerCollisionHandler: - HealthLoss: 15 - HitForce: 1000 - HitSound: {fileID: 8300000, guid: f9517356afb533a41b9e7cb6f155031e, type: 3} - HitVolume: 0.4 --- !u!1 &1034220754 GameObject: m_ObjectHideFlags: 0 @@ -663,10 +650,6 @@ MonoBehaviour: _killCountOffset: 30 _foregroundColor: {r: 1, g: 0.08823532, b: 0.08823532, a: 1} _backgroundColor: {r: 1, g: 1, b: 1, a: 1} ---- !u!4 &1177745373 stripped -Transform: - m_PrefabParentObject: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - m_PrefabInternal: {fileID: 1486646969} --- !u!1 &1303116742 GameObject: m_ObjectHideFlags: 0 @@ -682,7 +665,6 @@ GameObject: - component: {fileID: 1303116749} - component: {fileID: 1303116750} - component: {fileID: 1303116751} - - component: {fileID: 1303116748} m_Layer: 8 m_Name: Player m_TagString: Untagged @@ -697,7 +679,7 @@ Transform: m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 1303116742} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -1.38, y: 0, z: 0} + m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 855903056} @@ -771,17 +753,6 @@ MonoBehaviour: _installerPrefabs: [] _scriptableObjectInstallers: [] _kernel: {fileID: 0} ---- !u!114 &1303116748 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1303116742} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 236c9a6d21ec53543bacb91e5ea84aa1, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!54 &1303116749 Rigidbody: m_ObjectHideFlags: 0 @@ -824,77 +795,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 2db4310dd7706af419ae62fb99fac156, type: 3} m_Name: m_EditorClassIdentifier: ---- !u!1001 &1486646969 -Prefab: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - m_TransformParent: {fileID: 1911468625} - m_Modifications: - - target: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - propertyPath: m_LocalPosition.x - value: 41.7 - objectReference: {fileID: 0} - - target: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - propertyPath: m_LocalPosition.y - value: 4.7 - objectReference: {fileID: 0} - - target: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - propertyPath: m_LocalPosition.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - propertyPath: m_LocalRotation.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - propertyPath: m_LocalRotation.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - propertyPath: m_LocalRotation.z - value: 0.39402217 - objectReference: {fileID: 0} - - target: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - propertyPath: m_LocalRotation.w - value: 0.91910094 - objectReference: {fileID: 0} - - target: {fileID: 463158, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - propertyPath: m_RootOrder - value: 0 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_ParentPrefab: {fileID: 100100000, guid: 55f63c48150ecbb469e095dbde67c6e9, type: 2} - m_IsPrefabParent: 0 ---- !u!1 &1911468624 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 - m_Component: - - component: {fileID: 1911468625} - m_Layer: 0 - m_Name: Enemies - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1911468625 -Transform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 1911468624} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1177745373} - m_Father: {fileID: 0} - m_RootOrder: 4 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1920614870 GameObject: m_ObjectHideFlags: 0 @@ -937,5 +837,5 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 6 + m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs index 6438a45de..c8e49eab2 100644 --- a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs +++ b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs @@ -22,7 +22,7 @@ public void LateDispose() { foreach (var pool in _poolFactories) { - Assert.IsEqual(pool.NumActive, 0, + Assert.That(pool.NumActive == 0, "Found active objects in pool '{0}' during dispose. Did you forget to despawn an object of type '{1}'?", pool.GetType(), pool.ContractType); } } diff --git a/UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta b/UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta new file mode 100644 index 000000000..daad463e2 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ed8c2ea47adf5544d838e58584d5175c +timeCreated: 1484719217 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/ProjectSettings/GraphicsSettings.asset b/UnityProject/ProjectSettings/GraphicsSettings.asset index f15de1d44..7016a0e28 100644 --- a/UnityProject/ProjectSettings/GraphicsSettings.asset +++ b/UnityProject/ProjectSettings/GraphicsSettings.asset @@ -40,7 +40,7 @@ GraphicsSettings: type: 0} m_TierSettings_Tier1: renderingPath: 1 - useCascadedShadowMaps: 0 + useCascadedShadowMaps: 1 m_TierSettings_Tier2: renderingPath: 1 useCascadedShadowMaps: 1 From be48f78434a95adcf48dfcda3509bc4f0981ac0e Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 21 Jan 2017 23:17:23 -0400 Subject: [PATCH 20/62] - Updated the samples to be easier to understand - Fixed WithArguments bind method to support passing null values - Changed list bindings to default to optional so that you don't have to do this explicitly constantly - Added some more tests of using Lazy<>. Also fixed Lazy<> to validate properly --- .../SampleGame1 (Beginner)/Asteroids.unity | 2 +- .../{Resources => }/Installers.meta | 0 .../Installers/GameSettingsInstaller.asset | 4 +- .../GameSettingsInstaller.asset.meta | 0 .../SampleGame1 (Beginner)/Resources.meta | 9 - .../Scripts/Asteroid/Asteroid.cs | 44 +--- .../Scripts/Asteroid/AsteroidManager.cs | 9 +- .../Editor/Tests/TestAsteroidManager.cs | 2 +- .../Installers/GameDecoratorInstaller.cs | 42 ---- .../Scripts/Installers/GameInstaller.cs | 9 +- .../Scripts/Main/GameController.cs | 10 +- .../Scripts/Misc/LevelHelper.cs | 40 +-- .../Scripts/Ship/Ship.cs | 33 +-- .../Scripts/Ship/ShipStateFactory.cs | 8 + .../Scripts/Ship/States/ShipState.cs | 12 +- .../Scripts/Ship/States/ShipStateDead.cs | 2 +- .../Scripts/Ship/States/ShipStateMoving.cs | 2 +- .../Ship/States/ShipStateWaitingToStart.cs | 29 +-- .../Media/Materials/LaserSight.mat | 118 --------- .../Media/Materials/LaserSight.mat.meta | 8 - .../Media/Models/Materials/Material.mat | 231 +++++++++--------- .../{Explosion07.prefab => Explosion.prefab} | 2 +- ...on07.prefab.meta => Explosion.prefab.meta} | 0 .../Media/Textures/Background.png | Bin 48322 -> 0 bytes .../Media/Textures/Background.png.meta | 57 ----- .../Scripts/Enemy/EnemyFacade.cs | 4 - .../Scripts/Enemy/States/EnemyStateFollow.cs | 12 - .../Installers/GameSettingsInstaller.cs | 2 +- .../Scripts/Installers/PlayerInstaller.cs | 7 +- .../Scripts/Misc/Bullet.cs | 23 +- .../Scripts/Misc/Explosion.cs | 9 +- ...etHitHandler.cs => PlayerDamageHandler.cs} | 20 +- ...er.cs.meta => PlayerDamageHandler.cs.meta} | 4 +- .../Scripts/Player/PlayerDirectionHandler.cs | 8 +- .../Scripts/Player/PlayerFacade.cs | 6 +- .../{PlayerHealthDisplay.cs => PlayerGui.cs} | 12 +- ...ealthDisplay.cs.meta => PlayerGui.cs.meta} | 0 .../Scripts/Player/PlayerHealthWatcher.cs | 14 +- .../Scripts/Player/PlayerModel.cs | 7 +- .../Scripts/Player/PlayerMoveHandler.cs | 4 +- .../Scripts/Player/PlayerShootHandler.cs | 4 +- .../SampleGame2 (Advanced)/SpaceFighter.unity | 6 +- .../BindFeatures/TestMultipleContractTypes.cs | 23 -- .../Editor/BindFeatures/TestWithArguments.cs | 18 ++ .../Bindings/TestPooledFactoryTo0.cs | 2 + .../Editor/Injection/TestListInjection.cs | 36 --- .../UnitTests/Editor/Util/TestLazy.cs | 67 +++++ .../Editor/Util/TestLazy.cs.meta} | 6 +- .../Binders/ArgConditionCopyNonLazyBinder.cs | 45 +++- .../Binding/Binders/ArgNonLazyBinder.cs | 47 +++- .../Source/Binding/Binders/IdBinder.cs | 21 ++ .../Source/Binding/Binders/IdBinder.cs.meta | 12 + .../Assets/Zenject/Source/Injection/Lazy.cs | 6 + .../Assets/Zenject/Source/Main/DiContainer.cs | 7 + .../Zenject/Source/Util/PoolCleanupChecker.cs | 4 +- 55 files changed, 454 insertions(+), 655 deletions(-) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/{Resources => }/Installers.meta (100%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/{Resources => }/Installers/GameSettingsInstaller.asset (95%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/{Resources => }/Installers/GameSettingsInstaller.asset.meta (100%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat.meta rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/{Explosion07.prefab => Explosion.prefab} (99%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/{Explosion07.prefab.meta => Explosion.prefab.meta} (100%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Textures/Background.png delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Textures/Background.png.meta rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/{PlayerBulletHitHandler.cs => PlayerDamageHandler.cs} (61%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/{PlayerBulletHitHandler.cs.meta => PlayerDamageHandler.cs.meta} (76%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/{PlayerHealthDisplay.cs => PlayerGui.cs} (85%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/{PlayerHealthDisplay.cs.meta => PlayerGui.cs.meta} (100%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs rename UnityProject/Assets/Zenject/OptionalExtras/{SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta => UnitTests/Editor/Util/TestLazy.cs.meta} (52%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/IdBinder.cs create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/IdBinder.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity index 2057434c7..cb2a8715c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity @@ -831,7 +831,7 @@ AudioSource: OutputAudioMixerGroup: {fileID: 0} m_audioClip: {fileID: 8300000, guid: c5a6af7adb029df4ba0967bc4de9e7ac, type: 3} m_PlayOnAwake: 1 - m_Volume: 0.362 + m_Volume: 0.23 m_Pitch: 1 Loop: 0 Mute: 0 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset similarity index 95% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset index 8d9107b9c..da69f81e1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset @@ -25,7 +25,9 @@ MonoBehaviour: type: 2} explosionForce: 15 StateStarting: - blinkRate: 1 + StartOffset: {x: 0, y: 3, z: 0} + Amplitude: 0.25 + Frequency: 5 Asteroid: Spawner: minSpeed: 5 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta deleted file mode 100644 index 658e7c615..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 0b687b6163f476646b5ca0dfc9059029 -folderAsset: yes -timeCreated: 1477227577 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/Asteroid.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/Asteroid.cs index dee1a5f95..b3186e7af 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/Asteroid.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/Asteroid.cs @@ -6,7 +6,7 @@ namespace Zenject.Asteroids { - public class Asteroid : MonoBehaviour, IPoolable + public class Asteroid : MonoBehaviour { LevelHelper _level; Rigidbody _rigidBody; @@ -24,38 +24,16 @@ public void Construct(LevelHelper level, Settings settings) _rigidBody = GetComponent(); } - public void OnSpawned() - { - gameObject.SetActive(true); - } - - public void OnDespawned() - { - gameObject.SetActive(false); - } - public Vector3 Position { - get - { - return transform.position; - } - set - { - transform.position = value; - } + get { return transform.position; } + set { transform.position = value; } } public float Mass { - get - { - return _rigidBody.mass; - } - set - { - _rigidBody.mass = value; - } + get { return _rigidBody.mass; } + set { _rigidBody.mass = value; } } public float Scale @@ -77,14 +55,8 @@ public float Scale public Vector3 Velocity { - get - { - return _rigidBody.velocity; - } - set - { - _rigidBody.velocity = value; - } + get { return _rigidBody.velocity; } + set { _rigidBody.velocity = value; } } public void FixedTick() @@ -138,7 +110,7 @@ public class Settings public float maxSpeed; } - public class Factory : PooledFactory + public class Factory : Factory { } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/AsteroidManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/AsteroidManager.cs index ca97b64f0..b4d3aff05 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/AsteroidManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Asteroid/AsteroidManager.cs @@ -36,10 +36,7 @@ public AsteroidManager( public IEnumerable Asteroids { - get - { - return _asteroids; - } + get { return _asteroids; } } public void Start() @@ -104,7 +101,7 @@ void ResetAll() { foreach (var asteroid in _asteroids) { - _asteroidFactory.Despawn(asteroid); + GameObject.Destroy(asteroid.gameObject); } _asteroids.Clear(); @@ -146,7 +143,7 @@ public void Tick() public void SpawnNext() { - var asteroid = _asteroidFactory.Spawn(); + var asteroid = _asteroidFactory.Create(); var attributes = _cachedAttributes.Dequeue(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs index 9a4540fef..06c705a07 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs @@ -20,7 +20,7 @@ public void CommonInstall() GameSettingsInstaller.InstallFromResource(Container); var gameSettings = Container.Resolve(); Container.Bind().AsSingle(); - Container.BindPooledFactory().FromPrefab(gameSettings.AsteroidPrefab); + Container.BindFactory().FromPrefab(gameSettings.AsteroidPrefab); Container.Bind().WithId("Main").FromGameObject(); Container.Bind().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs deleted file mode 100644 index 10487fdbd..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs +++ /dev/null @@ -1,42 +0,0 @@ -using UnityEngine; -using System.Collections; -using Zenject; -using ModestTree; - -namespace Zenject.Asteroids -{ - // This scene is an example of how decorators work - // We override move settings to make the ship much slower and add a hotkey to manually spawn asteroids - // Decorators are really useful in particular for running different test configurations - public class GameDecoratorInstaller : MonoInstaller - { - public ShipStateMoving.Settings OverrideMoveSettings; - - // If you are injecting into an installer then you will need to put the binding in PreInstall - public override void InstallBindings() - { - Container.Bind().To().AsSingle(); - // Do not spawn asteroids automatically - Container.BindInstance(false).WhenInjectedInto(); - } - } - - public class TestHotKeysAdder : ITickable - { - readonly AsteroidManager _asteroidManager; - - public TestHotKeysAdder(AsteroidManager asteroidManager) - { - _asteroidManager = asteroidManager; - } - - public void Tick() - { - if (Input.GetKeyDown(KeyCode.F4)) - { - _asteroidManager.SpawnNext(); - Log.Info("Spawned new asteroid!"); - } - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs index 720ae723a..f1c0b89d4 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs @@ -60,8 +60,7 @@ void InstallAsteroids() // Here, we're defining a generic factory to create asteroid objects using the given prefab // So any classes that want to create new asteroid objects can simply include an injected field // or constructor parameter of type Asteroid.Factory, then call Create() on that - Container.BindPooledFactory() - .WithInitialSize(25).ExpandByDoubling() + Container.BindFactory() .FromPrefab(_settings.AsteroidPrefab) // We can also tell Zenject what to name the new gameobject here .WithGameObjectName("Asteroid") @@ -90,9 +89,9 @@ void InstallShip() // Note that the ship itself is bound using a ZenjectBinding component (see Ship // game object in scene heirarchy) - Container.BindFactory(); - Container.BindFactory(); - Container.BindFactory(); + Container.BindFactory().WhenInjectedInto(); + Container.BindFactory().WhenInjectedInto(); + Container.BindFactory().WhenInjectedInto(); } void InitExecutionOrder() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameController.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameController.cs index 97fcbe5ec..871435670 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameController.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Main/GameController.cs @@ -33,18 +33,12 @@ public GameController( public float ElapsedTime { - get - { - return _elapsedTime; - } + get { return _elapsedTime; } } public GameStates State { - get - { - return _state; - } + get { return _state; } } public void Initialize() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/LevelHelper.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/LevelHelper.cs index d99034a1a..20622fcfb 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/LevelHelper.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Misc/LevelHelper.cs @@ -19,66 +19,42 @@ public LevelHelper( public float Bottom { - get - { - return -ExtentHeight; - } + get { return -ExtentHeight; } } public float Top { - get - { - return ExtentHeight; - } + get { return ExtentHeight; } } public float Left { - get - { - return -ExtentWidth; - } + get { return -ExtentWidth; } } public float Right { - get - { - return ExtentWidth; - } + get { return ExtentWidth; } } public float ExtentHeight { - get - { - return _camera.orthographicSize; - } + get { return _camera.orthographicSize; } } public float Height { - get - { - return ExtentHeight * 2.0f; - } + get { return ExtentHeight * 2.0f; } } public float ExtentWidth { - get - { - return _camera.aspect * _camera.orthographicSize; - } + get { return _camera.aspect * _camera.orthographicSize; } } public float Width { - get - { - return ExtentWidth * 2.0f; - } + get { return ExtentWidth * 2.0f; } } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/Ship.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/Ship.cs index a694917e1..953a7f1ae 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/Ship.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/Ship.cs @@ -27,42 +27,24 @@ public void Construct(ShipStateFactory stateFactory) public MeshRenderer MeshRenderer { - get - { - return _meshRenderer; - } + get { return _meshRenderer; } } public ParticleEmitter ParticleEmitter { - get - { - return _particleEmitter; - } + get { return _particleEmitter; } } public Vector3 Position { - get - { - return transform.position; - } - set - { - transform.position = value; - } + get { return transform.position; } + set { transform.position = value; } } public Quaternion Rotation { - get - { - return transform.rotation; - } - set - { - transform.rotation = value; - } + get { return transform.rotation; } + set { transform.rotation = value; } } public void Start() @@ -84,7 +66,8 @@ public void ChangeState(ShipStates state) { if (_state != null) { - _state.Stop(); + _state.Dispose(); + _state = null; } _state = _stateFactory.CreateState(state); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/ShipStateFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/ShipStateFactory.cs index 31b598974..8e0427ade 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/ShipStateFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/ShipStateFactory.cs @@ -7,6 +7,14 @@ namespace Zenject.Asteroids { + public enum ShipStates + { + Moving, + Dead, + WaitingToStart, + Count, + } + public class ShipStateFactory { readonly ShipStateWaitingToStart.Factory _waitingFactory; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipState.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipState.cs index 6b5bd2c2d..596e9352a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipState.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipState.cs @@ -5,15 +5,7 @@ namespace Zenject.Asteroids { - public enum ShipStates - { - Moving, - Dead, - WaitingToStart, - Count, - } - - public abstract class ShipState + public abstract class ShipState : IDisposable { public abstract void Update(); @@ -22,7 +14,7 @@ public virtual void Start() // optionally overridden } - public virtual void Stop() + public virtual void Dispose() { // optionally overridden } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs index cf97ac04e..934d8f623 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs @@ -60,7 +60,7 @@ public override void Start() _gameEvents.ShipCrashed(); } - public override void Stop() + public override void Dispose() { _ship.MeshRenderer.enabled = true; _ship.ParticleEmitter.emit = true; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateMoving.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateMoving.cs index 1d47b5c01..9f58b8eea 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateMoving.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateMoving.cs @@ -77,7 +77,7 @@ public override void Start() _ship.ParticleEmitter.emit = true; } - public override void Stop() + public override void Dispose() { _ship.ParticleEmitter.emit = false; } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateWaitingToStart.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateWaitingToStart.cs index 96d82b206..502263a7a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateWaitingToStart.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateWaitingToStart.cs @@ -10,41 +10,34 @@ public class ShipStateWaitingToStart : ShipState readonly Settings _settings; readonly Ship _ship; - float _elapsedTime; + float _theta; - public ShipStateWaitingToStart(Settings settings, Ship ship) + public ShipStateWaitingToStart( + Ship ship, + Settings settings) { - _ship = ship; _settings = settings; + _ship = ship; } public override void Start() { - _ship.Position = Vector3.zero; + _ship.Position = _settings.StartOffset; _ship.Rotation = Quaternion.AngleAxis(90.0f, Vector3.up) * Quaternion.AngleAxis(90.0f, Vector3.right); } - public override void Stop() - { - _ship.MeshRenderer.material.color = Color.white; - } - public override void Update() { - _elapsedTime += Time.deltaTime; - - var timeForOneCycle = 1.0f / _settings.blinkRate; - var theta = 2.0f * Mathf.PI * _elapsedTime / timeForOneCycle; - - var px = (Mathf.Cos(theta) + 1.0f) / 2.0f; - - _ship.MeshRenderer.material.color = new Color(1.0f, 1.0f, 1.0f, px); + _ship.Position = _settings.StartOffset + Vector3.up * _settings.Amplitude * Mathf.Sin(_theta); + _theta += Time.deltaTime * _settings.Frequency; } [Serializable] public class Settings { - public float blinkRate; + public Vector3 StartOffset; + public float Amplitude; + public float Frequency; } public class Factory : Factory diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat deleted file mode 100644 index 1113f908c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat +++ /dev/null @@ -1,118 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_Name: LaserSight - m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} - m_ShaderKeywords: - m_LightmapFlags: 5 - m_CustomRenderQueue: -1 - stringTagMap: {} - m_SavedProperties: - serializedVersion: 2 - m_TexEnvs: - - first: - name: _BumpMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - first: - name: _DetailAlbedoMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - first: - name: _DetailMask - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - first: - name: _DetailNormalMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - first: - name: _EmissionMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - first: - name: _MainTex - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - first: - name: _MetallicGlossMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - first: - name: _OcclusionMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - first: - name: _ParallaxMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: - - first: - name: _BumpScale - second: 1 - - first: - name: _Cutoff - second: 0.5 - - first: - name: _DetailNormalMapScale - second: 1 - - first: - name: _DstBlend - second: 0 - - first: - name: _Glossiness - second: 0.5 - - first: - name: _InvFade - second: 1 - - first: - name: _Metallic - second: 0 - - first: - name: _Mode - second: 0 - - first: - name: _OcclusionStrength - second: 1 - - first: - name: _Parallax - second: 0.02 - - first: - name: _SrcBlend - second: 1 - - first: - name: _UVSec - second: 0 - - first: - name: _ZWrite - second: 1 - m_Colors: - - first: - name: _Color - second: {r: 0.7352941, g: 0, b: 0, a: 1} - - first: - name: _EmissionColor - second: {r: 0, g: 0, b: 0, a: 1} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat.meta deleted file mode 100644 index ce76e4219..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Materials/LaserSight.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ff629f1f83352ae4a88e72f9cefa2770 -timeCreated: 1456628383 -licenseType: Free -NativeFormatImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Models/Materials/Material.mat b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Models/Materials/Material.mat index a395ae840..284e4e237 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Models/Materials/Material.mat +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Models/Materials/Material.mat @@ -8,131 +8,120 @@ Material: m_PrefabInternal: {fileID: 0} m_Name: Material m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} - m_ShaderKeywords: - m_LightmapFlags: 5 + m_ShaderKeywords: _EMISSION + m_LightmapFlags: 1 m_CustomRenderQueue: -1 stringTagMap: {} m_SavedProperties: serializedVersion: 2 m_TexEnvs: - data: - first: - name: _MainTex - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _BumpMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailNormalMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _ParallaxMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _OcclusionMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _EmissionMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailMask - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailAlbedoMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _MetallicGlossMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} + - first: + name: _BumpMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailAlbedoMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailMask + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _DetailNormalMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _EmissionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MetallicGlossMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _OcclusionMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _ParallaxMap + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} m_Floats: - data: - first: - name: _SrcBlend - second: 1 - data: - first: - name: _DstBlend - second: 0 - data: - first: - name: _Cutoff - second: 0.5 - data: - first: - name: _Parallax - second: 0.02 - data: - first: - name: _ZWrite - second: 1 - data: - first: - name: _Glossiness - second: 0.5 - data: - first: - name: _BumpScale - second: 1 - data: - first: - name: _OcclusionStrength - second: 1 - data: - first: - name: _DetailNormalMapScale - second: 1 - data: - first: - name: _UVSec - second: 0 - data: - first: - name: _Mode - second: 0 - data: - first: - name: _Metallic - second: 0 + - first: + name: _BumpScale + second: 1 + - first: + name: _Cutoff + second: 0.5 + - first: + name: _DetailNormalMapScale + second: 1 + - first: + name: _DstBlend + second: 0 + - first: + name: _GlossMapScale + second: 1 + - first: + name: _Glossiness + second: 0.5 + - first: + name: _GlossyReflections + second: 1 + - first: + name: _Metallic + second: 0 + - first: + name: _Mode + second: 0 + - first: + name: _OcclusionStrength + second: 1 + - first: + name: _Parallax + second: 0.02 + - first: + name: _SmoothnessTextureChannel + second: 0 + - first: + name: _SpecularHighlights + second: 1 + - first: + name: _SrcBlend + second: 1 + - first: + name: _UVSec + second: 0 + - first: + name: _ZWrite + second: 1 m_Colors: - data: - first: - name: _EmissionColor - second: {r: 0, g: 0, b: 0, a: 1} - data: - first: - name: _Color - second: {r: 0.8, g: 0.8, b: 0.8, a: 1} + - first: + name: _Color + second: {r: 0.8, g: 0.8, b: 0.8, a: 1} + - first: + name: _EmissionColor + second: {r: 0, g: 0, b: 0, a: 1} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion.prefab similarity index 99% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion.prefab index 6fd002923..5a3dc3bd0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion.prefab @@ -29,7 +29,7 @@ GameObject: - component: {fileID: 19900002} - component: {fileID: 11436508} m_Layer: 0 - m_Name: Explosion07 + m_Name: Explosion m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion.prefab.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion07.prefab.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Prefabs/Explosion.prefab.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Textures/Background.png b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Media/Textures/Background.png deleted file mode 100644 index 963027d0cdb53ee4561a479151fcd64b42af3c75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48322 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 { } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs index a9dc30016..b018f6597 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs @@ -52,17 +52,6 @@ public void Update() var distanceToPlayer = (_player.Position - _enemy.Position).magnitude; - Assert.That(_settings.TeleportDistance > _settings.TeleportNewDistance); - - // If they are far enough away, just teleport them to the other side of the player - // This is good because otherwise the best strategy is just to keep running away and shooting - // and it gets boring - if (distanceToPlayer > _settings.TeleportDistance) - { - var playerDir = (_player.Position - _enemy.Position).normalized; - _enemy.Position = _player.Position + playerDir * _settings.TeleportNewDistance; - } - // Always look towards the player _enemy.DesiredLookDir = (_player.Position - _enemy.Position).normalized; @@ -111,7 +100,6 @@ public class Settings { public float StrafeMultiplier; public float StrafeChangeInterval; - public float TeleportDistance; public float TeleportNewDistance; } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs index a17fbef1b..ac11cdcbe 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameSettingsInstaller.cs @@ -34,7 +34,7 @@ public class PlayerSettings { public PlayerMoveHandler.Settings PlayerMoveHandler; public PlayerShootHandler.Settings PlayerShootHandler; - public PlayerBulletHitHandler.Settings PlayerCollisionHandler; + public PlayerDamageHandler.Settings PlayerCollisionHandler; public PlayerHealthWatcher.Settings PlayerHealthWatcher; } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs index 60ee1fde7..251def6ca 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs @@ -11,13 +11,12 @@ public class PlayerInstaller : MonoInstaller public override void InstallBindings() { - Container.BindInstance(_settings.Rigidbody).WhenInjectedInto(); - Container.BindInstance(_settings.MeshRenderer).WhenInjectedInto(); - Container.Bind().AsSingle(); + Container.Bind().AsSingle() + .WithArguments(_settings.Rigidbody, _settings.MeshRenderer); Container.BindAllInterfaces().To().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); - Container.BindAllInterfacesAndSelf().To().AsSingle(); + Container.BindAllInterfacesAndSelf().To().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); Container.BindAllInterfaces().To().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs index 2227f3a8a..94f4cac79 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs @@ -26,14 +26,17 @@ public class Bullet : MonoBehaviour, IPoolable [SerializeField] Material _enemyMaterial = null; + [Inject] Factory _selfFactory; - GameEvents _gameEvents; - [Inject] - void Construct(Factory selfFactory, GameEvents gameEvents) + public BulletTypes Type + { + get { return _type; } + } + + public Vector3 MoveDirection { - _selfFactory = selfFactory; - _gameEvents = gameEvents; + get { return transform.right; } } public void OnSpawned(float speed, float lifeTime, BulletTypes type) @@ -54,16 +57,6 @@ public void OnDespawned() this.gameObject.SetActive(false); } - public BulletTypes Type - { - get { return _type; } - } - - public Vector3 MoveDirection - { - get { return transform.right; } - } - public void OnTriggerEnter(Collider other) { var enemy = other.GetComponent(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs index b30d93e22..a5659e7eb 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs @@ -20,17 +20,10 @@ public class Explosion : MonoBehaviour, IPoolable [SerializeField] float _soundVolume; - AudioPlayer _audioPlayer; - float _startTime; - Factory _selfFactory; [Inject] - public void Construct(AudioPlayer audioPlayer, Factory selfFactory) - { - _audioPlayer = audioPlayer; - _selfFactory = selfFactory; - } + Factory _selfFactory; public void OnSpawned() { diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDamageHandler.cs similarity index 61% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDamageHandler.cs index 84ca7a426..f6dbe5634 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDamageHandler.cs @@ -4,33 +4,29 @@ namespace Zenject.SpaceFighter { - public class PlayerBulletHitHandler + public class PlayerDamageHandler { readonly AudioPlayer _audioPlayer; readonly Settings _settings; - readonly PlayerModel _model; + readonly Player _player; - GameEvents _gameEvents; - - public PlayerBulletHitHandler( - PlayerModel model, + public PlayerDamageHandler( + Player player, Settings settings, - AudioPlayer audioPlayer, - GameEvents gameEvents) + AudioPlayer audioPlayer) { - _gameEvents = gameEvents; _audioPlayer = audioPlayer; _settings = settings; - _model = model; + _player = player; } public void TakeDamage(Vector3 moveDirection) { _audioPlayer.Play(_settings.HitSound, _settings.HitSoundVolume); - _model.AddForce(-moveDirection * _settings.HitForce); + _player.AddForce(-moveDirection * _settings.HitForce); - _model.TakeDamage(_settings.HealthLoss); + _player.TakeDamage(_settings.HealthLoss); } [Serializable] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDamageHandler.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDamageHandler.cs.meta index c75dd8d35..3b7b8f1a2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerBulletHitHandler.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDamageHandler.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 584a43d89e0f8b74a89a8ba978b1fdd2 -timeCreated: 1457197731 +guid: b6cd15ebe0f3c3243af6b6a44d7f2ded +timeCreated: 1484757106 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDirectionHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDirectionHandler.cs index 1633c9d1b..e45df53e1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDirectionHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerDirectionHandler.cs @@ -4,20 +4,20 @@ namespace Zenject.SpaceFighter { - public class PlayerDirectionHandler : ILateTickable + public class PlayerDirectionHandler : ITickable { - readonly PlayerModel _player; + readonly Player _player; readonly Camera _mainCamera; public PlayerDirectionHandler( Camera mainCamera, - PlayerModel player) + Player player) { _player = player; _mainCamera = mainCamera; } - public void LateTick() + public void Tick() { var mouseRay = _mainCamera.ScreenPointToRay(Input.mousePosition); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerFacade.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerFacade.cs index 539b0c373..12e80f201 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerFacade.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerFacade.cs @@ -5,11 +5,11 @@ namespace Zenject.SpaceFighter { public class PlayerFacade : MonoBehaviour { - PlayerModel _model; - PlayerBulletHitHandler _hitHandler; + Player _model; + PlayerDamageHandler _hitHandler; [Inject] - public void Construct(PlayerModel player, PlayerBulletHitHandler hitHandler) + public void Construct(Player player, PlayerDamageHandler hitHandler) { _model = player; _hitHandler = hitHandler; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerGui.cs similarity index 85% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerGui.cs index c846303fc..c494a1864 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerGui.cs @@ -6,7 +6,7 @@ namespace Zenject.SpaceFighter { - public class PlayerHealthDisplay : MonoBehaviour + public class PlayerGui : MonoBehaviour { [SerializeField] float _leftPadding; @@ -35,15 +35,15 @@ public class PlayerHealthDisplay : MonoBehaviour [SerializeField] Color _backgroundColor; - PlayerModel _model; + Player _player; Texture2D _textureForeground; Texture2D _textureBackground; int _killCount; [Inject] - public void Construct(PlayerModel model, GameEvents gameEvents) + public void Construct(Player player, GameEvents gameEvents) { - _model = model; + _player = player; _textureForeground = CreateColorTexture(_foregroundColor); _textureBackground = CreateColorTexture(_backgroundColor); @@ -67,7 +67,7 @@ Texture2D CreateColorTexture(Color color) public void OnGUI() { var healthLabelBounds = new Rect(_leftPadding, Screen.height - _bottomPadding, _labelWidth, _labelHeight); - GUI.Label(healthLabelBounds, "Health: {0:0}".Fmt(_model.Health)); + GUI.Label(healthLabelBounds, "Health: {0:0}".Fmt(_player.Health)); var killLabelBounds = new Rect(healthLabelBounds.xMin, healthLabelBounds.yMin - _killCountOffset, _labelWidth, _labelHeight); GUI.Label(killLabelBounds, "Kill Count: {0}".Fmt(_killCount)); @@ -75,7 +75,7 @@ public void OnGUI() var boundsBackground = new Rect(healthLabelBounds.xMax, healthLabelBounds.yMin, _textureWidth, _textureHeight); GUI.DrawTexture(boundsBackground, _textureBackground); - var boundsForeground = new Rect(boundsBackground.xMin, boundsBackground.yMin, (_model.Health / 100.0f) * _textureWidth, _textureHeight); + var boundsForeground = new Rect(boundsBackground.xMin, boundsBackground.yMin, (_player.Health / 100.0f) * _textureWidth, _textureHeight); GUI.DrawTexture(boundsForeground, _textureForeground); } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerGui.cs.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthDisplay.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerGui.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs index 94a3c07b8..92814b3fa 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs @@ -10,10 +10,10 @@ public class PlayerHealthWatcher : ITickable readonly Settings _settings; readonly GameEvents _gameEvents; readonly Explosion.Factory _explosionFactory; - readonly PlayerModel _model; + readonly Player _player; public PlayerHealthWatcher( - PlayerModel model, + Player player, Explosion.Factory explosionFactory, GameEvents gameEvents, Settings settings, @@ -23,12 +23,12 @@ public PlayerHealthWatcher( _settings = settings; _gameEvents = gameEvents; _explosionFactory = explosionFactory; - _model = model; + _player = player; } public void Tick() { - if (_model.Health <= 0 && !_model.IsDead) + if (_player.Health <= 0 && !_player.IsDead) { Die(); } @@ -36,12 +36,12 @@ public void Tick() void Die() { - _model.IsDead = true; + _player.IsDead = true; var explosion = _explosionFactory.Spawn(); - explosion.transform.position = _model.Position; + explosion.transform.position = _player.Position; - _model.Renderer.enabled = false; + _player.Renderer.enabled = false; _gameEvents.PlayerKilled(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerModel.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerModel.cs index 2d5b586f5..8e986cb6f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerModel.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerModel.cs @@ -2,14 +2,14 @@ namespace Zenject.SpaceFighter { - public class PlayerModel + public class Player { readonly Rigidbody _rigidBody; readonly MeshRenderer _renderer; float _health = 100.0f; - public PlayerModel( + public Player( Rigidbody rigidBody, MeshRenderer renderer) { @@ -24,8 +24,7 @@ public MeshRenderer Renderer public bool IsDead { - get; - set; + get; set; } public float Health diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerMoveHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerMoveHandler.cs index 0c024a40f..e0c4a71fe 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerMoveHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerMoveHandler.cs @@ -9,12 +9,12 @@ public class PlayerMoveHandler : IFixedTickable { readonly LevelBoundary _levelBoundary; readonly Settings _settings; - readonly PlayerModel _player; + readonly Player _player; readonly PlayerInputState _inputState; public PlayerMoveHandler( PlayerInputState inputState, - PlayerModel player, + Player player, Settings settings, LevelBoundary levelBoundary) { diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs index 7573f30c2..716562fd9 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs @@ -7,7 +7,7 @@ namespace Zenject.SpaceFighter public class PlayerShootHandler : ITickable { readonly AudioPlayer _audioPlayer; - readonly PlayerModel _player; + readonly Player _player; readonly Settings _settings; readonly Bullet.Factory _bulletFactory; readonly PlayerInputState _inputState; @@ -18,7 +18,7 @@ public PlayerShootHandler( PlayerInputState inputState, Bullet.Factory bulletFactory, Settings settings, - PlayerModel player, + Player player, AudioPlayer audioPlayer) { _audioPlayer = audioPlayer; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity index 8b0e01f73..9ad643e59 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity @@ -236,11 +236,11 @@ AudioSource: m_Enabled: 1 serializedVersion: 4 OutputAudioMixerGroup: {fileID: 0} - m_audioClip: {fileID: 0} + m_audioClip: {fileID: 8300000, guid: c5a6af7adb029df4ba0967bc4de9e7ac, type: 3} m_PlayOnAwake: 1 - m_Volume: 1 + m_Volume: 0.171 m_Pitch: 1 - Loop: 0 + Loop: 1 Mute: 0 Spatialize: 0 SpatializePostEffects: 0 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes.cs index 212880d38..ff8ae41dd 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes.cs @@ -54,29 +54,6 @@ public void TestMultiBind1() Assert.That(test1.tests.Count == 2); } - [Test] - public void TestMultiBind2() - { - Container.Bind().AsSingle().NonLazy(); - - Assert.Throws(() => Container.Validate()); - - // optional list dependencies should be declared as optional - Assert.Throws( - delegate { Container.Resolve(); }); - } - - [Test] - public void TestMultiBind2Validate() - { - Container.Bind().AsSingle().NonLazy(); - - Assert.Throws(() => Container.Validate()); - - Assert.Throws( - delegate { Container.Resolve(); }); - } - [Test] public void TestMultiBindListInjection() { diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestWithArguments.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestWithArguments.cs index 8d9dd1a2d..1872f0bd9 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestWithArguments.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestWithArguments.cs @@ -42,6 +42,17 @@ public void TestSingleDifferentArguments() Container.Resolve(); } + [Test] + public void TestNullValues() + { + Container.Bind().AsSingle().WithArguments(3, (string)null); + + var foo = Container.Resolve(); + + Assert.IsEqual(foo.Value, 3); + Assert.IsEqual(foo.Value2, null); + } + interface IFoo { } @@ -54,6 +65,7 @@ public Foo( string value2) { Value = value; + Value2 = value2; } public int Value @@ -61,6 +73,12 @@ public int Value get; private set; } + + public string Value2 + { + get; + private set; + } } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs index 57dca4903..ae0ddd613 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs @@ -2,6 +2,8 @@ using NUnit.Framework; using Assert=ModestTree.Assert; +#pragma warning disable 219 + namespace Zenject.Tests.Bindings { [TestFixture] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestListInjection.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestListInjection.cs index db247acec..00e2549f6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestListInjection.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestListInjection.cs @@ -17,28 +17,13 @@ public Test1(List values) } } - class Test2 - { - public Test2( - [InjectOptional] List values) - { - } - } - class Test3 { [Inject] public List values = null; } - class Test4 - { - [InjectOptional] - public List values = null; - } - [Test] - [ExpectedException] public void TestCase1() { Container.Bind().AsSingle(); @@ -47,33 +32,12 @@ public void TestCase1() } [Test] - public void TestCase2() - { - Container.Bind().AsSingle(); - - var result = Container.ResolveAll(); - - Assert.That(result != null); - } - - [Test] - [ExpectedException] public void TestCase3() { Container.Bind().AsSingle(); Container.ResolveAll(); } - - [Test] - public void TestCase4() - { - Container.Bind().AsSingle(); - - var result = Container.ResolveAll(); - - Assert.That(result != null); - } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs new file mode 100644 index 000000000..e36cf1b77 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs @@ -0,0 +1,67 @@ +using System; +using NUnit.Framework; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestLazy : ZenjectUnitTestFixture + { + [Test] + public void Test1() + { + Bar.InstanceCount = 0; + + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + + var foo = Container.Resolve(); + + Container.Validate(); + + Assert.IsEqual(Bar.InstanceCount, 0); + + foo.DoIt(); + + Assert.IsEqual(Bar.InstanceCount, 1); + } + + [Test] + public void Test2() + { + Container.Bind().AsSingle(); + + Assert.Throws(() => Container.Validate()); + Assert.Throws(() => Container.Resolve()); + } + + public class Bar + { + public static int InstanceCount = 0; + + public Bar() + { + InstanceCount++; + } + + public void DoIt() + { + } + } + + public class Foo + { + readonly Lazy _bar; + + public Foo(Lazy bar) + { + _bar = bar; + } + + public void DoIt() + { + _bar.Value.DoIt(); + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta similarity index 52% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta index 6ebbc9ba2..d37babd2d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameDecoratorInstaller.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta @@ -1,8 +1,12 @@ fileFormatVersion: 2 -guid: f5efd89f29bfcd141907dd60701bc741 +guid: 06aa2c1aff843464b9ec86db2b946e85 +timeCreated: 1485055134 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs index 55880d610..6c1bc178a 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgConditionCopyNonLazyBinder.cs @@ -10,7 +10,50 @@ public ArgConditionCopyNonLazyBinder(BindInfo bindInfo) { } - public ConditionCopyNonLazyBinder WithArguments(params object[] args) + // We use generics instead of params object[] so that we preserve type info + // So that you can for example pass in a variable that is null and the type info will + // still be used to map null on to the correct field + public ConditionCopyNonLazyBinder WithArguments(T param) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param); + return this; + } + + public ConditionCopyNonLazyBinder WithArguments(TParam1 param1, TParam2 param2) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2); + return this; + } + + public ConditionCopyNonLazyBinder WithArguments( + TParam1 param1, TParam2 param2, TParam3 param3) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2, param3); + return this; + } + + public ConditionCopyNonLazyBinder WithArguments( + TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2, param3, param4); + return this; + } + + public ConditionCopyNonLazyBinder WithArguments( + TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2, param3, param4, param5); + return this; + } + + public ConditionCopyNonLazyBinder WithArguments( + TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5, TParam6 param6) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2, param3, param4, param5, param6); + return this; + } + + public ConditionCopyNonLazyBinder WithArguments(object[] args) { BindInfo.Arguments = InjectUtil.CreateArgList(args); return this; diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs index 9a42acbd0..f526f1561 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ArgNonLazyBinder.cs @@ -10,13 +10,56 @@ public ArgNonLazyBinder(BindInfo bindInfo) { } - public NonLazyBinder WithArguments(params object[] args) + // We use generics instead of params object[] so that we preserve type info + // So that you can for example pass in a variable that is null and the type info will + // still be used to map null on to the correct field + public ArgNonLazyBinder WithArguments(T param) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param); + return this; + } + + public ArgNonLazyBinder WithArguments(TParam1 param1, TParam2 param2) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2); + return this; + } + + public ArgNonLazyBinder WithArguments( + TParam1 param1, TParam2 param2, TParam3 param3) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2, param3); + return this; + } + + public ArgNonLazyBinder WithArguments( + TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2, param3, param4); + return this; + } + + public ArgNonLazyBinder WithArguments( + TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2, param3, param4, param5); + return this; + } + + public ArgNonLazyBinder WithArguments( + TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5, TParam6 param6) + { + BindInfo.Arguments = InjectUtil.CreateArgListExplicit(param1, param2, param3, param4, param5, param6); + return this; + } + + public ArgNonLazyBinder WithArguments(object[] args) { BindInfo.Arguments = InjectUtil.CreateArgList(args); return this; } - public NonLazyBinder WithArgumentsExplicit(IEnumerable extraArgs) + public ArgNonLazyBinder WithArgumentsExplicit(IEnumerable extraArgs) { BindInfo.Arguments = extraArgs.ToList(); return this; diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/IdBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdBinder.cs new file mode 100644 index 000000000..ca791a342 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdBinder.cs @@ -0,0 +1,21 @@ +using ModestTree; + +namespace Zenject +{ + public class IdBinder + { + BindInfo _bindInfo; + + public IdBinder(BindInfo bindInfo) + { + _bindInfo = bindInfo; + } + + public void WithId(object identifier) + { + _bindInfo.Identifier = identifier; + } + } +} + + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/IdBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdBinder.cs.meta new file mode 100644 index 000000000..99c248e8f --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/IdBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 371e1c0b9a8ff664f993cbe2a547eeae +timeCreated: 1484790451 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs b/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs index a1a5fe2d9..334f72480 100644 --- a/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs +++ b/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs @@ -2,6 +2,7 @@ namespace Zenject { + [ZenjectAllowDuringValidationAttribute] public class Lazy { readonly DiContainer _container; @@ -14,6 +15,11 @@ public Lazy(DiContainer container, InjectContext context) { _container = container; _context = context; + + if (container.IsValidating) + { + var value = this.Value; + } } public T Value diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index ce8b09dff..4059fbfac 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -266,6 +266,8 @@ public void ValidateIValidatables() List validatableProviders; + Assert.That(!bindingId.Type.IsGenericTypeDefinition()); + var injectContext = new InjectContext( this, bindingId.Type, bindingId.Identifier); @@ -607,6 +609,10 @@ public object Resolve(InjectContext context) var subContext = context.Clone(); subContext.MemberType = subType; + // By making this optional this means that all injected fields of type List<> + // will pass validation, which could be error prone, but I think this is better + // than always requiring that they explicitly mark their list types as optional + subContext.Optional = true; return ResolveAll(subContext); } @@ -1815,6 +1821,7 @@ public ConcreteIdBinderGeneric Bind(BindInfo bindInfo) { Assert.That(!typeof(TContract).DerivesFrom(), "You should not use Container.Bind for factory classes. Use Container.BindFactory instead."); + Assert.That(bindInfo.ContractTypes.Contains(typeof(TContract))); return new ConcreteIdBinderGeneric( bindInfo, StartBinding()); diff --git a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs index c8e49eab2..fc7f31d31 100644 --- a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs +++ b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs @@ -22,8 +22,8 @@ public void LateDispose() { foreach (var pool in _poolFactories) { - Assert.That(pool.NumActive == 0, - "Found active objects in pool '{0}' during dispose. Did you forget to despawn an object of type '{1}'?", pool.GetType(), pool.ContractType); + Assert.IsEqual(pool.NumActive, 0, + "Found active objects in pool '{0}' during dispose. Did you forget to despawn an object of type '{1}'?".Fmt(pool.GetType(), pool.ContractType)); } } } From e22fff86f49b41aa1c9c9e39d081c63cf4b4936c Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 22 Jan 2017 13:49:08 -0400 Subject: [PATCH 21/62] - Renamed BindAllInterfaces to BindInterfacesTo and BindAllInterfacesAndSelf to BindInterfacesAndSelfTo to avoid the extremely common mistake of forgetting the To - Added some more tests of using Lazy<>. Also fixed Lazy<> to validate properly - Added ProfileBlock class --- .../Scripts/Installers/GameInstaller.cs | 6 +- .../Scripts/Installers/EnemyInstaller.cs | 6 +- .../Scripts/Installers/GameInstaller.cs | 4 +- .../Scripts/Installers/PlayerInstaller.cs | 12 +- .../TestMultipleContractTypes2.cs | 17 +-- .../Bindings/TestPooledFactoryTo1.cs | 2 + .../Editor/Other/TestFacadeSubContainer.cs | 4 +- .../UnitTests/Editor/Util/TestLazy.cs | 7 +- .../UnitTests/Editor/Util/TestLazy.cs.meta | 4 +- .../Finalizers/ProviderBindingFinalizer.cs | 2 +- .../Assets/Zenject/Source/Injection/Lazy.cs | 15 +- .../Source/Install/Contexts/Context.cs | 4 +- .../Zenject/Source/Install/ZenjectBinding.cs | 2 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 44 +++--- .../Source/Providers/MethodProvider.cs | 2 +- .../Source/Providers/MethodProviderUntyped.cs | 2 +- .../Source/Runtime/GuiRenderableManager.cs | 4 +- .../Source/Runtime/InitializableManager.cs | 2 +- .../Zenject/Source/Runtime/TaskUpdater.cs | 12 +- .../Zenject/Source/Util/PoolCleanupChecker.cs | 2 +- .../Zenject/Source/Util/ProfileBlock.cs | 140 ++++++++++++++++++ .../Zenject/Source/Util/ProfileBlock.cs.meta | 12 ++ 22 files changed, 230 insertions(+), 75 deletions(-) create mode 100644 UnityProject/Assets/Zenject/Source/Util/ProfileBlock.cs create mode 100644 UnityProject/Assets/Zenject/Source/Util/ProfileBlock.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs index f1c0b89d4..70e16fb99 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs @@ -55,7 +55,7 @@ void InstallAsteroids() Container.Bind().AsSingle(); // The above three lines are also identical to just doing this instead: - // Container.BindAllInterfacesAndSelf().To(); + // Container.BindInterfacesAndSelfTo(); // Here, we're defining a generic factory to create asteroid objects using the given prefab // So any classes that want to create new asteroid objects can simply include an injected field @@ -71,10 +71,10 @@ void InstallAsteroids() void InstallMisc() { - Container.BindAllInterfacesAndSelf().To().AsSingle(); + Container.BindInterfacesAndSelfTo().AsSingle(); Container.Bind().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.BindFactory().FromPrefab(_settings.ExplosionPrefab); Container.BindFactory().FromPrefab(_settings.BrokenShipPrefab); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs index 53b218972..ada51c955 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/EnemyInstaller.cs @@ -16,14 +16,14 @@ public override void InstallBindings() Container.Bind().AsSingle() .WithArguments(_settings.Renderer, _settings.Collider, _settings.Rigidbody); - Container.BindAllInterfacesAndSelf().To().AsSingle(); + Container.BindInterfacesAndSelfTo().AsSingle(); Container.Bind().AsSingle(); Container.Bind().AsSingle(); Container.Bind().AsSingle(); - Container.BindAllInterfacesAndSelf().To().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesAndSelfTo().AsSingle(); + Container.BindInterfacesTo().AsSingle(); } [Serializable] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs index 3691ab0ed..4a4d2ec3b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs @@ -15,7 +15,7 @@ public override void InstallBindings() { Container.Bind().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.BindPooledFactory() .FromSubContainerResolve() @@ -34,7 +34,7 @@ public override void InstallBindings() Container.Bind().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); } [Serializable] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs index 251def6ca..78b17d31c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/PlayerInstaller.cs @@ -14,15 +14,15 @@ public override void InstallBindings() Container.Bind().AsSingle() .WithArguments(_settings.Rigidbody, _settings.MeshRenderer); - Container.BindAllInterfaces().To().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); - Container.BindAllInterfacesAndSelf().To().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); + Container.BindInterfacesTo().AsSingle(); + Container.BindInterfacesAndSelfTo().AsSingle(); + Container.BindInterfacesTo().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.Bind().AsSingle(); - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); } [Serializable] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs index 6baac9e40..59e22e1f4 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs @@ -55,7 +55,7 @@ public void TestInterfaces() [Test] public void TestAllInterfaces() { - Container.BindAllInterfaces().To().AsSingle().NonLazy(); + Container.BindInterfacesTo().AsSingle().NonLazy(); Container.Validate(); @@ -67,7 +67,7 @@ public void TestAllInterfaces() [Test] public void TestAllInterfacesAndSelf() { - Container.BindAllInterfacesAndSelf().To().AsSingle().NonLazy(); + Container.BindInterfacesAndSelfTo().AsSingle().NonLazy(); Container.Validate(); @@ -75,19 +75,6 @@ public void TestAllInterfacesAndSelf() Assert.IsNotNull(Container.Resolve()); Assert.IsNotNull(Container.Resolve()); } - - [Test] - [ExpectedException] - public void TestAllInterfacesMistake() - { - Container.BindAllInterfaces().AsSingle().NonLazy(); - Container.FlushBindings(); - - Container.Validate(); - - Assert.IsNotNull(Container.Resolve()); - Assert.IsNotNull(Container.Resolve()); - } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs index 71eb8f759..8958b0cb1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs @@ -2,6 +2,8 @@ using NUnit.Framework; using Assert=ModestTree.Assert; +#pragma warning disable 219 + namespace Zenject.Tests.Bindings { [TestFixture] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestFacadeSubContainer.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestFacadeSubContainer.cs index 3ca758800..e3adf435a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestFacadeSubContainer.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestFacadeSubContainer.cs @@ -27,8 +27,8 @@ public void Test1() .ToSelf().AsSingle().CopyIntoAllSubContainers(); // This is how you add ITickables / etc. within sub containers - container.BindAllInterfacesAndSelf() - .To().FromSubContainerResolve().ByMethod(InstallFoo).AsSingle(); + container.BindInterfacesAndSelfTo() + .FromSubContainerResolve().ByMethod(InstallFoo).AsSingle(); var tickManager = container.Resolve(); var initManager = container.Resolve(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs index e36cf1b77..d65f345ce 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs @@ -29,10 +29,13 @@ public void Test1() [Test] public void Test2() { - Container.Bind().AsSingle(); + Container.Bind().AsSingle().NonLazy(); Assert.Throws(() => Container.Validate()); - Assert.Throws(() => Container.Resolve()); + + var foo = Container.Resolve(); + + Assert.Throws(() => foo.DoIt()); } public class Bar diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta index d37babd2d..2c6862c75 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 06aa2c1aff843464b9ec86db2b946e85 -timeCreated: 1485055134 +guid: 3abd5475d61683e4b88631a8a4a7eb2e +timeCreated: 1485055480 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs index b1ff4f55c..0c38187ea 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs @@ -28,7 +28,7 @@ public void FinalizeBinding(DiContainer container) if (BindInfo.ContractTypes.IsEmpty()) { // We could assert her instead but it is nice when used with things like - // BindAllInterfaces() (and there aren't any interfaces) to allow + // BindInterfaces() (and there aren't any interfaces) to allow // interfaces to be added later return; } diff --git a/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs b/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs index 334f72480..bdb64328d 100644 --- a/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs +++ b/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs @@ -2,8 +2,13 @@ namespace Zenject { + public interface ILazy + { + void Validate(); + } + [ZenjectAllowDuringValidationAttribute] - public class Lazy + public class Lazy : ILazy { readonly DiContainer _container; readonly InjectContext _context; @@ -15,11 +20,11 @@ public Lazy(DiContainer container, InjectContext context) { _container = container; _context = context; + } - if (container.IsValidating) - { - var value = this.Value; - } + void ILazy.Validate() + { + _container.Resolve(_context); } public T Value diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs index 78f8095e7..dea6797b9 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs @@ -230,12 +230,12 @@ void InstallZenjectBinding(ZenjectBinding binding) } case ZenjectBinding.BindTypes.AllInterfaces: { - Container.BindAllInterfaces(componentType).WithId(identifier).FromInstance(component, true); + Container.Bind(componentType.Interfaces().ToArray()).WithId(identifier).FromInstance(component, true); break; } case ZenjectBinding.BindTypes.AllInterfacesAndSelf: { - Container.BindAllInterfacesAndSelf(componentType).WithId(identifier).FromInstance(component, true); + Container.Bind(componentType.Interfaces().Append(componentType).ToArray()).WithId(identifier).FromInstance(component, true); break; } default: diff --git a/UnityProject/Assets/Zenject/Source/Install/ZenjectBinding.cs b/UnityProject/Assets/Zenject/Source/Install/ZenjectBinding.cs index 4f0a477b2..0d054ecf0 100644 --- a/UnityProject/Assets/Zenject/Source/Install/ZenjectBinding.cs +++ b/UnityProject/Assets/Zenject/Source/Install/ZenjectBinding.cs @@ -20,7 +20,7 @@ public class ZenjectBinding : MonoBehaviour [FormerlySerializedAs("_compositionRoot")] Context _context = null; - [Tooltip("This value is used to determine how to bind this component. When set to 'Self' is equivalent to calling Container.FromInstance inside an installer. When set to 'AllInterfaces' this is equivalent to calling 'Container.BindAllInterfaces().ToInstance', and similarly for AllInterfacesAndSelf")] + [Tooltip("This value is used to determine how to bind this component. When set to 'Self' is equivalent to calling Container.FromInstance inside an installer. When set to 'AllInterfaces' this is equivalent to calling 'Container.BindInterfaces().ToInstance', and similarly for InterfacesAndSelf")] [SerializeField] BindTypes _bindType = BindTypes.Self; diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 4059fbfac..e4ba07253 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -71,8 +71,16 @@ object CreateLazyBinding(InjectContext context) // By cloning it this also means that Ids, optional, etc. are forwarded properly var newContext = context.Clone(); newContext.MemberType = context.MemberType.GenericArguments().Single(); - return Activator.CreateInstance( + + var result = Activator.CreateInstance( typeof(Lazy<>).MakeGenericType(newContext.MemberType), new object[] { this, newContext }); + + if (_isValidating) + { + ((ILazy)result).Validate(); + } + + return result; } public DiContainer() @@ -266,8 +274,6 @@ public void ValidateIValidatables() List validatableProviders; - Assert.That(!bindingId.Type.IsGenericTypeDefinition()); - var injectContext = new InjectContext( this, bindingId.Type, bindingId.Identifier); @@ -735,7 +741,7 @@ public object InstantiateExplicit(Type concreteType, List extraAr // See comment in IInstantiator.cs for description of this method public object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs args) { -#if PROFILING_ENABLED +#if UNITY_EDITOR using (ProfileBlock.Start("Zenject.Instantiate({0})", concreteType)) #endif { @@ -827,8 +833,8 @@ object InstantiateInternal(Type concreteType, bool autoInject, InjectArgs args) //Log.Debug("Zenject: Instantiating type '{0}'", concreteType); try { -#if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.{0}()", concreteType)) +#if UNITY_EDITOR + using (ProfileBlock.Start("{0}.{1}()", concreteType, concreteType.Name)) #endif { newObj = typeInfo.InjectConstructor.Invoke(paramValues.ToArray()); @@ -959,7 +965,7 @@ public void InjectExplicit( foreach (var method in typeInfo.PostInjectMethods) { -#if PROFILING_ENABLED +#if UNITY_EDITOR using (ProfileBlock.Start("{0}.{1}()", injectableType, method.MethodInfo.Name)) #endif { @@ -1865,7 +1871,7 @@ public ConcreteIdBinderNonGeneric Bind( var bindInfo = new BindInfo(contractTypesList); // This is nice because it allows us to do things like Bind(all interfaces).To() - // (though of course it would be more efficient to use BindAllInterfaces in this case) + // (though of course it would be more efficient to use BindInterfacesTo in this case) bindInfo.InvalidBindResponse = InvalidBindResponses.Skip; return new ConcreteIdBinderNonGeneric(bindInfo, StartBinding()); @@ -1902,38 +1908,38 @@ public void BindRootResolve(object identifier, IEnumerable rootTypes) // { // } // - // Container.BindAllInterfaces().To().AsSingle(); + // Container.BindInterfacesTo().AsSingle(); // // This line above is equivalent to the following: // // Container.Bind().ToSingle(); // Container.Bind().ToSingle(); // - // Note here that we do not bind Foo to itself. For that, use BindAllInterfacesAndSelf - public ConcreteIdBinderNonGeneric BindAllInterfaces() + // Note here that we do not bind Foo to itself. For that, use BindInterfacesAndSelfTo + public FromBinderNonGeneric BindInterfacesTo() { - return BindAllInterfaces(typeof(T)); + return BindInterfacesTo(typeof(T)); } - public ConcreteIdBinderNonGeneric BindAllInterfaces(Type type) + public FromBinderNonGeneric BindInterfacesTo(Type type) { // We must only have one dependency root per container // We need this when calling this with a GameObjectContext - return BindInternal(type.Interfaces().ToArray(), "BindAllInterfaces({0})".Fmt(type)); + return BindInternal(type.Interfaces().ToArray(), "BindInterfacesTo({0})".Fmt(type)).To(type); } - // Same as BindAllInterfaces except also binds to self - public ConcreteIdBinderNonGeneric BindAllInterfacesAndSelf() + // Same as BindInterfaces except also binds to self + public FromBinderNonGeneric BindInterfacesAndSelfTo() { - return BindAllInterfacesAndSelf(typeof(T)); + return BindInterfacesAndSelfTo(typeof(T)); } - public ConcreteIdBinderNonGeneric BindAllInterfacesAndSelf(Type type) + public FromBinderNonGeneric BindInterfacesAndSelfTo(Type type) { // We must only have one dependency root per container // We need this when calling this with a GameObjectContext return Bind( - type.Interfaces().Append(type).ToArray()); + type.Interfaces().Append(type).ToArray()).To(type); } // This is simply a shortcut to using the FromInstance method. diff --git a/UnityProject/Assets/Zenject/Source/Providers/MethodProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/MethodProvider.cs index eb5e93358..e6f4788e5 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/MethodProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/MethodProvider.cs @@ -29,7 +29,7 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co Assert.That(typeof(TReturn).DerivesFromOrEqual(context.MemberType)); - if (_container.IsValidating) + if (_container.IsValidating && !DiContainer.CanCreateOrInjectDuringValidation(context.MemberType)) { yield return new List() { new ValidationMarker(typeof(TReturn)) }; } diff --git a/UnityProject/Assets/Zenject/Source/Providers/MethodProviderUntyped.cs b/UnityProject/Assets/Zenject/Source/Providers/MethodProviderUntyped.cs index f44807530..35e4b06d5 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/MethodProviderUntyped.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/MethodProviderUntyped.cs @@ -27,7 +27,7 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co Assert.IsEmpty(args); Assert.IsNotNull(context); - if (_container.IsValidating) + if (_container.IsValidating && !DiContainer.CanCreateOrInjectDuringValidation(context.MemberType)) { yield return new List() { new ValidationMarker(context.MemberType) }; } diff --git a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs index c8ec09559..fdb2c1606 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderableManager.cs @@ -47,8 +47,8 @@ public void OnGui() { try { -#if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.Initialize()", renderable.Renderable.GetType())) +#if UNITY_EDITOR + using (ProfileBlock.Start("{0}.GuiRender()", renderable.Renderable.GetType())) #endif { renderable.Renderable.GuiRender(); diff --git a/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs index 0febc8441..25c144681 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/InitializableManager.cs @@ -47,7 +47,7 @@ public void Initialize() try { -#if PROFILING_ENABLED +#if UNITY_EDITOR using (ProfileBlock.Start("{0}.Initialize()", initializable.Initializable.GetType())) #endif { diff --git a/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs b/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs index 0ff168256..13e825ac0 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/TaskUpdater.cs @@ -146,8 +146,8 @@ public class TickablesTaskUpdater : TaskUpdater { protected override void UpdateItem(ITickable task) { -#if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.Tick()".Fmt(task.GetType()))) +#if UNITY_EDITOR + using (ProfileBlock.Start("{0}.Tick()", task.GetType())) #endif { task.Tick(); @@ -159,8 +159,8 @@ public class LateTickablesTaskUpdater : TaskUpdater { protected override void UpdateItem(ILateTickable task) { -#if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.LateTick()".Fmt(task.GetType()))) +#if UNITY_EDITOR + using (ProfileBlock.Start("{0}.LateTick()", task.GetType())) #endif { task.LateTick(); @@ -172,8 +172,8 @@ public class FixedTickablesTaskUpdater : TaskUpdater { protected override void UpdateItem(IFixedTickable task) { -#if PROFILING_ENABLED - using (ProfileBlock.Start("{0}.FixedTick()".Fmt(task.GetType()))) +#if UNITY_EDITOR + using (ProfileBlock.Start("{0}.FixedTick()", task.GetType())) #endif { task.FixedTick(); diff --git a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs index fc7f31d31..47c9f123c 100644 --- a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs +++ b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs @@ -6,7 +6,7 @@ namespace Zenject { // If you want to ensure that all items are always returned to the pool, include the following // line in an installer on project context: - // Container.BindAllInterfaces().To().AsSingle().CopyIntoAllSubContainers().NonLazy() + // Container.BindInterfaces().To().AsSingle().CopyIntoAllSubContainers().NonLazy() public class PoolCleanupChecker : ILateDisposable { readonly List _poolFactories; diff --git a/UnityProject/Assets/Zenject/Source/Util/ProfileBlock.cs b/UnityProject/Assets/Zenject/Source/Util/ProfileBlock.cs new file mode 100644 index 000000000..f7f52917a --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Util/ProfileBlock.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text.RegularExpressions; +using System.Xml.Serialization; +using ModestTree; + +#if !NOT_UNITY3D +using UnityEngine; +using UnityEngine.Profiling; +#endif + +namespace Zenject +{ + public class ProfileBlock : IDisposable + { +#if UNITY_EDITOR + static bool _isActive; + + bool _rootBlock; + + ProfileBlock(string sampleName, bool rootBlock) + { + Profiler.BeginSample(sampleName); + _rootBlock = rootBlock; + + if (rootBlock) + { + Assert.That(!_isActive); + _isActive = true; + } + } + + ProfileBlock(string sampleName) + : this(sampleName, false) + { + } + + public static Regex ProfilePattern + { + get; + set; + } + + public static ProfileBlock Start(string sampleNameFormat, object obj1, object obj2) + { + if (!Profiler.enabled) + { + return null; + } + return Start(string.Format(sampleNameFormat, obj1, obj2)); + } + + public static ProfileBlock Start(string sampleNameFormat, object obj) + { + if (!Profiler.enabled) + { + return null; + } + return Start(string.Format(sampleNameFormat, obj)); + } + + public static ProfileBlock Start(string sampleName) + { + if (!Profiler.enabled) + { + return null; + } + + if (ProfilePattern == null || _isActive) + // If we are below one of the regex matches, show all all profile blocks + { + return new ProfileBlock(sampleName); + } + + if (ProfilePattern.Match(sampleName).Success) + { + return new ProfileBlock(sampleName, true); + } + + return null; + } + + public void Dispose() + { + Profiler.EndSample(); + + if (_rootBlock) + { + Assert.That(_isActive); + _isActive = false; + } + } + +#else + ProfileBlock(string sampleName, bool rootBlock) + { + } + + ProfileBlock(string sampleName) + : this(sampleName, false) + { + } + + public static Regex ProfilePattern + { + get; + set; + } + + // Remove the call completely for builds + public static ProfileBlock Start() + { + return null; + } + + // Remove the call completely for builds + public static ProfileBlock Start(string sampleNameFormat, object obj1, object obj2) + { + return null; + } + + // Remove the call completely for builds + public static ProfileBlock Start(string sampleNameFormat, object obj) + { + return null; + } + + // Remove the call completely for builds + public static ProfileBlock Start(string sampleName) + { + return null; + } + + public void Dispose() + { + } +#endif + } +} diff --git a/UnityProject/Assets/Zenject/Source/Util/ProfileBlock.cs.meta b/UnityProject/Assets/Zenject/Source/Util/ProfileBlock.cs.meta new file mode 100644 index 000000000..7f32e1979 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Util/ProfileBlock.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 952433523e6a6e445adc4ac7e2086e7d +timeCreated: 1485104137 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 31b4a36c9f057d383491ef7eeea3255027422389 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 22 Jan 2017 14:38:06 -0400 Subject: [PATCH 22/62] Updated integration tests --- .../Bindings/Editor/TestFromGameObject.cs | 48 +++++ .../Bindings/Editor/TestFromPrefab.cs | 2 +- .../Bindings/Editor/TestFromPrefabResource.cs | 2 +- .../Resources/TestFromPrefab/Foo.prefab | 12 +- .../Resources/TestFromPrefab/Foo2.prefab | 10 +- .../TestFromPrefab/GorpAndQux.prefab | 12 +- .../Resources/TestFromPrefab/JimAndBob.prefab | 12 +- .../Resources/TestFromPrefab/Norf.prefab | 14 +- .../TestFromSubContainerPrefab/Foo.prefab | 28 +-- .../TestFromSubContainerPrefab/Foo2.prefab | 26 +-- .../Factories/Editor/TestBindFactory.cs | 49 +++++ .../IntegrationTests/SceneLoading.meta | 9 + .../SceneLoading/Decorators.meta | 9 + .../SceneLoading/Decorators/Bar.cs | 14 ++ .../SceneLoading/Decorators/Bar.cs.meta | 12 ++ .../Decorators/DecoratorScene.unity | 194 +++++++++++++++++ .../Decorators/DecoratorScene.unity.meta | 8 + .../SceneLoading/Decorators/Editor.meta | 9 + .../Decorators/Editor/TestSceneDecorators.cs | 85 ++++++++ .../Editor/TestSceneDecorators.cs.meta | 12 ++ .../SceneLoading/Decorators/Foo.cs | 11 + .../SceneLoading/Decorators/Foo.cs.meta | 12 ++ .../SceneLoading/Decorators/MainScene.unity | 198 ++++++++++++++++++ .../Decorators/MainScene.unity.meta | 8 + .../SceneLoading/Parenting.meta | 9 + .../SceneLoading/Parenting/Bar.cs | 14 ++ .../SceneLoading/Parenting/Bar.cs.meta | 12 ++ .../SceneLoading/Parenting/ChildScene.unity | 197 +++++++++++++++++ .../Parenting/ChildScene.unity.meta | 8 + .../SceneLoading/Parenting/Editor.meta | 9 + .../Editor/TestSceneParentingName.cs | 85 ++++++++ .../Editor/TestSceneParentingName.cs.meta | 12 ++ .../SceneLoading/Parenting/Foo.cs | 11 + .../SceneLoading/Parenting/Foo.cs.meta | 12 ++ .../SceneLoading/Parenting/ParentScene.unity | 198 ++++++++++++++++++ .../Parenting/ParentScene.unity.meta | 8 + .../SampleGame1 (Beginner)/Resources.meta | 9 + .../{ => Resources}/Installers.meta | 0 .../Installers/GameSettingsInstaller.asset | 0 .../GameSettingsInstaller.asset.meta | 0 40 files changed, 1321 insertions(+), 59 deletions(-) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Bar.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Bar.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/DecoratorScene.unity create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/DecoratorScene.unity.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Foo.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Foo.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/MainScene.unity create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/MainScene.unity.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Bar.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Bar.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ChildScene.unity create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ChildScene.unity.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor/TestSceneParentingName.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor/TestSceneParentingName.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Foo.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Foo.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ParentScene.unity create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ParentScene.unity.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/{ => Resources}/Installers.meta (100%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/{ => Resources}/Installers/GameSettingsInstaller.asset (100%) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/{ => Resources}/Installers/GameSettingsInstaller.asset.meta (100%) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs index ca00cc684..99c4236ad 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs @@ -145,6 +145,54 @@ public void TestMultipleConcreteSingle() FixtureUtil.AssertNumGameObjects(Container, 2); } + + [Test] + public void TestUnderTransformGroup() + { + Container.Bind().FromGameObject() + .WithGameObjectName(GameObjName).UnderTransformGroup("Foo").AsSingle(); + Container.BindRootResolve(); + + Initialize(); + + var root = Container.Resolve().transform; + var child1 = root.GetChild(0); + + Assert.IsEqual(child1.name, "Foo"); + + var child2 = child1.GetChild(0); + + Assert.IsNotNull(child2.GetComponent()); + } + + [Test] + public void TestUnderTransform() + { + var tempGameObject = new GameObject("Foo"); + + Container.Bind().FromGameObject() + .WithGameObjectName(GameObjName).UnderTransform(tempGameObject.transform).AsSingle(); + Container.BindRootResolve(); + + Initialize(); + + Assert.IsNotNull(tempGameObject.transform.GetChild(0).GetComponent()); + } + + [Test] + public void TestUnderTransformGetter() + { + var tempGameObject = new GameObject("Foo"); + + Container.Bind().FromGameObject() + .WithGameObjectName(GameObjName).UnderTransform((context) => tempGameObject.transform).AsSingle(); + Container.BindRootResolve(); + + Initialize(); + + Assert.IsNotNull(tempGameObject.transform.GetChild(0).GetComponent()); + } + public interface IBar { } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs index c7d3ecd4a..656b379d4 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs @@ -176,7 +176,7 @@ public void TestCircularDependencies() { // Jim and Bob both depend on each other Container.Bind(typeof(Jim), typeof(Bob)).FromPrefab(JimAndBobPrefab).AsCached().NonLazy(); - Container.BindAllInterfaces().To().AsSingle().NonLazy(); + Container.BindInterfacesTo().AsSingle().NonLazy(); Initialize(); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs index b3a9dc51e..29f3966f2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs @@ -150,7 +150,7 @@ public void TestCircularDependencies() // Jim and Bob both depend on each other Container.Bind(typeof(Jim), typeof(Bob)).FromPrefabResource(PathPrefix + "JimAndBob").AsCached().NonLazy(); - Container.BindAllInterfaces().To().AsSingle().NonLazy(); + Container.BindInterfacesTo().AsSingle().NonLazy(); Initialize(); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Foo.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Foo.prefab index 365e978ab..ca7c29f98 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Foo.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Foo.prefab @@ -5,18 +5,18 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 496146} - - 114: {fileID: 11420556} - - 114: {fileID: 11472394} + - component: {fileID: 496146} + - component: {fileID: 11420556} + - component: {fileID: 11472394} m_Layer: 0 m_Name: Foo m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &496146 Transform: m_ObjectHideFlags: 1 @@ -26,10 +26,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &11420556 MonoBehaviour: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Foo2.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Foo2.prefab index 96c1b1ac5..38baa94f8 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Foo2.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Foo2.prefab @@ -5,17 +5,17 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 496146} - - 114: {fileID: 11420556} + - component: {fileID: 496146} + - component: {fileID: 11420556} m_Layer: 0 m_Name: Foo2 m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &496146 Transform: m_ObjectHideFlags: 1 @@ -25,10 +25,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &11420556 MonoBehaviour: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab index a1d9d8e83..aceb9451e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab @@ -5,18 +5,18 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 496146} - - 114: {fileID: 11461012} - - 114: {fileID: 11470700} + - component: {fileID: 496146} + - component: {fileID: 11461012} + - component: {fileID: 11470700} m_Layer: 0 m_Name: GorpAndQux m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &496146 Transform: m_ObjectHideFlags: 1 @@ -26,10 +26,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &11461012 MonoBehaviour: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/JimAndBob.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/JimAndBob.prefab index 9ec0a63a8..50d601dae 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/JimAndBob.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/JimAndBob.prefab @@ -5,18 +5,18 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 464534} - - 114: {fileID: 11499784} - - 114: {fileID: 11418142} + - component: {fileID: 464534} + - component: {fileID: 11499784} + - component: {fileID: 11418142} m_Layer: 0 m_Name: JimAndBob m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &464534 Transform: m_ObjectHideFlags: 1 @@ -26,10 +26,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &11418142 MonoBehaviour: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Norf.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Norf.prefab index ab4b6c624..01df16e53 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Norf.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Norf.prefab @@ -5,19 +5,19 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 431222} - - 114: {fileID: 11449184} - - 114: {fileID: 11420968} - - 114: {fileID: 11461460} + - component: {fileID: 431222} + - component: {fileID: 11449184} + - component: {fileID: 11420968} + - component: {fileID: 11461460} m_Layer: 0 m_Name: Norf m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &431222 Transform: m_ObjectHideFlags: 1 @@ -27,10 +27,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &11420968 MonoBehaviour: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromSubContainerPrefab/Foo.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromSubContainerPrefab/Foo.prefab index 8a5f19d73..507324c3f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromSubContainerPrefab/Foo.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromSubContainerPrefab/Foo.prefab @@ -5,36 +5,36 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 436462} - - 114: {fileID: 11426760} - - 114: {fileID: 11423502} + - component: {fileID: 436462} + - component: {fileID: 11426760} + - component: {fileID: 11423502} m_Layer: 0 - m_Name: + m_Name: Foo m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!1 &162920 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 406566} - - 114: {fileID: 11460120} - - 114: {fileID: 11429022} - - 114: {fileID: 11473484} + - component: {fileID: 406566} + - component: {fileID: 11460120} + - component: {fileID: 11429022} + - component: {fileID: 11473484} m_Layer: 0 m_Name: Foo m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &406566 Transform: m_ObjectHideFlags: 1 @@ -44,11 +44,11 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 436462} m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &436462 Transform: m_ObjectHideFlags: 1 @@ -58,10 +58,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 406566} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &11423502 MonoBehaviour: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromSubContainerPrefab/Foo2.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromSubContainerPrefab/Foo2.prefab index 35b3b6d4b..d190b0dd1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromSubContainerPrefab/Foo2.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromSubContainerPrefab/Foo2.prefab @@ -5,35 +5,35 @@ GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 436462} - - 114: {fileID: 11426760} + - component: {fileID: 436462} + - component: {fileID: 11426760} m_Layer: 0 - m_Name: + m_Name: Foo m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!1 &162920 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 + serializedVersion: 5 m_Component: - - 4: {fileID: 406566} - - 114: {fileID: 11460120} - - 114: {fileID: 11429022} - - 114: {fileID: 11473484} + - component: {fileID: 406566} + - component: {fileID: 11460120} + - component: {fileID: 11429022} + - component: {fileID: 11473484} m_Layer: 0 m_Name: Foo2 m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &406566 Transform: m_ObjectHideFlags: 1 @@ -43,11 +43,11 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 436462} m_Father: {fileID: 0} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &436462 Transform: m_ObjectHideFlags: 1 @@ -57,10 +57,10 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 406566} m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &11426760 MonoBehaviour: m_ObjectHideFlags: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs index 51486b6b7..68be401ef 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs @@ -244,6 +244,55 @@ public void TestToSubContainerPrefabResourceConcrete() FixtureUtil.AssertNumGameObjects(Container, 1); } + [Test] + public void TestUnderTransformGroup() + { + Container.BindFactory().FromGameObject().UnderTransformGroup("Foo"); + + Initialize(); + + FixtureUtil.CallFactoryCreateMethod(Container); + + var root = Container.Resolve().transform; + var child1 = root.GetChild(0); + + Assert.IsEqual(child1.name, "Foo"); + + var child2 = child1.GetChild(0); + + Assert.IsNotNull(child2.GetComponent()); + } + + [Test] + public void TestUnderTransform() + { + var tempGameObject = new GameObject("Foo"); + + Container.BindFactory().FromGameObject(). + UnderTransform(tempGameObject.transform); + + Initialize(); + + FixtureUtil.CallFactoryCreateMethod(Container); + + Assert.IsNotNull(tempGameObject.transform.GetChild(0).GetComponent()); + } + + [Test] + public void TestUnderTransformGetter() + { + var tempGameObject = new GameObject("Foo"); + + Container.BindFactory().FromGameObject() + .UnderTransform((context) => tempGameObject.transform); + + Initialize(); + + FixtureUtil.CallFactoryCreateMethod(Container); + + Assert.IsNotNull(tempGameObject.transform.GetChild(0).GetComponent()); + } + public class Foo3 : MonoBehaviour { public class Factory : Factory diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading.meta new file mode 100644 index 000000000..1f5c5d1dc --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a5e76a66633c6304eb27f41402f89ec9 +folderAsset: yes +timeCreated: 1485111023 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators.meta new file mode 100644 index 000000000..64d3c96e4 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 859ab13d5686cea4daddbe0237fee777 +folderAsset: yes +timeCreated: 1477003121 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Bar.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Bar.cs new file mode 100644 index 000000000..70ce2e26e --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Bar.cs @@ -0,0 +1,14 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Zenject.Tests.SceneDecorators +{ + public class Bar : MonoBehaviour + { + [Inject] + public void Construct(Foo foo) + { + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Bar.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Bar.cs.meta new file mode 100644 index 000000000..7750a6b70 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Bar.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 237beb93c79ae954ca5660839e0e7978 +timeCreated: 1477003183 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/DecoratorScene.unity b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/DecoratorScene.unity new file mode 100644 index 000000000..880738b0c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/DecoratorScene.unity @@ -0,0 +1,194 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.37311992, g: 0.38074034, b: 0.35872713, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 4 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_DirectLightInLightProbes: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_LightingDataAsset: {fileID: 0} + m_RuntimeCPUUsage: 25 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + accuratePlacement: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &315770083 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 315770084} + - component: {fileID: 315770086} + - component: {fileID: 315770085} + m_Layer: 0 + m_Name: Foo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &315770084 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 233.15675, y: 367.62057, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &315770085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0166d8ff8d905b048b2448179e1f5d11, type: 3} + m_Name: + m_EditorClassIdentifier: + _components: + - {fileID: 315770086} + _identifier: + _context: {fileID: 0} + _bindType: 0 +--- !u!114 &315770086 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c0ac35096cb539141b563161bbb97dbe, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &794780037 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 794780039} + - component: {fileID: 794780038} + m_Layer: 0 + m_Name: DecoratorContext + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &794780038 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 794780037} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ed7323e8fdd8c26438c6485f2060dad0, type: 3} + m_Name: + m_EditorClassIdentifier: + _installers: [] + _installerPrefabs: [] + _scriptableObjectInstallers: [] + _decoratedContractName: Main +--- !u!4 &794780039 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 794780037} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/DecoratorScene.unity.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/DecoratorScene.unity.meta new file mode 100644 index 000000000..44968b4e9 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/DecoratorScene.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 80012b23843d0014f88fab6775064232 +timeCreated: 1477003182 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor.meta new file mode 100644 index 000000000..aba35d99e --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7129c7b8e7528f74e90fa9ca74420605 +folderAsset: yes +timeCreated: 1477003182 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs new file mode 100644 index 000000000..d207ce8e1 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using ModestTree; +using UnityEngine.SceneManagement; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.SceneDecorators +{ + [TestFixture] + public class TestSceneDecorators + { + const string CommonFolderPath = "Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators"; + const string DecoratorScenePath = CommonFolderPath + "/DecoratorScene.unity"; + const string MainScenePath = CommonFolderPath + "/MainScene.unity"; + + Scene _mainScene; + Scene _decoratorScene; + + [Test] + public void TestValidationPass() + { + ZenUnityEditorUtil.ValidateCurrentSceneSetup(); + } + + [Test] + public void TestValidationFail() + { + _decoratorScene.GetRootGameObjects().Where(x => x.name == "Foo") + .Single().GetComponent().enabled = false; + + Assert.Throws(() => ZenUnityEditorUtil.ValidateCurrentSceneSetup()); + } + + [Test] + public void TestSuccess() + { + ZenUnityEditorUtil.RunCurrentSceneSetup(); + } + + [Test] + public void TestFail() + { + _decoratorScene.GetRootGameObjects().Where(x => x.name == "Foo") + .Single().GetComponent().enabled = false; + + Assert.Throws(() => ZenUnityEditorUtil.RunCurrentSceneSetup()); + } + + [SetUp] + public void SetUp() + { + ClearScene(); + + _decoratorScene = EditorSceneManager.OpenScene(DecoratorScenePath, OpenSceneMode.Additive); + _mainScene = EditorSceneManager.OpenScene(MainScenePath, OpenSceneMode.Additive); + } + + [TearDown] + public void TearDown() + { + EditorSceneManager.CloseScene(_mainScene, true); + EditorSceneManager.CloseScene(_decoratorScene, true); + + ClearScene(); + } + + void ClearScene() + { + var scene = EditorSceneManager.GetActiveScene(); + + // This is the temp scene that unity creates for EditorTestRunner + Assert.IsEqual(scene.name, ""); + + foreach (var gameObject in scene.GetRootGameObjects()) + { + GameObject.DestroyImmediate(gameObject); + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs.meta new file mode 100644 index 000000000..1e3c05273 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d70a1bb388fdc7441809f18139532a04 +timeCreated: 1477003183 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Foo.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Foo.cs new file mode 100644 index 000000000..fad558dbd --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Foo.cs @@ -0,0 +1,11 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Zenject.Tests.SceneDecorators +{ + public class Foo : MonoBehaviour + { + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Foo.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Foo.cs.meta new file mode 100644 index 000000000..0026200d2 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Foo.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cfeb72ed97ffd174ea4f5493c3a36512 +timeCreated: 1477003183 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/MainScene.unity b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/MainScene.unity new file mode 100644 index 000000000..416bc5508 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/MainScene.unity @@ -0,0 +1,198 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.37311992, g: 0.38074034, b: 0.35872713, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 4 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_DirectLightInLightProbes: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_LightingDataAsset: {fileID: 0} + m_RuntimeCPUUsage: 25 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + accuratePlacement: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &315770083 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 315770084} + - component: {fileID: 315770086} + - component: {fileID: 315770085} + m_Layer: 0 + m_Name: Bar + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &315770084 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 233.15675, y: 367.62057, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &315770085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0166d8ff8d905b048b2448179e1f5d11, type: 3} + m_Name: + m_EditorClassIdentifier: + _components: + - {fileID: 315770086} + _identifier: + _context: {fileID: 0} + _bindType: 0 +--- !u!114 &315770086 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 270504f9c934f984c9d51d01689ae664, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &880306062 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 880306064} + - component: {fileID: 880306063} + m_Layer: 0 + m_Name: SceneContext + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &880306063 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 880306062} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 89715ad69b973a14899afa2c6730b30b, type: 3} + m_Name: + m_EditorClassIdentifier: + _installers: [] + _installerPrefabs: [] + _scriptableObjectInstallers: [] + _parentNewObjectsUnderRoot: 0 + _contractNames: + - Main + _parentContractName: + _autoRun: 1 +--- !u!4 &880306064 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 880306062} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/MainScene.unity.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/MainScene.unity.meta new file mode 100644 index 000000000..c3a6fef40 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/MainScene.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 77380fc0aa94cf34aa1976283f7cbfec +timeCreated: 1477003182 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting.meta new file mode 100644 index 000000000..37f8f026a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 747b54134789b6c4dbb0eef4efa5ba20 +folderAsset: yes +timeCreated: 1476908356 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Bar.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Bar.cs new file mode 100644 index 000000000..30c8fd97a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Bar.cs @@ -0,0 +1,14 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Zenject.Tests.SceneParenting +{ + public class Bar : MonoBehaviour + { + [Inject] + public void Construct(Foo foo) + { + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Bar.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Bar.cs.meta new file mode 100644 index 000000000..6976fa93c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Bar.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 270504f9c934f984c9d51d01689ae664 +timeCreated: 1476912248 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ChildScene.unity b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ChildScene.unity new file mode 100644 index 000000000..a9c8ac53d --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ChildScene.unity @@ -0,0 +1,197 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.37311992, g: 0.38074034, b: 0.35872713, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 4 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_DirectLightInLightProbes: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_LightingDataAsset: {fileID: 0} + m_RuntimeCPUUsage: 25 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + accuratePlacement: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &315770083 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 315770084} + - component: {fileID: 315770086} + - component: {fileID: 315770085} + m_Layer: 0 + m_Name: Bar + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &315770084 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 233.15675, y: 367.62057, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &315770085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0166d8ff8d905b048b2448179e1f5d11, type: 3} + m_Name: + m_EditorClassIdentifier: + _components: + - {fileID: 315770086} + _identifier: + _context: {fileID: 0} + _bindType: 0 +--- !u!114 &315770086 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 270504f9c934f984c9d51d01689ae664, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &880306062 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 880306064} + - component: {fileID: 880306063} + m_Layer: 0 + m_Name: SceneContext + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &880306063 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 880306062} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 89715ad69b973a14899afa2c6730b30b, type: 3} + m_Name: + m_EditorClassIdentifier: + _installers: [] + _installerPrefabs: [] + _scriptableObjectInstallers: [] + _parentNewObjectsUnderRoot: 0 + _contractName: + _parentContractName: Parent + _autoRun: 1 +--- !u!4 &880306064 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 880306062} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ChildScene.unity.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ChildScene.unity.meta new file mode 100644 index 000000000..1f9139e0b --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ChildScene.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: adefd26c142de6d46a417c7c3e1bd0ab +timeCreated: 1476894914 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor.meta new file mode 100644 index 000000000..88d283367 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1a492bcda0af9ad4d8e00ec857ee0b00 +folderAsset: yes +timeCreated: 1476910544 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor/TestSceneParentingName.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor/TestSceneParentingName.cs new file mode 100644 index 000000000..d9ec96d15 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor/TestSceneParentingName.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using ModestTree; +using UnityEngine.SceneManagement; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.SceneParenting +{ + [TestFixture] + public class TestSceneParentingName + { + const string CommonFolderPath = "Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting"; + const string ParentScenePath = CommonFolderPath + "/ParentScene.unity"; + const string ChildScenePath = CommonFolderPath + "/ChildScene.unity"; + + Scene _childScene; + Scene _parentScene; + + [Test] + public void TestValidationPass() + { + ZenUnityEditorUtil.ValidateCurrentSceneSetup(); + } + + [Test] + public void TestValidationFail() + { + _parentScene.GetRootGameObjects().Where(x => x.name == "Foo") + .Single().GetComponent().enabled = false; + + Assert.Throws(() => ZenUnityEditorUtil.ValidateCurrentSceneSetup()); + } + + [Test] + public void TestSuccess() + { + ZenUnityEditorUtil.RunCurrentSceneSetup(); + } + + [Test] + public void TestFail() + { + _parentScene.GetRootGameObjects().Where(x => x.name == "Foo") + .Single().GetComponent().enabled = false; + + Assert.Throws(() => ZenUnityEditorUtil.RunCurrentSceneSetup()); + } + + [SetUp] + public void SetUp() + { + ClearScene(); + + _parentScene = EditorSceneManager.OpenScene(ParentScenePath, OpenSceneMode.Additive); + _childScene = EditorSceneManager.OpenScene(ChildScenePath, OpenSceneMode.Additive); + } + + [TearDown] + public void TearDown() + { + EditorSceneManager.CloseScene(_childScene, true); + EditorSceneManager.CloseScene(_parentScene, true); + + ClearScene(); + } + + void ClearScene() + { + var scene = EditorSceneManager.GetActiveScene(); + + // This is the temp scene that unity creates for EditorTestRunner + Assert.IsEqual(scene.name, ""); + + foreach (var gameObject in scene.GetRootGameObjects()) + { + GameObject.DestroyImmediate(gameObject); + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor/TestSceneParentingName.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor/TestSceneParentingName.cs.meta new file mode 100644 index 000000000..cec2d1010 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Editor/TestSceneParentingName.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 954258f04db1948478ae3c2030adb767 +timeCreated: 1476910553 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Foo.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Foo.cs new file mode 100644 index 000000000..125147ad6 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Foo.cs @@ -0,0 +1,11 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Zenject.Tests.SceneParenting +{ + public class Foo : MonoBehaviour + { + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Foo.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Foo.cs.meta new file mode 100644 index 000000000..da911fcbe --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/Foo.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c0ac35096cb539141b563161bbb97dbe +timeCreated: 1476912245 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ParentScene.unity b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ParentScene.unity new file mode 100644 index 000000000..54b117a0d --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ParentScene.unity @@ -0,0 +1,198 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.37311992, g: 0.38074034, b: 0.35872713, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 4 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_DirectLightInLightProbes: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_LightingDataAsset: {fileID: 0} + m_RuntimeCPUUsage: 25 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + accuratePlacement: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &315770083 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 315770084} + - component: {fileID: 315770086} + - component: {fileID: 315770085} + m_Layer: 0 + m_Name: Foo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &315770084 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 233.15675, y: 367.62057, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &315770085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0166d8ff8d905b048b2448179e1f5d11, type: 3} + m_Name: + m_EditorClassIdentifier: + _components: + - {fileID: 315770086} + _identifier: + _context: {fileID: 0} + _bindType: 0 +--- !u!114 &315770086 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 315770083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c0ac35096cb539141b563161bbb97dbe, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &880306062 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 880306064} + - component: {fileID: 880306063} + m_Layer: 0 + m_Name: SceneContext + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &880306063 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 880306062} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 89715ad69b973a14899afa2c6730b30b, type: 3} + m_Name: + m_EditorClassIdentifier: + _installers: [] + _installerPrefabs: [] + _scriptableObjectInstallers: [] + _parentNewObjectsUnderRoot: 0 + _contractNames: + - Parent + _parentContractName: + _autoRun: 1 +--- !u!4 &880306064 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 880306062} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ParentScene.unity.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ParentScene.unity.meta new file mode 100644 index 000000000..fe44ed932 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Parenting/ParentScene.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7b70e4f9240d2eb45ad7507b008eaf9b +timeCreated: 1476894914 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta new file mode 100644 index 000000000..7e5d150a8 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b52899dcc226b7648900113d48a0550f +folderAsset: yes +timeCreated: 1485111074 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Installers/GameSettingsInstaller.asset.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources/Installers/GameSettingsInstaller.asset.meta From 0f446127c4a63699f8a4699bcd8259ca3cba3cb1 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 27 Jan 2017 17:59:08 -0400 Subject: [PATCH 23/62] Removed the unnecessary Validate() function in DiContainer and also fixed to not bother saving the _processedBindings --- .../SampleGame1 (Beginner)/Resources.meta | 4 +- .../BindFeatures/TestMultipleContractTypes.cs | 4 - .../TestMultipleContractTypes2.cs | 8 +- .../TestMultipleContractTypes3.cs | 2 - .../Editor/BindFeatures/TestNonLazy.cs | 3 - .../Editor/BindFeatures/TestRebind.cs | 2 - .../Editor/BindFeatures/TestUnbind.cs | 2 - .../Editor/BindFeatures/TestWithArguments.cs | 4 - .../UnitTests/Editor/Bindings/TestTo.cs | 42 ------- .../Editor/Bindings/TestToFactory.cs | 14 --- .../UnitTests/Editor/Bindings/TestToGetter.cs | 6 - .../Editor/Bindings/TestToInstance.cs | 6 - .../UnitTests/Editor/Bindings/TestToMethod.cs | 18 --- .../Editor/Bindings/TestToResolve.cs | 24 ---- .../Bindings/TestToSubContainerInstaller.cs | 16 --- .../Bindings/TestToSubContainerMethod.cs | 24 ---- .../Editor/Conditions/TestConditionsBasic.cs | 4 - .../Conditions/TestConditionsComplex.cs | 2 - .../Conditions/TestConditionsFieldName.cs | 4 - .../Conditions/TestConditionsIdentifier.cs | 16 --- .../Conditions/TestConditionsParents.cs | 10 -- .../Editor/Conditions/TestConditionsTarget.cs | 4 - .../Editor/Conditions/TestIdentifiers.cs | 10 -- .../Factories/Bindings/TestFactoryTo0.cs | 8 -- .../Factories/Bindings/TestFactoryTo1.cs | 4 - .../Factories/Bindings/TestFactoryTo5.cs | 6 - .../Bindings/TestFactoryToFactory0.cs | 6 +- .../Bindings/TestFactoryToFactory1.cs | 4 - .../Bindings/TestFactoryToGetter0.cs | 2 - .../Bindings/TestFactoryToInstance0.cs | 4 - .../Bindings/TestFactoryToMethod0.cs | 4 - .../Bindings/TestFactoryToMethod1.cs | 4 - .../Bindings/TestFactoryToResolve0.cs | 8 -- .../TestFactoryToSubContainerInstaller0.cs | 4 - .../TestFactoryToSubContainerInstaller1.cs | 4 - .../TestFactoryToSubContainerMethod0.cs | 4 - .../TestFactoryToSubContainerMethod1.cs | 4 - .../Bindings/TestPooledFactoryTo0.cs | 2 - .../Editor/Factories/IFactory/TestIFactory.cs | 6 - .../UnitTests/Editor/Factories/TestFactory.cs | 2 - .../Editor/Injection/TestAllInjectionTypes.cs | 2 - .../TestBaseClassPropertyInjection.cs | 2 - .../Injection/TestCircularDependencies.cs | 9 -- .../Injection/TestConstructorInjection.cs | 2 - .../TestConstructorInjectionOptional.cs | 2 - .../Injection/TestDuplicateInjection.cs | 2 - .../Editor/Injection/TestNullableValues.cs | 4 - .../Editor/Injection/TestParameters.cs | 2 - .../Editor/Injection/TestPostInjectCall.cs | 8 -- .../Injection/TestPostInjectParameters.cs | 2 - .../Editor/Injection/TestPropertyInjection.cs | 2 - .../Editor/Injection/TestStructInjection.cs | 2 +- .../Editor/Injection/TestTestOptional.cs | 26 ----- .../Editor/Other/TestGenericContract.cs | 4 - .../Editor/Other/TestValidateInstaller.cs | 106 ------------------ .../Other/TestValidateInstaller.cs.meta | 12 -- .../UnitTests/Editor/Util/TestLazy.cs | 4 - .../UnitTests/Editor/Validation.meta | 9 -- .../Editor/Validation/TestValidate1.cs | 45 -------- .../Editor/Validation/TestValidate1.cs.meta | 12 -- .../Validation/TestValidateFactories.cs | 47 -------- .../Validation/TestValidateFactories.cs.meta | 12 -- .../Assets/Zenject/Source/Main/DiContainer.cs | 70 +++--------- 63 files changed, 18 insertions(+), 673 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestValidateInstaller.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestValidateInstaller.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidate1.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidate1.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidateFactories.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidateFactories.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta index 7e5d150a8..f08fae9d0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Resources.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: b52899dcc226b7648900113d48a0550f +guid: 8cdb112b0507d3140abad125b6a7fe9e folderAsset: yes -timeCreated: 1485111074 +timeCreated: 1485554692 licenseType: Free DefaultImporter: userData: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes.cs index ff8ae41dd..b1e3459cd 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes.cs @@ -47,8 +47,6 @@ public void TestMultiBind1() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test1 = Container.Resolve(); Assert.That(test1.tests.Count == 2); @@ -61,8 +59,6 @@ public void TestMultiBindListInjection() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test = Container.Resolve(); Assert.That(test.tests.Count == 2); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs index 59e22e1f4..975456d4f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs @@ -37,8 +37,6 @@ public void Test1() Container.Bind(types).AsSingle().NonLazy(); - Container.Validate(); - Container.Resolve(); Container.Resolve(); } @@ -49,7 +47,7 @@ public void TestInterfaces() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); + Container.Resolve(); } [Test] @@ -57,8 +55,6 @@ public void TestAllInterfaces() { Container.BindInterfacesTo().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNull(Container.TryResolve()); Assert.IsNotNull(Container.Resolve()); Assert.IsNotNull(Container.Resolve()); @@ -69,8 +65,6 @@ public void TestAllInterfacesAndSelf() { Container.BindInterfacesAndSelfTo().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsNotNull(Container.Resolve()); Assert.IsNotNull(Container.Resolve()); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes3.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes3.cs index 6ba420b8a..7a1be4b62 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes3.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes3.cs @@ -51,8 +51,6 @@ public void TestMultiBind2() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Container.Resolve(); } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestNonLazy.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestNonLazy.cs index 72984668a..dda4cf829 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestNonLazy.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestNonLazy.cs @@ -11,7 +11,6 @@ public void Test1() { Container.Bind().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); Assert.Throws(() => Container.ResolveDependencyRoots()); } @@ -20,7 +19,6 @@ public void Test2() { Container.Bind().AsSingle(); - Container.Validate(); Container.ResolveDependencyRoots(); } @@ -30,7 +28,6 @@ public void Test3() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle(); - Container.Validate(); Container.ResolveDependencyRoots(); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestRebind.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestRebind.cs index c98a7c246..6e3c2afb2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestRebind.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestRebind.cs @@ -25,12 +25,10 @@ public void Run() Container.Bind().To().AsSingle(); Assert.That(Container.Resolve() is Test2); - Container.Validate(); Container.Rebind().To().AsSingle(); Assert.That(Container.Resolve() is Test3); - Container.Validate(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestUnbind.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestUnbind.cs index 326ae472c..b1b454dec 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestUnbind.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestUnbind.cs @@ -21,12 +21,10 @@ public void Run() Container.Bind().To().AsSingle(); Assert.IsNotNull(Container.Resolve()); - Container.Validate(); Container.Unbind(); Assert.IsNull(Container.TryResolve()); - Container.Validate(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestWithArguments.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestWithArguments.cs index 1872f0bd9..29a7d2838 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestWithArguments.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestWithArguments.cs @@ -15,8 +15,6 @@ public void Test1() { Container.Bind().AsTransient().WithArguments(3).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Value, 3); } @@ -26,8 +24,6 @@ public void TestSingleSameArgument() Container.Bind().To().AsSingle().WithArguments(3).NonLazy(); Container.Bind().AsSingle().WithArguments(3).NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs index 991bbb5ee..573386d15 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs @@ -16,8 +16,6 @@ public void TestSelfSingle() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -27,8 +25,6 @@ public void TestSelfSingleExplicit() { Container.Bind().ToSelf().FromNew().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -38,8 +34,6 @@ public void TestSelfTransient() { Container.Bind().AsTransient().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsNotEqual(Container.Resolve(), Container.Resolve()); } @@ -49,8 +43,6 @@ public void TestSelfCached() { Container.Bind().AsCached().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -61,8 +53,6 @@ public void TestConcreteSingle() Container.Bind().AsSingle().NonLazy(); Container.Bind().To().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsNotNull(Container.Resolve()); @@ -76,8 +66,6 @@ public void TestConcreteTransient() { Container.Bind().To().AsTransient().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsNotEqual(Container.Resolve(), Container.Resolve()); } @@ -87,8 +75,6 @@ public void TestConcreteTransient2() { Container.Bind().To().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsNotEqual(Container.Resolve(), Container.Resolve()); } @@ -99,8 +85,6 @@ public void TestConcreteCached() Container.Bind().AsCached().NonLazy(); Container.Bind().To().AsCached().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsNotNull(Container.Resolve()); @@ -115,8 +99,6 @@ public void TestDuplicateBindingsFail() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Assert.Throws( delegate { Container.Resolve(); }); @@ -128,8 +110,6 @@ public void TestConcreteMultipleTransient() { Container.Bind().To(typeof(Foo), typeof(Bar)).AsTransient().NonLazy(); - Container.Validate(); - var foos = Container.ResolveAll(); Assert.IsEqual(foos.Count, 2); @@ -147,8 +127,6 @@ public void TestConcreteMultipleSingle() { Container.Bind().To(typeof(Foo), typeof(Bar)).AsSingle().NonLazy(); - Container.Validate(); - var foos = Container.ResolveAll(); Assert.IsEqual(foos.Count, 2); @@ -182,8 +160,6 @@ public void TestMultipleBindingsSingle() { Container.Bind(typeof(IFoo), typeof(IBar)).To().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.That(Container.Resolve() is Foo); } @@ -193,8 +169,6 @@ public void TestMultipleBindingsTransient() { Container.Bind(typeof(IFoo), typeof(IBar)).To().AsTransient().NonLazy(); - Container.Validate(); - Assert.That(Container.Resolve() is Foo); Assert.That(Container.Resolve() is Foo); @@ -207,8 +181,6 @@ public void TestMultipleBindingsCached() { Container.Bind(typeof(IFoo), typeof(IBar)).To().AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -220,8 +192,6 @@ public void TestMultipleBindingsConcreteMultipleSingle() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var foos = Container.ResolveAll(); var bars = Container.ResolveAll(); @@ -243,8 +213,6 @@ public void TestMultipleBindingsConcreteMultipleTransient() { Container.Bind(typeof(IFoo), typeof(IBar)).To(new List() {typeof(Foo), typeof(Bar)}).AsTransient().NonLazy(); - Container.Validate(); - var foos = Container.ResolveAll(); var bars = Container.ResolveAll(); @@ -265,8 +233,6 @@ public void TestMultipleBindingsConcreteMultipleCached() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var foos = Container.ResolveAll(); var bars = Container.ResolveAll(); @@ -290,8 +256,6 @@ public void TestSingletonIdsSameIdsSameInstance() Container.Bind().To().AsSingle("foo").NonLazy(); Container.Bind().AsSingle("foo").NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -302,8 +266,6 @@ public void TestSingletonIdsDifferentIdsDifferentInstances() Container.Bind().To().AsSingle("foo").NonLazy(); Container.Bind().AsSingle("bar").NonLazy(); - Container.Validate(); - Assert.IsNotEqual(Container.Resolve(), Container.Resolve()); } @@ -313,8 +275,6 @@ public void TestSingletonIdsNoIdDifferentInstances() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().AsSingle("bar").NonLazy(); - Container.Validate(); - Assert.IsNotEqual(Container.Resolve(), Container.Resolve()); } @@ -326,8 +286,6 @@ public void TestSingletonIdsManyInstances() Container.Bind().To().AsSingle("foo3").NonLazy(); Container.Bind().To().AsSingle("foo4").NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.ResolveAll().Count, 4); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs index 4235b86d2..57493f81d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs @@ -20,8 +20,6 @@ public void TestSelfSingle() Container.Bind().FromFactory().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), StaticFoo); Container.Resolve(); @@ -38,8 +36,6 @@ public void TestConcreteSingle() Container.Bind().To().FromFactory().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), StaticFoo); Container.Resolve(); @@ -57,8 +53,6 @@ public void TestSelfAndConcreteSingle() Container.Bind().FromFactory().AsSingle().NonLazy(); Container.Bind().To().FromFactory().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), StaticFoo); Assert.IsEqual(Container.Resolve(), StaticFoo); @@ -76,8 +70,6 @@ public void TestSelfTransient() Container.Bind().FromFactory().AsTransient().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), StaticFoo); Container.Resolve(); @@ -94,8 +86,6 @@ public void TestConcreteTransient() Container.Bind().To().FromFactory().AsTransient().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), StaticFoo); Container.Resolve(); @@ -112,8 +102,6 @@ public void TestSelfCached() Container.Bind().FromFactory().AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), StaticFoo); Container.Resolve(); @@ -130,8 +118,6 @@ public void TestConcreteCached() Container.Bind().To().FromFactory().AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), StaticFoo); Container.Resolve(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs index 7c01f5e0e..a8b16065e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs @@ -16,8 +16,6 @@ public void TestTransient() Container.Bind().AsSingle().NonLazy(); Container.Bind().FromResolveGetter(x => x.Bar).AsTransient().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve().Bar); @@ -36,8 +34,6 @@ public void TestCached() Container.Bind().AsSingle().NonLazy(); Container.Bind().FromResolveGetter(x => x.Bar).AsCached().NonLazy(); - Container.Validate(); - Foo.NumCalls = 0; Container.Resolve(); @@ -57,8 +53,6 @@ public void TestSingle() // Not sure why I need to specify the "().To().FromResolveGetter(BarGetter).AsSingle().NonLazy(); - Container.Validate(); - Foo.NumCalls = 0; Assert.IsEqual(Container.Resolve(), Foo.StaticBar); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs index 04529f69f..bd2e0ae80 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs @@ -19,8 +19,6 @@ public void TestTransient() Container.Bind().FromInstance(foo).NonLazy(); Container.Bind().FromInstance(foo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), foo); } @@ -32,8 +30,6 @@ public void TestSingle() Container.Bind().FromInstance(new Foo()).AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Container.Resolve(); } @@ -46,8 +42,6 @@ public void TestCached() Container.Bind().FromInstance(foo).AsCached().NonLazy(); Container.Bind().FromInstance(foo).AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), foo); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs index c1ff10113..ff3d4b6c9 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs @@ -18,8 +18,6 @@ public void TestSingle() Container.Bind().FromMethod((ctx) => foo).AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), foo); } @@ -30,8 +28,6 @@ public void TestTransient() Container.Bind().FromMethod((ctx) => foo).AsTransient().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), foo); } @@ -42,8 +38,6 @@ public void TestCached() Container.Bind().FromMethod((ctx) => foo).AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), foo); } @@ -54,8 +48,6 @@ public void TestSingleConflict() Container.Bind().FromMethod((ctx) => new Foo()).AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Container.ResolveAll(); } @@ -68,8 +60,6 @@ public void TestSingle2() Container.Bind().FromMethod(method).AsSingle().NonLazy(); Container.Bind().To().FromMethod(method).AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), foo); @@ -81,8 +71,6 @@ public void TestSingle3() Container.Bind().FromMethod(CreateFoo).AsSingle().NonLazy(); Container.Bind().To().FromMethod(CreateFoo).AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -106,8 +94,6 @@ public void TestSingle4() Container.Bind().FromMethod(method).AsSingle().NonLazy(); Container.Bind().To().FromMethod(method).AsSingle().NonLazy(); - Container.Validate(); - Container.Resolve(); Container.Resolve(); Container.Resolve(); @@ -130,8 +116,6 @@ public void TestTransient2() Container.Bind().FromMethod(method).AsTransient().NonLazy(); Container.Bind().To().FromMethod(method).AsTransient().NonLazy(); - Container.Validate(); - Container.Resolve(); Container.Resolve(); Container.Resolve(); @@ -145,8 +129,6 @@ public void TestCached2() { Container.Bind(typeof(Foo), typeof(IFoo)).To().FromMethod((ctx) => new Foo()).AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs index 1c9817cff..09879ac27 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs @@ -19,8 +19,6 @@ public void TestTransient() Container.BindInstance(foo).NonLazy(); Container.Bind().To().FromResolve().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), foo); } @@ -33,8 +31,6 @@ public void TestIdentifier() Container.Bind().WithId("foo").FromInstance(foo).NonLazy(); Container.Bind().To().FromResolve("foo").NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve("foo")); Assert.IsEqual(Container.Resolve(), foo); } @@ -46,8 +42,6 @@ public void TestCached() Container.Bind().To().FromResolve().AsCached().NonLazy(); - Container.Validate(); - Assert.IsNotEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -59,8 +53,6 @@ public void TestSingle() Container.Bind().To().FromResolve().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -72,8 +64,6 @@ public void TestSingleFailure() Container.Bind().AsSingle().NonLazy(); Container.Bind().To().FromResolve().AsSingle().NonLazy(); - Container.Validate(); - Container.Resolve(); } @@ -82,8 +72,6 @@ public void TestInfiniteLoop() { Container.Bind().To().FromResolve().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws(() => Container.Resolve()); } @@ -95,8 +83,6 @@ public void TestResolveManyTransient() Container.Bind().To().FromResolve().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.ResolveAll().Count, 2); } @@ -108,8 +94,6 @@ public void TestResolveManyTransient2() Container.Bind(typeof(IFoo), typeof(IBar)).To().FromResolve().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.ResolveAll().Count, 2); Assert.IsEqual(Container.ResolveAll().Count, 2); } @@ -122,8 +106,6 @@ public void TestResolveManyCached() Container.Bind().To().FromResolve().AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.ResolveAll().Count, 2); Assert.That(Enumerable.SequenceEqual(Container.ResolveAll(), Container.ResolveAll())); } @@ -136,8 +118,6 @@ public void TestResolveManyCached2() Container.Bind(typeof(IFoo), typeof(IBar)).To().FromResolve().AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.ResolveAll().Count, 2); Assert.IsEqual(Container.ResolveAll().Count, 2); Assert.That(Enumerable.SequenceEqual(Container.ResolveAll().Cast(), Container.ResolveAll().Cast())); @@ -152,8 +132,6 @@ public void TestResolveManyCached3() Container.Bind().To().FromResolve().AsCached().NonLazy(); Container.Bind().To().FromResolve().AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.ResolveAll().Count, 2); Assert.IsEqual(Container.ResolveAll().Count, 2); Assert.That(!Enumerable.SequenceEqual(Container.ResolveAll().Cast(), Container.ResolveAll().Cast())); @@ -169,8 +147,6 @@ public void TestResolveManySingle() Container.Bind().To().FromResolve().AsSingle().NonLazy(); Container.Bind().To().FromResolve().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.ResolveAll().Count, 2); Assert.IsEqual(Container.ResolveAll().Count, 2); Assert.That(Enumerable.SequenceEqual(Container.ResolveAll().Cast(), Container.ResolveAll().Cast())); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs index 65df60cad..bab6ae033 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs @@ -16,8 +16,6 @@ public void TestInstallerSelfSingle() { Container.Bind().FromSubContainerResolve().ByInstaller().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -26,8 +24,6 @@ public void TestInstallerSelfTransient() { Container.Bind().FromSubContainerResolve().ByInstaller().AsTransient().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -36,8 +32,6 @@ public void TestInstallerSelfCached() { Container.Bind().FromSubContainerResolve().ByInstaller().AsCached().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -47,8 +41,6 @@ public void TestInstallerSelfSingleMultipleContracts() Container.Bind().FromSubContainerResolve().ByInstaller().AsSingle().NonLazy(); Container.Bind().FromSubContainerResolve().ByInstaller().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Bar, Container.Resolve()); } @@ -57,8 +49,6 @@ public void TestInstallerSelfCachedMultipleContracts() { Container.Bind(typeof(Foo), typeof(IFoo)).To().FromSubContainerResolve().ByInstaller().AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -67,8 +57,6 @@ public void TestInstallerSelfSingleMultipleMatches() { Container.Bind().FromSubContainerResolve().ByInstaller().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.ResolveAll().Count, 2); } @@ -77,8 +65,6 @@ public void TestInstallerSelfIdentifiersFails() { Container.Bind().FromSubContainerResolve().ByInstaller().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws(() => Container.Resolve()); } @@ -87,8 +73,6 @@ public void TestInstallerSelfIdentifiers() { Container.Bind().FromSubContainerResolve("gorp").ByInstaller().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs index b72490736..1a5910761 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs @@ -16,8 +16,6 @@ public void TestMethodSelfSingle() { Container.Bind().FromSubContainerResolve().ByMethod(InstallFooFacade).AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -26,8 +24,6 @@ public void TestMethodSelfTransient() { Container.Bind().FromSubContainerResolve().ByMethod(InstallFooFacade).AsTransient().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -44,8 +40,6 @@ public void TestMethodSelfCached() { Container.Bind().FromSubContainerResolve().ByMethod(InstallFooFacade).AsCached().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -55,8 +49,6 @@ public void TestMethodSelfSingleMultipleContracts() Container.Bind().FromSubContainerResolve().ByMethod(InstallFooFacade).AsSingle().NonLazy(); Container.Bind().FromSubContainerResolve().ByMethod(InstallFooFacade).AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Bar, Container.Resolve()); } @@ -65,8 +57,6 @@ public void TestMethodSelfCachedMultipleContracts() { Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByMethod(InstallFooFacade).AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Bar, Container.Resolve()); } @@ -75,8 +65,6 @@ public void TestMethodConcreteSingle() { Container.Bind().To().FromSubContainerResolve().ByMethod(InstallFooFacade).AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -85,8 +73,6 @@ public void TestMethodConcreteTransient() { Container.Bind().To().FromSubContainerResolve().ByMethod(InstallFooFacade).AsTransient().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -95,8 +81,6 @@ public void TestMethodConcreteCached() { Container.Bind().To().FromSubContainerResolve().ByMethod(InstallFooFacade).AsCached().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Bar); } @@ -106,8 +90,6 @@ public void TestMethodConcreteSingleMultipleContracts() Container.Bind().To().FromSubContainerResolve().ByMethod(InstallFooFacade).AsSingle().NonLazy(); Container.Bind().FromSubContainerResolve().ByMethod(InstallFooFacade).AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Bar, Container.Resolve()); } @@ -116,8 +98,6 @@ public void TestMethodConcreteCachedMultipleContracts() { Container.Bind(typeof(Foo), typeof(IFoo)).To().FromSubContainerResolve().ByMethod(InstallFooFacade).AsCached().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve(), Container.Resolve()); } @@ -126,8 +106,6 @@ public void TestMethodSelfIdentifiersFails() { Container.Bind().FromSubContainerResolve().ByMethod(InstallFooFacade).AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws(() => Container.Resolve()); } @@ -136,8 +114,6 @@ public void TestMethodSelfIdentifiers() { Container.Bind().FromSubContainerResolve("gorp").ByMethod(InstallFooFacade).AsSingle().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsBasic.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsBasic.cs index 1a6d4ebf1..979fd3639 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsBasic.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsBasic.cs @@ -51,8 +51,6 @@ public void Test1() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().To().AsSingle().WhenInjectedInto().NonLazy(); - Container.Validate(); - Assert.IsNotEqual( Container.Resolve().Foo, Container.Resolve().Foo); } @@ -65,8 +63,6 @@ public void Test2() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().To().AsSingle().WhenNotInjectedInto().NonLazy(); - Container.Validate(); - Assert.IsNotEqual( Container.Resolve().Foo, Container.Resolve().Foo); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsComplex.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsComplex.cs index f59572100..3e93151dc 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsComplex.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsComplex.cs @@ -35,8 +35,6 @@ public void TestCorrespondingIdentifiers() Container.BindInstance(foo1).When(c => c.ParentContexts.Where(x => x.MemberType == typeof(Bar) && object.Equals(x.Identifier, "Bar1")).Any()); Container.BindInstance(foo2).When(c => c.ParentContexts.Where(x => x.MemberType == typeof(Bar) && object.Equals(x.Identifier, "Bar2")).Any()); - Container.Validate(); - Assert.IsEqual(Container.Resolve("Bar1").Foo, foo1); Assert.IsEqual(Container.Resolve("Bar2").Foo, foo2); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsFieldName.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsFieldName.cs index 18f41c2b8..7e30f34ba 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsFieldName.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsFieldName.cs @@ -43,8 +43,6 @@ public void TestNameConditionError() Assert.Throws( delegate { Container.Resolve(); }); - - Assert.Throws(() => Container.Validate()); } [Test] @@ -52,8 +50,6 @@ public void TestNameConditionSuccess() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test1 = Container.Resolve(); Assert.That(test1 != null); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsIdentifier.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsIdentifier.cs index 435610724..3f191468a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsIdentifier.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsIdentifier.cs @@ -36,8 +36,6 @@ public void TestUnspecifiedNameConstructorInjection() Container.Bind().AsTransient().NonLazy(); Container.Bind().AsTransient().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -50,8 +48,6 @@ public void TestUnspecifiedNameFieldInjection() Container.Bind().AsTransient().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -65,8 +61,6 @@ public void TestSuccessConstructorInjectionString() Container.Bind().FromInstance(new Test0()).NonLazy(); Container.Bind().WithId("foo").FromInstance(new Test0()).NonLazy(); - Container.Validate(); - // Should not throw exceptions Container.Resolve(); @@ -82,8 +76,6 @@ public void TestSuccessFieldInjectionString() Container.Bind().FromInstance(new Test0()).NonLazy(); Container.Bind().WithId("foo").FromInstance(new Test0()).NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); } @@ -111,8 +103,6 @@ public void TestFailConstructorInjectionEnum() Container.Bind().FromInstance(new Test0()).NonLazy(); Container.Bind().WithId("TestValue1").FromInstance(new Test0()).NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -125,8 +115,6 @@ public void TestSuccessConstructorInjectionEnum() Container.Bind().FromInstance(new Test0()).NonLazy(); Container.Bind().WithId("TestValue2").FromInstance(new Test0()).NonLazy(); - Container.Validate(); - // No exceptions Container.Resolve(); @@ -143,8 +131,6 @@ public void TestFailFieldInjectionEnum() Container.Bind().FromInstance(new Test0()).NonLazy(); Container.Bind().WithId("TestValue1").FromInstance(new Test0()).NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -157,8 +143,6 @@ public void TestSuccessFieldInjectionEnum() Container.Bind().FromInstance(new Test0()).NonLazy(); Container.Bind().WithId("TestValue3").FromInstance(new Test0()).NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve()); } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsParents.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsParents.cs index d59d3876e..7353c0fdd 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsParents.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsParents.cs @@ -65,8 +65,6 @@ public void TestCase1() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().When(c => c.AllObjectTypes.Contains(typeof(Test2))); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -77,8 +75,6 @@ public void TestCase2() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().When(c => c.AllObjectTypes.Contains(typeof(Test1))); - Container.Validate(); - var test1 = Container.Resolve(); Assert.That(test1 != null); } @@ -111,8 +107,6 @@ public void TestCase4() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().AsSingle().When(c => c.AllObjectTypes.Contains(typeof(ITest1))); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -123,8 +117,6 @@ public void TestCase5() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().AsSingle().When(c => c.AllObjectTypes.Contains(typeof(Test2))); - Container.Validate(); - var test1 = Container.Resolve(); Assert.That(test1 != null); } @@ -135,8 +127,6 @@ public void TestCase6() Container.Bind().To().AsSingle().NonLazy(); Container.Bind().AsSingle().When(c => c.AllObjectTypes.Where(x => typeof(ITest1).IsAssignableFrom(x)).Any()); - Container.Validate(); - var test1 = Container.Resolve(); Assert.That(test1 != null); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsTarget.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsTarget.cs index 009b45f77..8fb49d43f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsTarget.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsTarget.cs @@ -40,8 +40,6 @@ public void TestTargetConditionError() { Container.Bind().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -51,8 +49,6 @@ public void TestTargetConditionSuccess() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test2 = Container.Resolve(); Assert.That(test2 != null); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestIdentifiers.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestIdentifiers.cs index 5b1faeba2..4c046c0d7 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestIdentifiers.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestIdentifiers.cs @@ -20,8 +20,6 @@ public void TestBasic() { Container.Bind().WithId("foo").AsTransient().NonLazy(); - Container.Validate(); - Assert.Throws( delegate { Container.Resolve(); }); @@ -33,8 +31,6 @@ public void TestBasic2() { Container.Bind().WithId("foo").AsSingle().NonLazy(); - Container.Validate(); - Assert.Throws( delegate { Container.Resolve(); }); @@ -46,8 +42,6 @@ public void TestBasic3() { Container.Bind().WithId("foo").FromMethod((ctx) => new Test0()).NonLazy(); - Container.Validate(); - Assert.Throws( delegate { Container.Resolve(); }); @@ -60,8 +54,6 @@ public void TestBasic4() Container.Bind().WithId("foo").AsTransient().NonLazy(); Container.Bind().WithId("foo").AsTransient().NonLazy(); - Container.Validate(); - Assert.Throws( delegate { Container.Resolve(); }); @@ -76,8 +68,6 @@ public void TestFromMethodUntyped() { Container.Bind(typeof(Test0)).FromMethod((ctx) => new Test0()).NonLazy(); - Container.Validate(); - Container.Resolve(); } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs index aad6aa741..9fa850794 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs @@ -16,8 +16,6 @@ public void TestSelf1() { Container.BindFactory().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Create()); } @@ -26,8 +24,6 @@ public void TestSelf2() { Container.BindFactory().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Create()); } @@ -36,8 +32,6 @@ public void TestSelf3() { Container.BindFactory().FromNew().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Create()); } @@ -46,8 +40,6 @@ public void TestConcrete() { Container.BindFactory().To().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Create()); Assert.That(Container.Resolve().Create() is Foo); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs index bc2b348fd..972927e42 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs @@ -16,8 +16,6 @@ public void TestSelf() { Container.BindFactory().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } @@ -26,8 +24,6 @@ public void TestConcrete() { Container.BindFactory().To().NonLazy(); - Container.Validate(); - var ifoo = Container.Resolve().Create("asdf"); Assert.IsNotNull(ifoo); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs index b4561c66c..efbe4acd6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs @@ -16,8 +16,6 @@ public void TestSelf1() { Container.BindFactory().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf", 2, "a", 4.2f, 6).P1, "asdf"); } @@ -26,8 +24,6 @@ public void TestSelf2() { Container.BindFactory().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf", 2, "a", 4.2f, 6).P1, "asdf"); } @@ -36,8 +32,6 @@ public void TestConcrete() { Container.BindFactory().To().NonLazy(); - Container.Validate(); - var ifoo = Container.Resolve().Create("asdf", 2, "a", 4.2f, 6); Assert.IsNotNull(ifoo); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs index 395a67150..8e484502e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs @@ -18,8 +18,6 @@ public void TestSelf() { Container.BindFactory().FromFactory().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), StaticFoo); } @@ -29,8 +27,6 @@ public void TestConcrete() Container.BindFactory() .To().FromFactory().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), StaticFoo); } @@ -40,7 +36,7 @@ public void TestFactoryValidation() Container.BindFactory() .To().FromFactory().NonLazy(); - Assert.Throws(() => Container.Validate()); + Container.Resolve().Create(); } class CustomFooFactoryWithValidate : IFactory, IValidatable diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs index b434d4ada..be3ea9295 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs @@ -16,8 +16,6 @@ public void TestSelf() { Container.BindFactory().FromFactory().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } @@ -26,8 +24,6 @@ public void TestConcrete() { Container.BindFactory().To().FromFactory().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs index 0f79fc86d..dbddbb551 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs @@ -16,8 +16,6 @@ public void TestSelf() Container.Bind().AsSingle().NonLazy(); Container.BindFactory().FromResolveGetter(x => x.Bar).NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Create()); Assert.IsEqual(Container.Resolve().Create(), Container.Resolve().Bar); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs index e3e74c8fb..7cc9c0d42 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs @@ -18,8 +18,6 @@ public void TestSelf() Container.BindFactory().FromInstance(foo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), foo); } @@ -30,8 +28,6 @@ public void TestConcrete() Container.BindFactory().FromInstance(foo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), foo); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs index d5695a79a..11af6dbc2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs @@ -18,8 +18,6 @@ public void TestSelf() Container.BindFactory().FromMethod((c) => foo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), foo); } @@ -30,8 +28,6 @@ public void TestConcrete() Container.BindFactory().FromMethod((c) => foo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), foo); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs index 8bb2a9553..2b0e0555a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs @@ -16,8 +16,6 @@ public void TestSelf() { Container.BindFactory().FromMethod((c, value) => new Foo(value)).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } @@ -26,8 +24,6 @@ public void TestConcrete() { Container.BindFactory().FromMethod((c, value) => new Foo(value)).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs index b2333689d..765f7235f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs @@ -20,8 +20,6 @@ public void TestSelf() Container.BindFactory().FromResolve().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), foo); } @@ -34,8 +32,6 @@ public void TestConcrete() Container.BindFactory().To().FromResolve().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), foo); } @@ -48,8 +44,6 @@ public void TestSelfIdentifier() Container.BindFactory().FromResolve("foo").NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), foo); } @@ -62,8 +56,6 @@ public void TestConcreteIdentifier() Container.BindFactory().To().FromResolve("foo").NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), foo); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs index 2d4b0dac4..03dc5ce5e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs @@ -17,8 +17,6 @@ public void TestSelf() Container.BindFactory() .FromSubContainerResolve().ByInstaller().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), FooInstaller.Foo); } @@ -28,8 +26,6 @@ public void TestConcrete() Container.BindFactory() .To().FromSubContainerResolve().ByInstaller().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), FooInstaller.Foo); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs index 6b351d80a..6d41dfef0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs @@ -17,8 +17,6 @@ public void TestSelf() Container.BindFactory() .FromSubContainerResolve().ByInstaller().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } @@ -28,8 +26,6 @@ public void TestConcrete() Container.BindFactory() .To().FromSubContainerResolve().ByInstaller().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs index e6b8ddefb..fd1888400 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs @@ -18,8 +18,6 @@ public void TestSelf() { Container.BindFactory().FromSubContainerResolve().ByMethod(InstallFoo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), ConstFoo); } @@ -29,8 +27,6 @@ public void TestConcrete() Container.BindFactory() .To().FromSubContainerResolve().ByMethod(InstallFoo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create(), ConstFoo); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs index eaf73e94c..65c2f144a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs @@ -17,8 +17,6 @@ public void TestSelf() Container.BindFactory() .FromSubContainerResolve().ByMethod(InstallFoo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } @@ -27,8 +25,6 @@ public void TestConcrete() { Container.BindFactory().To().FromSubContainerResolve().ByMethod(InstallFoo).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Create("asdf").Value, "asdf"); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs index ae0ddd613..e8d58ef94 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs @@ -183,8 +183,6 @@ public void TestSubContainers() { Container.BindPooledFactory().FromSubContainerResolve().ByMethod(InstallQux).NonLazy(); - Container.Validate(); - var factory = Container.Resolve(); var qux = factory.Spawn(); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/IFactory/TestIFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/IFactory/TestIFactory.cs index 7249cf345..7f6f06f4b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/IFactory/TestIFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/IFactory/TestIFactory.cs @@ -26,8 +26,6 @@ public void Test2Error() { Container.BindIFactory(); - Assert.Throws(() => Container.Validate()); - var factory = Container.Resolve>(); Assert.Throws(() => factory.Create()); @@ -38,8 +36,6 @@ public void Test2() { Container.BindIFactory(); - Container.Validate(); - var factory = Container.Resolve>(); Assert.IsEqual(factory.Create("asdf").Value, "asdf"); @@ -50,8 +46,6 @@ public void Test5() { Container.BindIFactory().To(); - Container.Validate(); - var factory = Container.Resolve>(); Assert.IsEqual(factory.Create("asdf", 0, 'z', 2, 3.0).P1, "asdf"); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/TestFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/TestFactory.cs index 17b44ede8..ded4280a5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/TestFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/TestFactory.cs @@ -16,8 +16,6 @@ public void TestToSelf() { Container.BindFactory().NonLazy(); - Container.Validate(); - Assert.IsNotNull(Container.Resolve().Create()); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestAllInjectionTypes.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestAllInjectionTypes.cs index a3ae41d4e..865186104 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestAllInjectionTypes.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestAllInjectionTypes.cs @@ -17,8 +17,6 @@ public void TestCase1() Container.Bind().FromInstance(new Test0()).NonLazy(); Container.Bind().To().AsSingle().NonLazy(); - Container.Validate(); - var foo = Container.Resolve(); Assert.That(foo.DidPostInjectBase); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestBaseClassPropertyInjection.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestBaseClassPropertyInjection.cs index b9878eb00..ba06ee832 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestBaseClassPropertyInjection.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestBaseClassPropertyInjection.cs @@ -38,8 +38,6 @@ public void TestCaseBaseClassPropertyInjection() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test1 = Container.Resolve(); Assert.That(test1.GetVal() != null); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestCircularDependencies.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestCircularDependencies.cs index c8e542002..8da4ed484 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestCircularDependencies.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestCircularDependencies.cs @@ -46,9 +46,6 @@ public void TestFields() Container.Bind().AsSingle(); Container.Bind().AsSingle(); - // TODO: Validation does not support circular dependencies - Container.Validate(); - var test1 = Container.Resolve(); var test2 = Container.Resolve(); @@ -103,10 +100,6 @@ public void TestPostInject() Container.Bind().AsSingle(); Container.Bind().AsSingle(); - // TODO - validation does not support circular dependencies - // which is valid for properties - Container.Validate(); - var test1 = Container.Resolve(); var test2 = Container.Resolve(); @@ -140,8 +133,6 @@ public void TestConstructorInject() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws(() => Container.Resolve()); Assert.Throws(() => Container.Resolve()); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestConstructorInjection.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestConstructorInjection.cs index ed16c810b..9030cac01 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestConstructorInjection.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestConstructorInjection.cs @@ -30,8 +30,6 @@ public void TestCase1() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test1 = Container.Resolve(); Assert.That(test1.val != null); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestConstructorInjectionOptional.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestConstructorInjectionOptional.cs index c1d3b75d4..910a7c5dc 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestConstructorInjectionOptional.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestConstructorInjectionOptional.cs @@ -39,8 +39,6 @@ public void TestCase1() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test1 = Container.Resolve(); Assert.That(test1.val == null); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestDuplicateInjection.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestDuplicateInjection.cs index f7adf51d6..903a64081 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestDuplicateInjection.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestDuplicateInjection.cs @@ -30,8 +30,6 @@ public void TestCaseDuplicateInjection() Container.Bind().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestNullableValues.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestNullableValues.cs index 28854dc00..837cf3aa5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestNullableValues.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestNullableValues.cs @@ -38,8 +38,6 @@ public void RunTest1() Container.Bind().AsSingle().NonLazy(); Container.Bind().FromInstance(1).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().val, 1); } @@ -48,8 +46,6 @@ public void RunTest2() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().val, null); } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestParameters.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestParameters.cs index 26f2ccc78..3ea6b464b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestParameters.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestParameters.cs @@ -42,8 +42,6 @@ public void TestMissingParameterThrows() { Container.Bind().AsTransient().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPostInjectCall.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPostInjectCall.cs index 62735460a..7674b5ea3 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPostInjectCall.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPostInjectCall.cs @@ -65,8 +65,6 @@ public void Test() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test3 = Container.Resolve(); Assert.That(test3.HasInitialized); Assert.That(test3.HasInitialized2); @@ -92,8 +90,6 @@ public void TestPrivateBaseClassPostInject() { Container.Bind().To().AsSingle().NonLazy(); - Container.Validate(); - var simple = Container.Resolve(); Assert.That(simple.WasCalled); @@ -104,8 +100,6 @@ public void TestInheritance() { Container.Bind().To().AsSingle().NonLazy(); - Container.Validate(); - var foo = Container.Resolve(); Assert.That(((FooDerived)foo).WasDerivedCalled); @@ -125,8 +119,6 @@ public void TestInheritanceOrder() FooDerived.DerivedCallOrder = 0; FooDerived2.Derived2CallOrder = 0; - Container.Validate(); - Container.Resolve(); //Log.Info("FooBase.BaseCallOrder = {0}".Fmt(FooBase.BaseCallOrder)); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPostInjectParameters.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPostInjectParameters.cs index 4ac8ca4c9..49ed6fb37 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPostInjectParameters.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPostInjectParameters.cs @@ -54,8 +54,6 @@ public void Test() Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test3 = Container.Resolve(); Assert.That(test3.HasInitialized); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPropertyInjection.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPropertyInjection.cs index 817ad525b..ae8e4f8b1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPropertyInjection.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestPropertyInjection.cs @@ -36,8 +36,6 @@ public void TestPublicPrivate() Container.Bind().AsSingle().NonLazy(); Container.Bind().FromInstance(test1).NonLazy(); - Container.Validate(); - var test2 = Container.Resolve(); Assert.IsEqual(test2.val2, test1); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestStructInjection.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestStructInjection.cs index 509466a30..745d8256c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestStructInjection.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestStructInjection.cs @@ -27,7 +27,7 @@ public void TestCase1() Container.Bind().FromInstance(new Test1()).NonLazy(); Container.Bind().AsSingle().NonLazy(); - Container.Validate(); + Container.ResolveDependencyRoots(); var t2 = Container.Resolve(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestTestOptional.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestTestOptional.cs index d404c07c2..089b4524c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestTestOptional.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Injection/TestTestOptional.cs @@ -38,8 +38,6 @@ public void TestFieldRequired() { Container.Bind().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -49,8 +47,6 @@ public void TestFieldOptional() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test = Container.Resolve(); Assert.That(test.val1 == null); } @@ -63,8 +59,6 @@ public void TestFieldOptional2() var test1 = new Test1(); Container.Bind().FromInstance(test1).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().val1, test1); } @@ -73,15 +67,11 @@ public void TestFieldOptional3() { Container.Bind().AsTransient().NonLazy(); - Container.Validate(); - // Should not redefine the hard coded value in this case Assert.IsEqual(Container.Resolve().Val1, 5); Container.Bind().FromInstance(3).NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Val1, 3); } @@ -109,8 +99,6 @@ public void TestParameterRequired() { Container.Bind().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -120,8 +108,6 @@ public void TestParameterOptional() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - var test = Container.Resolve(); Assert.That(test.Val1 == null); } @@ -139,8 +125,6 @@ public void TestChildDependencyOptional() Container.Bind().AsSingle().NonLazy(); Container.Bind().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - Assert.Throws( delegate { Container.Resolve(); }); } @@ -162,8 +146,6 @@ public void TestPrimitiveParamOptionalUsesDefault() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Val1, 0); } @@ -184,8 +166,6 @@ public void TestPrimitiveParamOptionalUsesExplicitDefault() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Val1, 5); } @@ -204,8 +184,6 @@ public void TestPrimitiveParamOptionalUsesExplicitDefault2() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Val1, 5); } @@ -215,8 +193,6 @@ public void TestPrimitiveParamOptionalUsesExplicitDefault3() Container.Bind().AsSingle().NonLazy(); Container.BindInstance(2); - Container.Validate(); - Assert.IsEqual(Container.Resolve().Val1, 2); } @@ -237,8 +213,6 @@ public void TestPrimitiveParamOptionalNullable() { Container.Bind().AsSingle().NonLazy(); - Container.Validate(); - Assert.That(!Container.Resolve().Val1.HasValue); } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestGenericContract.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestGenericContract.cs index 6edae0925..6a8543288 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestGenericContract.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestGenericContract.cs @@ -28,8 +28,6 @@ public void TestToSingle() Container.BindRootResolve>(); Container.BindRootResolve>(); - Container.Validate(); - var test1 = Container.Resolve>(); Assert.That(test1.Data == 0); test1.Data = 5; @@ -49,8 +47,6 @@ public void TestToTransient() Container.BindRootResolve>(); Container.BindRootResolve>(); - Container.Validate(); - var test1 = Container.Resolve>(); Assert.That(test1.Data == 0); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestValidateInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestValidateInstaller.cs deleted file mode 100644 index 4fdcc48f4..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestValidateInstaller.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using NUnit.Framework; -using Zenject; -using System.Linq; -using ModestTree; -using Assert=ModestTree.Assert; - -namespace Zenject.Tests.Other -{ - [TestFixture] - public class TestValidateInstaller : ZenjectUnitTestFixture - { - [Test] - public void TestBasicSuccess() - { - Container.Bind().To().AsSingle().NonLazy(); - Container.Bind().AsSingle().NonLazy(); - - Container.Validate(); - } - - [Test] - public void TestBasicFailure() - { - Container.Bind().To().AsSingle().NonLazy(); - - Assert.Throws(() => Container.Validate()); - } - - [Test] - public void TestList() - { - Container.Bind().To().AsSingle().NonLazy(); - Container.Bind().To().AsSingle().NonLazy(); - - Container.Bind().AsSingle().NonLazy(); - - Container.Bind().AsSingle().NonLazy(); - - Container.Validate(); - } - - [Test] - public void TestValidateNestedContainerSuccess() - { - var nestedContainer = Container.CreateSubContainer(); - - nestedContainer.Bind().AsSingle().NonLazy(); - - // Should fail without Bar<> bound - Assert.Throws(() => nestedContainer.Validate()); - - Container.Bind().AsSingle().NonLazy(); - - Container.Validate(); - nestedContainer.Validate(); - } - - [Test] - public void TestValidateNestedContainerList() - { - var nestedContainer = Container.CreateSubContainer(); - - Container.Bind().To().AsSingle().NonLazy(); - Container.Bind().To().AsSingle().NonLazy(); - - Container.Bind().AsSingle().NonLazy(); - - Container.Validate(); - - // Should not throw - nestedContainer.Resolve>(); - } - - interface IFoo - { - } - - class Foo : IFoo - { - public Foo(Bar bar) - { - } - } - - class Foo2 : IFoo - { - public Foo2(Bar bar) - { - } - } - - class Bar - { - } - - class Qux - { - public Qux(List foos) - { - } - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestValidateInstaller.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestValidateInstaller.cs.meta deleted file mode 100644 index bb329d595..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Other/TestValidateInstaller.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 7dafb487041e94743ab6d894ee7f8077 -timeCreated: 1461708051 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs index d65f345ce..b2f4965d5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs @@ -17,8 +17,6 @@ public void Test1() var foo = Container.Resolve(); - Container.Validate(); - Assert.IsEqual(Bar.InstanceCount, 0); foo.DoIt(); @@ -31,8 +29,6 @@ public void Test2() { Container.Bind().AsSingle().NonLazy(); - Assert.Throws(() => Container.Validate()); - var foo = Container.Resolve(); Assert.Throws(() => foo.DoIt()); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta deleted file mode 100644 index 275529ec6..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 22fc19ecec6ff2c4d8e62fc8d4f49f9d -folderAsset: yes -timeCreated: 1461711435 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidate1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidate1.cs deleted file mode 100644 index 224c0b448..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidate1.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using Zenject; -using NUnit.Framework; -using System.Linq; -using ModestTree; -using Assert=ModestTree.Assert; - -namespace Zenject.Tests.Validation -{ - [TestFixture] - public class TestValidate1 : ZenjectUnitTestFixture - { - [Test] - public void Test1() - { - Container.Bind().AsSingle().NonLazy(); - Container.Bind().AsSingle(); - - Container.Validate(); - } - - [Test] - [ExpectedException] - public void Test2() - { - Container.Bind().AsSingle().NonLazy(); - - Container.Validate(); - } - - public class Foo - { - public Foo(Bar bar) - { - } - } - - public class Bar - { - } - } -} - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidate1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidate1.cs.meta deleted file mode 100644 index efc639d9f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidate1.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 57dda8b4597f14d4abcd473b17b0ed7a -timeCreated: 1461708050 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidateFactories.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidateFactories.cs deleted file mode 100644 index 6e4d70aea..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidateFactories.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using Zenject; -using NUnit.Framework; -using System.Linq; -using ModestTree; -using Assert=ModestTree.Assert; - -namespace Zenject.Tests.Validation -{ - [TestFixture] - public class TestValidateFactories : ZenjectUnitTestFixture - { - [Test] - public void Test1() - { - Container.BindFactory(); - Container.Bind().AsSingle(); - - Container.Validate(); - } - - [Test] - [ExpectedException] - public void Test2() - { - Container.BindFactory(); - - Container.Validate(); - } - - public class Foo - { - public Foo(Bar bar) - { - } - - public class Factory : Factory - { - } - } - - public class Bar - { - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidateFactories.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidateFactories.cs.meta deleted file mode 100644 index 629b28c3a..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation/TestValidateFactories.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: d54ab18ed25a03b4baeafe7110f22a87 -timeCreated: 1461708053 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index e4ba07253..0d0012223 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -38,7 +38,9 @@ public class DiContainer : IInstantiator readonly LazyInstanceInjector _lazyInjector; readonly Queue _currentBindings = new Queue(); - readonly List _processedBindings = new List(); + readonly List _childBindings = new List(); + + readonly List _lateBindingsToValidate = new List(); bool _isFinalizingBinding; bool _isValidating; @@ -56,8 +58,6 @@ public DiContainer(bool isValidating) InstallDefaultBindings(); FlushBindings(); Assert.That(_currentBindings.IsEmpty()); - // Clear the default bindings from history to avoid duplicating them in Clone below - _processedBindings.Clear(); } void InstallDefaultBindings() @@ -77,7 +77,10 @@ object CreateLazyBinding(InjectContext context) if (_isValidating) { - ((ILazy)result).Validate(); + // Unfortunately we can't validate each lazy binding here + // because that could result in circular reference exceptions + // And that might be exactly why you're using lazy in the first place + _lateBindingsToValidate.Add(((ILazy)result)); } return result; @@ -100,9 +103,9 @@ public DiContainer(DiContainer parentContainer, bool isValidating) #if !NOT_UNITY3D DefaultParent = parentContainer.DefaultParent; #endif - foreach (var binding in parentContainer._processedBindings - .Where(x => x.CopyIntoAllSubContainers)) + foreach (var binding in parentContainer._childBindings) { + Assert.That(binding.CopyIntoAllSubContainers); _currentBindings.Enqueue(binding); } @@ -193,27 +196,6 @@ public IEnumerable AllContracts } } - // DO not run this within Unity! - // This is only really useful if you are not using any of the Unity bind methods such as - // FromGameObject, FromPrefab, etc. - // If you are using those, and you call this method, then it will have side effects like - // creating game objects - // Otherwise, it should be safe to call since all the fake instances will be limited to - // within a cloned copy of the DiContainer and should not have any side effects - public void Validate() - { - var container = CloneForValidate(); - - Assert.That(container.IsValidating); - - // It's tempting here to iterate over all the BindingId's in _providers - // and make sure they can be resolved but that fails once we start - // using complex conditionals, so this is the best we can do - container.ResolveDependencyRoots(); - - container.ValidateIValidatables(); - } - public List ResolveDependencyRoots() { var context = new InjectContext( @@ -224,35 +206,6 @@ public List ResolveDependencyRoots() return ResolveAll(context).Cast().ToList(); } - DiContainer CloneForValidate() - { - FlushBindings(); - - DiContainer container; - - if (this.ParentContainer == null) - { - container = new DiContainer(null, true); - } - else - { - // Need to clone all parents too - container = new DiContainer( - this.ParentContainer.CloneForValidate(), true); - } - - // Validating shouldn't have side effects, so assert if this occurs - container.AssertOnNewGameObjects = true; - - foreach (var binding in _processedBindings) - { - container._currentBindings.Enqueue(binding); - } - - container.FlushBindings(); - return container; - } - // This will instantiate any binding that results in a type that derives from IValidatable // Note that we are looking at both the contract type and the mapped derived type // This means if you add the binding 'Container.Bind().To()' @@ -1788,7 +1741,10 @@ public void FlushBindings() _isFinalizingBinding = false; } - _processedBindings.Add(binding); + if (binding.CopyIntoAllSubContainers) + { + _childBindings.Add(binding); + } } } From a5cdfee4454aabd6719e7d72ccdef5b90938ac99 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 27 Jan 2017 18:51:31 -0400 Subject: [PATCH 24/62] Fixed Lazy<> to validate properly for real this time --- .../Bindings/Editor}/TestLazy.cs | 31 +++++++++++++++++-- .../Bindings/Editor}/TestLazy.cs.meta | 4 +-- .../Testing/ZenjectIntegrationTestFixture.cs | 2 +- .../Assets/Zenject/Source/Injection/Lazy.cs | 5 ++- .../Install/Contexts/GameObjectContext.cs | 4 +-- .../Source/Install/Contexts/SceneContext.cs | 4 +-- .../Assets/Zenject/Source/Main/DiContainer.cs | 7 ++++- .../SubContainerCreatorByInstaller.cs | 4 +-- .../SubContainerCreatorByMethod.cs | 24 +++++++------- .../SubContainerCreatorByPrefab.cs | 2 +- .../SubContainerCreatorByPrefabWithParams.cs | 2 +- 11 files changed, 61 insertions(+), 28 deletions(-) rename UnityProject/Assets/Zenject/OptionalExtras/{UnitTests/Editor/Util => IntegrationTests/Bindings/Editor}/TestLazy.cs (65%) rename UnityProject/Assets/Zenject/OptionalExtras/{UnitTests/Editor/Util => IntegrationTests/Bindings/Editor}/TestLazy.cs.meta (76%) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestLazy.cs similarity index 65% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestLazy.cs index b2f4965d5..693bb0e6b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestLazy.cs @@ -1,11 +1,16 @@ using System; +using System.Collections.Generic; +using System.Linq; using NUnit.Framework; +using UnityEngine; +using ModestTree; using Assert=ModestTree.Assert; +using Zenject.Tests.Bindings.FromPrefab; namespace Zenject.Tests.Bindings { [TestFixture] - public class TestLazy : ZenjectUnitTestFixture + public class TestLazy : ZenjectIntegrationTestFixture { [Test] public void Test1() @@ -15,6 +20,8 @@ public void Test1() Container.Bind().AsSingle(); Container.Bind().AsSingle(); + Initialize(); + var foo = Container.Resolve(); Assert.IsEqual(Bar.InstanceCount, 0); @@ -29,11 +36,30 @@ public void Test2() { Container.Bind().AsSingle().NonLazy(); - var foo = Container.Resolve(); + Initialize(); + var foo = Container.Resolve(); Assert.Throws(() => foo.DoIt()); } + [Test] + [ValidateOnly] + [ExpectedException] + public void Test3() + { + Container.Bind().AsSingle().NonLazy(); + Initialize(); + } + + [Test] + [ValidateOnly] + public void Test4() + { + Container.Bind().AsSingle().NonLazy(); + Container.Bind().AsSingle(); + Initialize(); + } + public class Bar { public static int InstanceCount = 0; @@ -64,3 +90,4 @@ public void DoIt() } } } + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestLazy.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestLazy.cs.meta index 2c6862c75..17c496ebd 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Util/TestLazy.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestLazy.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 3abd5475d61683e4b88631a8a4a7eb2e -timeCreated: 1485055480 +guid: 1ce0b6eda7a924b40a99633734931bb9 +timeCreated: 1485556448 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs index 55ef29105..1bfbfcacf 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs @@ -54,7 +54,7 @@ public void Initialize() if (_isValidating) { - Container.ValidateIValidatables(); + Container.ValidateValidatables(); } else { diff --git a/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs b/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs index bdb64328d..48d6e83d7 100644 --- a/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs +++ b/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs @@ -1,4 +1,5 @@ using System; +using ModestTree; namespace Zenject { @@ -18,13 +19,15 @@ public class Lazy : ILazy public Lazy(DiContainer container, InjectContext context) { + Assert.IsEqual(typeof(T), context.MemberType); + _container = container; _context = context; } void ILazy.Validate() { - _container.Resolve(_context); + _container.Resolve(_context); } public T Value diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs index 2bc519c5d..fea165088 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs @@ -70,10 +70,10 @@ public void Construct( if (_container.IsValidating) { - // The root-level Container has its ValidateIValidatables method + // The root-level Container has its ValidateValidatables method // called explicitly - however, this is not so for sub-containers // so call it here instead - _container.ValidateIValidatables(); + _container.ValidateValidatables(); } Log.Debug("GameObjectContext: Initialized successfully"); diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs index 1ede36c61..011e91f57 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs @@ -110,9 +110,7 @@ public void Validate() Install(); Resolve(); - Assert.That(_container.IsValidating); - - _container.ValidateIValidatables(); + _container.ValidateValidatables(); } #endif diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 0d0012223..3d6902eac 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -212,7 +212,7 @@ public List ResolveDependencyRoots() // and Foo derives from both IFoo and IValidatable, then Foo will be instantiated // and then Validate() will be called on it. Note that this will happen even if Foo is not // referenced anywhere in the normally resolved object graph - public void ValidateIValidatables() + public void ValidateValidatables() { Assert.That(IsValidating); @@ -248,6 +248,11 @@ public void ValidateIValidatables() validatable.Validate(); } } + + foreach (var lazy in _lateBindingsToValidate) + { + lazy.Validate(); + } } public DiContainer CreateSubContainer() diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs index b7c1875c7..ecde7eb1f 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs @@ -40,10 +40,10 @@ public DiContainer CreateSubContainer(List args) if (subContainer.IsValidating) { - // The root-level Container has its ValidateIValidatables method + // The root-level Container has its ValidateValidatables method // called explicitly - however, this is not so for sub-containers // so call it here instead - subContainer.ValidateIValidatables(); + subContainer.ValidateValidatables(); } return subContainer; diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByMethod.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByMethod.cs index 59ad72e55..6f552bb08 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByMethod.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByMethod.cs @@ -31,10 +31,10 @@ public DiContainer CreateSubContainer(List args) if (subContainer.IsValidating) { - // The root-level Container has its ValidateIValidatables method + // The root-level Container has its ValidateValidatables method // called explicitly - however, this is not so for sub-containers // so call it here instead - subContainer.ValidateIValidatables(); + subContainer.ValidateValidatables(); } return subContainer; @@ -69,10 +69,10 @@ public DiContainer CreateSubContainer(List args) if (subContainer.IsValidating) { - // The root-level Container has its ValidateIValidatables method + // The root-level Container has its ValidateValidatables method // called explicitly - however, this is not so for sub-containers // so call it here instead - subContainer.ValidateIValidatables(); + subContainer.ValidateValidatables(); } return subContainer; @@ -111,10 +111,10 @@ public DiContainer CreateSubContainer(List args) if (subContainer.IsValidating) { - // The root-level Container has its ValidateIValidatables method + // The root-level Container has its ValidateValidatables method // called explicitly - however, this is not so for sub-containers // so call it here instead - subContainer.ValidateIValidatables(); + subContainer.ValidateValidatables(); } return subContainer; @@ -155,10 +155,10 @@ public DiContainer CreateSubContainer(List args) if (subContainer.IsValidating) { - // The root-level Container has its ValidateIValidatables method + // The root-level Container has its ValidateValidatables method // called explicitly - however, this is not so for sub-containers // so call it here instead - subContainer.ValidateIValidatables(); + subContainer.ValidateValidatables(); } return subContainer; @@ -201,10 +201,10 @@ public DiContainer CreateSubContainer(List args) if (subContainer.IsValidating) { - // The root-level Container has its ValidateIValidatables method + // The root-level Container has its ValidateValidatables method // called explicitly - however, this is not so for sub-containers // so call it here instead - subContainer.ValidateIValidatables(); + subContainer.ValidateValidatables(); } return subContainer; @@ -249,10 +249,10 @@ public DiContainer CreateSubContainer(List args) if (subContainer.IsValidating) { - // The root-level Container has its ValidateIValidatables method + // The root-level Container has its ValidateValidatables method // called explicitly - however, this is not so for sub-containers // so call it here instead - subContainer.ValidateIValidatables(); + subContainer.ValidateValidatables(); } return subContainer; diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs index 0e77368e0..32db64804 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs @@ -33,7 +33,7 @@ public DiContainer CreateSubContainer(List args) Assert.IsNotNull(context, "Expected prefab with name '{0}' to container a component of type 'GameObjectContext'", prefab.name); - // Note: We don't need to call ValidateIValidatables here because GameObjectContext does this for us + // Note: We don't need to call ValidateValidatables here because GameObjectContext does this for us return context.Container; } diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs index 1f36595ca..b46931e06 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs @@ -54,7 +54,7 @@ public DiContainer CreateSubContainer(List args) Assert.IsNotNull(context, "Expected prefab with name '{0}' to container a component of type 'GameObjectContext'", prefab.name); - // Note: We don't need to call ValidateIValidatables here because GameObjectContext does this for us + // Note: We don't need to call ValidateValidatables here because GameObjectContext does this for us return context.Container; } From d9a38eb1e0576453542722c6687079834d584ec1 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 29 Jan 2017 11:45:41 -0400 Subject: [PATCH 25/62] - Renamed a bunch of the bind methods to be more consistent and clear - Refactored some stuff in memory pooling to be more elegant and clear --- .../Bindings/Editor/TestBindGameObject.cs | 28 ++-- .../Bindings/Editor/TestFromComponent.cs | 22 +-- .../Bindings/Editor/TestFromGameObject.cs | 30 ++-- .../Bindings/Editor/TestFromPrefab.cs | 28 ++-- .../Bindings/Editor/TestFromPrefabResource.cs | 30 ++-- .../Bindings/Editor/TestFromResource.cs | 10 +- .../Editor/TestFromSiblingComponent.cs | 12 +- .../Factories/Editor/TestBindFactory.cs | 28 ++-- .../Factories/Editor/TestBindFactoryFive.cs | 16 +- .../Factories/Editor/TestBindFactoryOne.cs | 16 +- .../Editor/TestGameObjectFactoryOne.cs | 8 +- .../Editor/TestGameObjectFactoryZero.cs | 12 +- .../TestBindFactoryFive/FooInstaller.cs | 2 +- .../TestBindFactoryOne/FooInstaller.cs | 2 +- .../Editor/Tests/TestAsteroidManager.cs | 4 +- .../Scripts/Installers/GameInstaller.cs | 6 +- ...athHandler.cs => EnemyExplosionHandler.cs} | 19 ++- .../Enemy/EnemyExplosionHandler.cs.meta} | 4 +- .../Scripts/Enemy/EnemyFacade.cs | 28 +--- .../Scripts/Enemy/GameEvents.cs | 2 +- .../Scripts/Enemy/States/EnemyStateAttack.cs | 8 +- .../Scripts/Installers/GameInstaller.cs | 12 +- .../Scripts/Misc/Bullet.cs | 36 ++--- .../Scripts/Misc/EnemySpawner.cs | 4 +- .../Scripts/Misc/Explosion.cs | 30 ++-- .../Scripts/Misc/GameRestartHandler.cs | 6 +- .../Scripts/Player/PlayerHealthWatcher.cs | 10 +- .../Scripts/Player/PlayerShootHandler.cs | 8 +- .../Binding/BindInfo/PooledFactoryBindInfo.cs | 4 +- .../Binders/Factory/FactoryFromBinderBase.cs | 8 +- ...lizer.cs => MemoryPoolBindingFinalizer.cs} | 14 +- .../MemoryPoolBindingFinalizer.cs.meta} | 4 +- ...andBinder.cs => MemoryPoolExpandBinder.cs} | 14 +- ...cs.meta => MemoryPoolExpandBinder.cs.meta} | 4 +- .../Pooling/MemoryPoolInitialSizeBinder.cs | 29 ++++ ...ta => MemoryPoolInitialSizeBinder.cs.meta} | 4 +- .../Pooling/PooledFactoryInitialSizeBinder.cs | 29 ---- .../Binding/Binders/FromBinders/FromBinder.cs | 22 +-- .../Pooling/DynamicPooledFactory.cs.meta | 12 -- .../{IPooledFactory.cs => IMemoryPool.cs} | 30 ++-- .../Factories/Pooling/IMemoryPool.cs.meta | 12 ++ .../Source/Factories/Pooling/IPoolable.cs | 37 ----- .../Factories/Pooling/IPoolable.cs.meta | 12 -- .../Factories/Pooling/IPooledFactory.cs.meta | 12 -- .../Source/Factories/Pooling/MemoryPool.cs | 95 +++++++++++ .../Factories/Pooling/MemoryPool.cs.meta | 12 ++ ...amicPooledFactory.cs => MemoryPoolBase.cs} | 135 ++++++++-------- .../Factories/Pooling/MemoryPoolBase.cs.meta | 12 ++ .../Factories/Pooling/MonoMemoryPool.cs | 143 +++++++++++++++++ .../Factories/Pooling/MonoMemoryPool.cs.meta | 12 ++ .../Source/Factories/Pooling/PooledFactory.cs | 149 ------------------ .../Factories/Pooling/PooledFactory.cs.meta | 12 -- .../Install/Contexts/GameObjectContext.cs | 2 +- .../Source/Install/Contexts/ProjectContext.cs | 4 +- .../Source/Install/Contexts/SceneContext.cs | 2 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 30 ++-- ...AddToCurrentGameObjectComponentProvider.cs | 2 +- .../Zenject/Source/Usage/IGuiRenderable.cs | 4 +- .../Zenject/Source/Util/PoolCleanupChecker.cs | 4 +- 59 files changed, 657 insertions(+), 629 deletions(-) rename UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/{EnemyDeathHandler.cs => EnemyExplosionHandler.cs} (66%) rename UnityProject/Assets/Zenject/{Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs.meta => OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyExplosionHandler.cs.meta} (76%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/{PooledFactoryBindingFinalizer.cs => MemoryPoolBindingFinalizer.cs} (72%) rename UnityProject/Assets/Zenject/{OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs.meta => Source/Binding/Binders/Factory/Pooling/MemoryPoolBindingFinalizer.cs.meta} (76%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/{PooledFactoryExpandBinder.cs => MemoryPoolExpandBinder.cs} (55%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/{PooledFactoryInitialSizeBinder.cs.meta => MemoryPoolExpandBinder.cs.meta} (76%) create mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolInitialSizeBinder.cs rename UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/{PooledFactoryBindingFinalizer.cs.meta => MemoryPoolInitialSizeBinder.cs.meta} (76%) delete mode 100644 UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs delete mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs.meta rename UnityProject/Assets/Zenject/Source/Factories/Pooling/{IPooledFactory.cs => IMemoryPool.cs} (50%) create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/IMemoryPool.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs delete mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs.meta rename UnityProject/Assets/Zenject/Source/Factories/Pooling/{DynamicPooledFactory.cs => MemoryPoolBase.cs} (64%) create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPoolBase.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs create mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs.meta delete mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs delete mode 100644 UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs index 169c2c61c..ce4287787 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs @@ -24,7 +24,7 @@ GameObject CubePrefab [Test] public void TestGameObjectSelfSingle1() { - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); Container.BindRootResolve(); Initialize(); @@ -36,9 +36,9 @@ public void TestGameObjectSelfSingle1() [Test] public void TestGameObjectSelfSingle2() { - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsSingle(); - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsSingle(); - Container.Bind().WithId("asdf").FromGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().WithId("asdf").FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve("asdf"); @@ -53,8 +53,8 @@ public void TestGameObjectSelfSingle2() [ExpectedException] public void TestGameObjectSelfSingleConflict() { - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsSingle(); - Container.Bind().FromGameObject().WithGameObjectName("asdf").AsSingle(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName("asdf").AsSingle(); Container.BindRootResolve(); @@ -64,9 +64,9 @@ public void TestGameObjectSelfSingleConflict() [Test] public void TestGameObjectSelfTransient() { - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsTransient(); - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsTransient(); - Container.Bind().FromGameObject().WithGameObjectName("asdf").AsTransient(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsTransient(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsTransient(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName("asdf").AsTransient(); Container.BindRootResolve(); Initialize(); @@ -78,7 +78,7 @@ public void TestGameObjectSelfTransient() [Test] public void TestGameObjectConcreteSingle() { - Container.Bind().To().FromGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().To().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); Container.BindRootResolve(); @@ -91,7 +91,7 @@ public void TestGameObjectConcreteSingle() [Test] public void TestPrefabSelfSingle1() { - Container.Bind().FromPrefab(CubePrefab) + Container.Bind().FromComponentInPrefab(CubePrefab) .WithGameObjectName(GameObjName).AsSingle().NonLazy(); Initialize(); @@ -106,7 +106,7 @@ public void TestPrefabSelfSingle1() public void TestPrefabConcreteSingle1() { Container.Bind().To() - .FromPrefab(CubePrefab).WithGameObjectName(GameObjName).AsSingle().NonLazy(); + .FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName).AsSingle().NonLazy(); Initialize(); @@ -119,7 +119,7 @@ public void TestPrefabConcreteSingle1() [Test] public void TestPrefabResourceSelfSingle1() { - Container.Bind().FromPrefabResource("TestBindGameObject/Cube").WithGameObjectName(GameObjName).AsSingle().NonLazy(); + Container.Bind().FromComponentInPrefabResource("TestBindGameObject/Cube").WithGameObjectName(GameObjName).AsSingle().NonLazy(); Initialize(); @@ -133,7 +133,7 @@ public void TestPrefabResourceSelfSingle1() public void TestPrefabResourceConcreteSingle1() { Container.Bind().To() - .FromPrefabResource("TestBindGameObject/Cube").WithGameObjectName(GameObjName).AsSingle().NonLazy(); + .FromComponentInPrefabResource("TestBindGameObject/Cube").WithGameObjectName(GameObjName).AsSingle().NonLazy(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponent.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponent.cs index 36d39d780..0d459947b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponent.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponent.cs @@ -18,7 +18,7 @@ public void TestBasic() Container.BindInstance(gameObject, true).WithId("Foo"); - Container.Bind().FromComponent(gameObject).AsSingle(); + Container.Bind().FromNewComponentOn(gameObject).AsSingle(); Container.BindRootResolve(); Initialize(); @@ -33,8 +33,8 @@ public void TestTransient() Container.BindInstance(gameObject, true).WithId("Foo"); - Container.Bind().FromComponent(gameObject).AsTransient(); - Container.Bind().To().FromComponent(gameObject).AsTransient(); + Container.Bind().FromNewComponentOn(gameObject).AsTransient(); + Container.Bind().To().FromNewComponentOn(gameObject).AsTransient(); Container.BindRootResolve(new[] {typeof(IFoo), typeof(Foo)}); @@ -50,8 +50,8 @@ public void TestSingle() Container.BindInstance(gameObject, true).WithId("Foo"); - Container.Bind().FromComponent(gameObject).AsSingle(); - Container.Bind().To().FromComponent(gameObject).AsSingle(); + Container.Bind().FromNewComponentOn(gameObject).AsSingle(); + Container.Bind().To().FromNewComponentOn(gameObject).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -68,8 +68,8 @@ public void TestCached1() Container.BindInstance(gameObject, true).WithId("Foo"); - Container.Bind().FromComponent(gameObject).AsCached(); - Container.Bind().To().FromComponent(gameObject).AsCached(); + Container.Bind().FromNewComponentOn(gameObject).AsCached(); + Container.Bind().To().FromNewComponentOn(gameObject).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -86,7 +86,7 @@ public void TestCached2() Container.BindInstance(gameObject, true).WithId("Foo"); - Container.Bind(typeof(IFoo), typeof(Foo)).To().FromComponent(gameObject).AsCached(); + Container.Bind(typeof(IFoo), typeof(Foo)).To().FromNewComponentOn(gameObject).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -104,7 +104,7 @@ public void TestCachedMultipleConcrete() Container.BindInstance(gameObject, true).WithId("Foo"); Container.Bind(typeof(IFoo), typeof(IBar)) - .To(new List() { typeof(Foo), typeof(Bar) }).FromComponent(gameObject).AsCached(); + .To(new List() { typeof(Foo), typeof(Bar) }).FromNewComponentOn(gameObject).AsCached(); Container.BindRootResolve(new [] { typeof(IFoo), typeof(IBar) }); @@ -122,8 +122,8 @@ public void TestSingleMultipleConcrete() Container.BindInstance(gameObject, true).WithId("Foo"); Container.Bind(typeof(IFoo), typeof(IBar)).To(new List() { typeof(Foo), typeof(Bar) }) - .FromComponent(gameObject).AsSingle(); - Container.Bind().To().FromComponent(gameObject).AsSingle(); + .FromNewComponentOn(gameObject).AsSingle(); + Container.Bind().To().FromNewComponentOn(gameObject).AsSingle(); Container.BindRootResolve(new [] { typeof(IFoo), typeof(IFoo2), typeof(IBar) }); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs index 99c4236ad..9c6185b9c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs @@ -16,7 +16,7 @@ public class TestFromGameObject : ZenjectIntegrationTestFixture [Test] public void TestBasic() { - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); Container.BindRootResolve(); Initialize(); @@ -28,8 +28,8 @@ public void TestBasic() [Test] public void TestSingle() { - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsSingle(); - Container.Bind().To().FromGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); + Container.Bind().To().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -43,8 +43,8 @@ public void TestSingle() [Test] public void TestTransient() { - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsTransient(); - Container.Bind().To().FromGameObject().WithGameObjectName(GameObjName).AsTransient(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsTransient(); + Container.Bind().To().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsTransient(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -58,8 +58,8 @@ public void TestTransient() [Test] public void TestCached1() { - Container.Bind().FromGameObject().WithGameObjectName(GameObjName).AsCached(); - Container.Bind().To().FromGameObject().WithGameObjectName(GameObjName).AsCached(); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsCached(); + Container.Bind().To().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -73,7 +73,7 @@ public void TestCached1() [Test] public void TestCached2() { - Container.Bind(typeof(Foo), typeof(IFoo)).To().FromGameObject().WithGameObjectName(GameObjName).AsCached(); + Container.Bind(typeof(Foo), typeof(IFoo)).To().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -87,7 +87,7 @@ public void TestCached2() [Test] public void TestMultipleConcreteTransient1() { - Container.Bind().To(typeof(Foo), typeof(Bar)).FromGameObject() + Container.Bind().To(typeof(Foo), typeof(Bar)).FromNewComponentOnNewGameObject() .WithGameObjectName(GameObjName); Container.BindRootResolve(); @@ -102,7 +102,7 @@ public void TestMultipleConcreteTransient1() [Test] public void TestMultipleConcreteTransient2() { - Container.Bind(typeof(IFoo), typeof(IBar)).To(new List() {typeof(Foo), typeof(Bar)}).FromGameObject() + Container.Bind(typeof(IFoo), typeof(IBar)).To(new List() {typeof(Foo), typeof(Bar)}).FromNewComponentOnNewGameObject() .WithGameObjectName(GameObjName).AsTransient(); Container.BindRootResolve(); @@ -118,7 +118,7 @@ public void TestMultipleConcreteTransient2() [Test] public void TestMultipleConcreteCached() { - Container.Bind(typeof(IFoo), typeof(IBar)).To(new List() {typeof(Foo), typeof(Bar)}).FromGameObject() + Container.Bind(typeof(IFoo), typeof(IBar)).To(new List() {typeof(Foo), typeof(Bar)}).FromNewComponentOnNewGameObject() .WithGameObjectName(GameObjName).AsCached(); Container.BindRootResolve(); @@ -134,7 +134,7 @@ public void TestMultipleConcreteCached() [Test] public void TestMultipleConcreteSingle() { - Container.Bind(typeof(IFoo), typeof(IBar)).To(new List() {typeof(Foo), typeof(Bar)}).FromGameObject() + Container.Bind(typeof(IFoo), typeof(IBar)).To(new List() {typeof(Foo), typeof(Bar)}).FromNewComponentOnNewGameObject() .WithGameObjectName(GameObjName).AsSingle(); Container.BindRootResolve(); @@ -149,7 +149,7 @@ public void TestMultipleConcreteSingle() [Test] public void TestUnderTransformGroup() { - Container.Bind().FromGameObject() + Container.Bind().FromNewComponentOnNewGameObject() .WithGameObjectName(GameObjName).UnderTransformGroup("Foo").AsSingle(); Container.BindRootResolve(); @@ -170,7 +170,7 @@ public void TestUnderTransform() { var tempGameObject = new GameObject("Foo"); - Container.Bind().FromGameObject() + Container.Bind().FromNewComponentOnNewGameObject() .WithGameObjectName(GameObjName).UnderTransform(tempGameObject.transform).AsSingle(); Container.BindRootResolve(); @@ -184,7 +184,7 @@ public void TestUnderTransformGetter() { var tempGameObject = new GameObject("Foo"); - Container.Bind().FromGameObject() + Container.Bind().FromNewComponentOnNewGameObject() .WithGameObjectName(GameObjName).UnderTransform((context) => tempGameObject.transform).AsSingle(); Container.BindRootResolve(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs index 656b379d4..f4d447a46 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs @@ -55,8 +55,8 @@ GameObject JimAndBobPrefab [Test] public void TestTransient() { - Container.Bind().FromPrefab(FooPrefab).AsTransient(); - Container.Bind().FromPrefab(FooPrefab).AsTransient(); + Container.Bind().FromComponentInPrefab(FooPrefab).AsTransient(); + Container.Bind().FromComponentInPrefab(FooPrefab).AsTransient(); Container.BindRootResolve(); @@ -68,8 +68,8 @@ public void TestTransient() [Test] public void TestSingle() { - Container.Bind().To().FromPrefab(FooPrefab).AsSingle().NonLazy(); - Container.Bind().FromPrefab(FooPrefab).AsSingle().NonLazy(); + Container.Bind().To().FromComponentInPrefab(FooPrefab).AsSingle().NonLazy(); + Container.Bind().FromComponentInPrefab(FooPrefab).AsSingle().NonLazy(); Initialize(); @@ -80,8 +80,8 @@ public void TestSingle() public void TestSingle2() { // For ToPrefab, the 'AsSingle' applies to the prefab and not the type, so this is valid - Container.Bind().To().FromPrefab(FooPrefab).AsSingle(); - Container.Bind().FromPrefab(FooPrefab2).AsSingle(); + Container.Bind().To().FromComponentInPrefab(FooPrefab).AsSingle(); + Container.Bind().FromComponentInPrefab(FooPrefab2).AsSingle(); Container.Bind().FromMethod(ctx => ctx.Container.CreateEmptyGameObject("Foo").AddComponent()); Container.BindRootResolve(); @@ -96,8 +96,8 @@ public void TestSingle2() [Test] public void TestSingleIdentifiers() { - Container.Bind().FromPrefab(FooPrefab).WithGameObjectName("Foo").AsSingle().NonLazy(); - Container.Bind().FromPrefab(FooPrefab).WithGameObjectName("Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInPrefab(FooPrefab).WithGameObjectName("Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInPrefab(FooPrefab).WithGameObjectName("Foo").AsSingle().NonLazy(); Initialize(); @@ -110,7 +110,7 @@ public void TestSingleIdentifiers() [Test] public void TestCached1() { - Container.Bind(typeof(Foo), typeof(Bar)).FromPrefab(FooPrefab).WithGameObjectName("Foo").AsCached().NonLazy(); + Container.Bind(typeof(Foo), typeof(Bar)).FromComponentInPrefab(FooPrefab).WithGameObjectName("Foo").AsCached().NonLazy(); Initialize(); @@ -125,7 +125,7 @@ public void TestCached1() public void TestWithArgumentsFail() { // They have required arguments - Container.Bind(typeof(Gorp), typeof(Qux)).FromPrefab(GorpAndQuxPrefab).AsCached().NonLazy(); + Container.Bind(typeof(Gorp), typeof(Qux)).FromComponentInPrefab(GorpAndQuxPrefab).AsCached().NonLazy(); Initialize(); } @@ -134,7 +134,7 @@ public void TestWithArgumentsFail() public void TestWithArguments() { Container.Bind(typeof(Gorp), typeof(Qux)) - .FromPrefab(GorpAndQuxPrefab).WithGameObjectName("GorpAndQux").AsCached() + .FromComponentInPrefab(GorpAndQuxPrefab).WithGameObjectName("GorpAndQux").AsCached() .WithArguments(5, "test1").NonLazy(); Initialize(); @@ -150,7 +150,7 @@ public void TestWithAbstractSearch() { // There are three components that implement INorf on this prefab // and so this should result in a list of 3 INorf's - Container.Bind().FromPrefab(NorfPrefab).NonLazy(); + Container.Bind().FromComponentInPrefab(NorfPrefab).NonLazy(); Initialize(); @@ -163,7 +163,7 @@ public void TestWithAbstractSearch() public void TestAbstractBindingConcreteSearch() { // Should ignore the Norf2 component on it - Container.Bind().To().FromPrefab(NorfPrefab).NonLazy(); + Container.Bind().To().FromComponentInPrefab(NorfPrefab).NonLazy(); Initialize(); @@ -175,7 +175,7 @@ public void TestAbstractBindingConcreteSearch() public void TestCircularDependencies() { // Jim and Bob both depend on each other - Container.Bind(typeof(Jim), typeof(Bob)).FromPrefab(JimAndBobPrefab).AsCached().NonLazy(); + Container.Bind(typeof(Jim), typeof(Bob)).FromComponentInPrefab(JimAndBobPrefab).AsCached().NonLazy(); Container.BindInterfacesTo().AsSingle().NonLazy(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs index 29f3966f2..0a200b10f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs @@ -19,7 +19,7 @@ public class TestFromPrefabResource : ZenjectIntegrationTestFixture public void TestTransientError() { // Validation should detect that it doesn't exist - Container.Bind().FromPrefabResource(PathPrefix + "asdfasdfas").AsTransient().NonLazy(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "asdfasdfas").AsTransient().NonLazy(); Initialize(); } @@ -27,8 +27,8 @@ public void TestTransientError() [Test] public void TestTransient() { - Container.Bind().FromPrefabResource(PathPrefix + "Foo").AsTransient(); - Container.Bind().FromPrefabResource(PathPrefix + "Foo").AsTransient(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").AsTransient(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").AsTransient(); Container.BindRootResolve(); @@ -40,8 +40,8 @@ public void TestTransient() [Test] public void TestSingle() { - Container.Bind().To().FromPrefabResource(PathPrefix + "Foo").AsSingle().NonLazy(); - Container.Bind().FromPrefabResource(PathPrefix + "Foo").AsSingle().NonLazy(); + Container.Bind().To().FromComponentInPrefabResource(PathPrefix + "Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").AsSingle().NonLazy(); Initialize(); @@ -52,8 +52,8 @@ public void TestSingle() public void TestSingle2() { // For ToPrefab, the 'AsSingle' applies to the prefab and not the type, so this is valid - Container.Bind().To().FromPrefabResource(PathPrefix + "Foo").AsSingle(); - Container.Bind().FromPrefabResource(PathPrefix + "Foo2").AsSingle(); + Container.Bind().To().FromComponentInPrefabResource(PathPrefix + "Foo").AsSingle(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo2").AsSingle(); Container.Bind().FromMethod(ctx => ctx.Container.CreateEmptyGameObject("Foo").AddComponent()); Container.BindRootResolve(); @@ -68,8 +68,8 @@ public void TestSingle2() [Test] public void TestSingleIdentifiers() { - Container.Bind().FromPrefabResource(PathPrefix + "Foo").WithGameObjectName("Foo").AsSingle().NonLazy(); - Container.Bind().FromPrefabResource(PathPrefix + "Foo").WithGameObjectName("Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").WithGameObjectName("Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").WithGameObjectName("Foo").AsSingle().NonLazy(); Initialize(); @@ -82,7 +82,7 @@ public void TestSingleIdentifiers() [Test] public void TestCached1() { - Container.Bind(typeof(Foo), typeof(Bar)).FromPrefabResource(PathPrefix + "Foo") + Container.Bind(typeof(Foo), typeof(Bar)).FromComponentInPrefabResource(PathPrefix + "Foo") .WithGameObjectName("Foo").AsCached().NonLazy(); Initialize(); @@ -98,7 +98,7 @@ public void TestCached1() public void TestWithArgumentsFail() { // They have required arguments - Container.Bind(typeof(Gorp), typeof(Qux)).FromPrefabResource(PathPrefix + "GorpAndQux").AsCached().NonLazy(); + Container.Bind(typeof(Gorp), typeof(Qux)).FromComponentInPrefabResource(PathPrefix + "GorpAndQux").AsCached().NonLazy(); Initialize(); } @@ -107,7 +107,7 @@ public void TestWithArgumentsFail() public void TestWithArguments() { Container.Bind(typeof(Gorp), typeof(Qux)) - .FromPrefabResource(PathPrefix + "GorpAndQux").WithGameObjectName("GorpAndQux").AsCached() + .FromComponentInPrefabResource(PathPrefix + "GorpAndQux").WithGameObjectName("GorpAndQux").AsCached() .WithArguments(5, "test1").NonLazy(); Initialize(); @@ -123,7 +123,7 @@ public void TestWithAbstractSearch() { // There are three components that implement INorf on this prefab // and so this should result in a list of 3 INorf's - Container.Bind().FromPrefabResource(PathPrefix + "Norf").NonLazy(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "Norf").NonLazy(); Initialize(); @@ -136,7 +136,7 @@ public void TestWithAbstractSearch() public void TestAbstractBindingConcreteSearch() { // Should ignore the Norf2 component on it - Container.Bind().To().FromPrefabResource(PathPrefix + "Norf").NonLazy(); + Container.Bind().To().FromComponentInPrefabResource(PathPrefix + "Norf").NonLazy(); Initialize(); @@ -148,7 +148,7 @@ public void TestAbstractBindingConcreteSearch() public void TestCircularDependencies() { // Jim and Bob both depend on each other - Container.Bind(typeof(Jim), typeof(Bob)).FromPrefabResource(PathPrefix + "JimAndBob").AsCached().NonLazy(); + Container.Bind(typeof(Jim), typeof(Bob)).FromComponentInPrefabResource(PathPrefix + "JimAndBob").AsCached().NonLazy(); Container.BindInterfacesTo().AsSingle().NonLazy(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromResource.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromResource.cs index c89013665..1fe1db4d0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromResource.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromResource.cs @@ -19,7 +19,7 @@ public void TestBasic() { Container.Bind().FromResource(ResourcePath); - Container.Bind().FromGameObject().AsSingle().WithArguments(1).NonLazy(); + Container.Bind().FromNewComponentOnNewGameObject().AsSingle().WithArguments(1).NonLazy(); Initialize(); } @@ -31,7 +31,7 @@ public void TestTransient() Container.Bind().FromResource(ResourcePath); Container.Bind().To().FromResource(ResourcePath); - Container.Bind().FromGameObject().AsSingle().WithArguments(3).NonLazy(); + Container.Bind().FromNewComponentOnNewGameObject().AsSingle().WithArguments(3).NonLazy(); Initialize(); } @@ -41,7 +41,7 @@ public void TestCached() { Container.Bind().FromResource(ResourcePath).AsCached(); - Container.Bind().FromGameObject().AsSingle().WithArguments(1).NonLazy(); + Container.Bind().FromNewComponentOnNewGameObject().AsSingle().WithArguments(1).NonLazy(); Initialize(); } @@ -52,7 +52,7 @@ public void TestSingle() Container.Bind().FromResource(ResourcePath).AsSingle(); Container.Bind().FromResource(ResourcePath).AsSingle(); - Container.Bind().FromGameObject().AsSingle().WithArguments(2).NonLazy(); + Container.Bind().FromNewComponentOnNewGameObject().AsSingle().WithArguments(2).NonLazy(); Initialize(); } @@ -64,7 +64,7 @@ public void TestSingleWithError() Container.Bind().FromResource(ResourcePath).AsSingle(); Container.Bind().FromResource(ResourcePath2).AsSingle(); - Container.Bind().FromGameObject().AsSingle().WithArguments(2).NonLazy(); + Container.Bind().FromNewComponentOnNewGameObject().AsSingle().WithArguments(2).NonLazy(); Initialize(); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSiblingComponent.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSiblingComponent.cs index 5d43cb165..4aea13734 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSiblingComponent.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSiblingComponent.cs @@ -14,8 +14,8 @@ public class TestFromSiblingComponent : ZenjectIntegrationTestFixture [Test] public void TestBasic() { - Container.Bind().FromGameObject().AsSingle().NonLazy(); - Container.Bind().FromSiblingComponent(); + Container.Bind().FromNewComponentOnNewGameObject().AsSingle().NonLazy(); + Container.Bind().FromNewSiblingComponent(); Initialize(); @@ -27,7 +27,7 @@ public void TestBasic() public void TestInvalidUse() { Container.Bind().NonLazy(); - Container.Bind().FromSiblingComponent(); + Container.Bind().FromNewSiblingComponent(); Initialize(); } @@ -37,10 +37,10 @@ public void TestBasic2() { var gameObject = Container.CreateEmptyGameObject("Test"); - Container.Bind().FromComponent(gameObject).AsSingle().NonLazy(); - Container.Bind().FromComponent(gameObject).AsSingle().NonLazy(); + Container.Bind().FromNewComponentOn(gameObject).AsSingle().NonLazy(); + Container.Bind().FromNewComponentOn(gameObject).AsSingle().NonLazy(); - Container.Bind().FromSiblingComponent(); + Container.Bind().FromNewSiblingComponent(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs index 68be401ef..cf3953b78 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs @@ -31,7 +31,7 @@ GameObject FooSubContainerPrefab [Test] public void TestToGameObjectSelf() { - Container.BindFactory().FromGameObject(); + Container.BindFactory().FromNewComponentOnNewGameObject(); Initialize(); @@ -45,7 +45,7 @@ public void TestToGameObjectSelf() [ExpectedException] public void TestToGameObjectSelfFail() { - Container.BindFactory().FromGameObject(); + Container.BindFactory().FromNewComponentOnNewGameObject(); Initialize(); @@ -55,7 +55,7 @@ public void TestToGameObjectSelfFail() [Test] public void TestToGameObjectConcrete() { - Container.BindFactory().To().FromGameObject(); + Container.BindFactory().To().FromNewComponentOnNewGameObject(); Initialize(); @@ -69,7 +69,7 @@ public void TestToMonoBehaviourSelf() { var gameObject = Container.CreateEmptyGameObject("foo"); - Container.BindFactory().FromComponent(gameObject); + Container.BindFactory().FromNewComponentOn(gameObject); Initialize(); @@ -82,7 +82,7 @@ public void TestToMonoBehaviourSelf() [ExpectedException] public void TestToMonoBehaviourSelfFail() { - Container.BindFactory().FromComponent((GameObject)null); + Container.BindFactory().FromNewComponentOn((GameObject)null); Initialize(); } @@ -92,7 +92,7 @@ public void TestToMonoBehaviourConcrete() { var gameObject = Container.CreateEmptyGameObject("foo"); - Container.BindFactory().To().FromComponent(gameObject); + Container.BindFactory().To().FromNewComponentOn(gameObject); Initialize(); @@ -104,7 +104,7 @@ public void TestToMonoBehaviourConcrete() [Test] public void TestToPrefabSelf() { - Container.BindFactory().FromPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); Initialize(); @@ -120,7 +120,7 @@ public void TestToPrefabSelf() public void TestToPrefabSelfFail() { // Foo3 is not on the prefab - Container.BindFactory().FromPrefab(FooPrefab); + Container.BindFactory().FromComponentInPrefab(FooPrefab); Initialize(); @@ -130,7 +130,7 @@ public void TestToPrefabSelfFail() [Test] public void TestToPrefabConcrete() { - Container.BindFactory().To().FromPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().To().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); Initialize(); @@ -166,7 +166,7 @@ public void TestToResource() [Test] public void TestToPrefabResourceSelf() { - Container.BindFactory().FromPrefabResource("TestBindFactory/Foo").WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInPrefabResource("TestBindFactory/Foo").WithGameObjectName("asdf"); Initialize(); @@ -180,7 +180,7 @@ public void TestToPrefabResourceSelf() [Test] public void TestToPrefabResourceConcrete() { - Container.BindFactory().To().FromPrefabResource("TestBindFactory/Foo").WithGameObjectName("asdf"); + Container.BindFactory().To().FromComponentInPrefabResource("TestBindFactory/Foo").WithGameObjectName("asdf"); Initialize(); @@ -247,7 +247,7 @@ public void TestToSubContainerPrefabResourceConcrete() [Test] public void TestUnderTransformGroup() { - Container.BindFactory().FromGameObject().UnderTransformGroup("Foo"); + Container.BindFactory().FromNewComponentOnNewGameObject().UnderTransformGroup("Foo"); Initialize(); @@ -268,7 +268,7 @@ public void TestUnderTransform() { var tempGameObject = new GameObject("Foo"); - Container.BindFactory().FromGameObject(). + Container.BindFactory().FromNewComponentOnNewGameObject(). UnderTransform(tempGameObject.transform); Initialize(); @@ -283,7 +283,7 @@ public void TestUnderTransformGetter() { var tempGameObject = new GameObject("Foo"); - Container.BindFactory().FromGameObject() + Container.BindFactory().FromNewComponentOnNewGameObject() .UnderTransform((context) => tempGameObject.transform); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryFive.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryFive.cs index 7e8a7b365..81f83c00c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryFive.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryFive.cs @@ -31,7 +31,7 @@ GameObject FooSubContainerPrefab [Test] public void TestToGameObjectSelf() { - Container.BindFactory().FromGameObject(); + Container.BindFactory().FromNewComponentOnNewGameObject(); AddFactoryUser(); @@ -44,7 +44,7 @@ public void TestToGameObjectSelf() [Test] public void TestToGameObjectConcrete() { - Container.BindFactory().To().FromGameObject(); + Container.BindFactory().To().FromNewComponentOnNewGameObject(); AddFactoryUser(); @@ -59,7 +59,7 @@ public void TestToMonoBehaviourSelf() { var gameObject = Container.CreateEmptyGameObject("foo"); - Container.BindFactory().FromComponent(gameObject); + Container.BindFactory().FromNewComponentOn(gameObject); AddFactoryUser(); @@ -74,7 +74,7 @@ public void TestToMonoBehaviourConcrete() { var gameObject = Container.CreateEmptyGameObject("foo"); - Container.BindFactory().To().FromComponent(gameObject); + Container.BindFactory().To().FromNewComponentOn(gameObject); AddFactoryUser(); @@ -87,7 +87,7 @@ public void TestToMonoBehaviourConcrete() [Test] public void TestToPrefabSelf() { - Container.BindFactory().FromPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -101,7 +101,7 @@ public void TestToPrefabSelf() [Test] public void TestToPrefabConcrete() { - Container.BindFactory().To().FromPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().To().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -115,7 +115,7 @@ public void TestToPrefabConcrete() [Test] public void TestToPrefabResourceSelf() { - Container.BindFactory().FromPrefabResource("TestBindFactoryFive/Foo").WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInPrefabResource("TestBindFactoryFive/Foo").WithGameObjectName("asdf"); AddFactoryUser(); @@ -130,7 +130,7 @@ public void TestToPrefabResourceSelf() public void TestToPrefabResourceConcrete() { Container.BindFactory() - .To().FromPrefabResource("TestBindFactoryFive/Foo").WithGameObjectName("asdf"); + .To().FromComponentInPrefabResource("TestBindFactoryFive/Foo").WithGameObjectName("asdf"); AddFactoryUser(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs index 486179c75..56ce3bc52 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs @@ -31,7 +31,7 @@ GameObject FooSubContainerPrefab [Test] public void TestToGameObjectSelf() { - Container.BindFactory().FromGameObject(); + Container.BindFactory().FromNewComponentOnNewGameObject(); AddFactoryUser(); @@ -44,7 +44,7 @@ public void TestToGameObjectSelf() [Test] public void TestToGameObjectConcrete() { - Container.BindFactory().To().FromGameObject(); + Container.BindFactory().To().FromNewComponentOnNewGameObject(); AddFactoryUser(); @@ -59,7 +59,7 @@ public void TestToMonoBehaviourSelf() { var gameObject = Container.CreateEmptyGameObject("foo"); - Container.BindFactory().FromComponent(gameObject); + Container.BindFactory().FromNewComponentOn(gameObject); AddFactoryUser(); @@ -74,7 +74,7 @@ public void TestToMonoBehaviourConcrete() { var gameObject = Container.CreateEmptyGameObject("foo"); - Container.BindFactory().To().FromComponent(gameObject); + Container.BindFactory().To().FromNewComponentOn(gameObject); AddFactoryUser(); @@ -87,7 +87,7 @@ public void TestToMonoBehaviourConcrete() [Test] public void TestToPrefabSelf() { - Container.BindFactory().FromPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -101,7 +101,7 @@ public void TestToPrefabSelf() [Test] public void TestToPrefabConcrete() { - Container.BindFactory().To().FromPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().To().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -115,7 +115,7 @@ public void TestToPrefabConcrete() [Test] public void TestToPrefabResourceSelf() { - Container.BindFactory().FromPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); AddFactoryUser(); @@ -129,7 +129,7 @@ public void TestToPrefabResourceSelf() [Test] public void TestToPrefabResourceConcrete() { - Container.BindFactory().To().FromPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); + Container.BindFactory().To().FromComponentInPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); AddFactoryUser(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs index 0fa9da119..11ca66cbf 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs @@ -25,7 +25,7 @@ GameObject CubePrefab [Test] public void TestPrefabSelfSingle1() { - Container.BindFactory().FromPrefab(CubePrefab).WithGameObjectName(GameObjName); + Container.BindFactory().FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName); AddFactoryUser(); @@ -38,7 +38,7 @@ public void TestPrefabSelfSingle1() [Test] public void TestPrefabConcreteSingle1() { - Container.BindFactory().To().FromPrefab(CubePrefab).WithGameObjectName(GameObjName); + Container.BindFactory().To().FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName); AddFactoryUser(); @@ -51,7 +51,7 @@ public void TestPrefabConcreteSingle1() [Test] public void TestPrefabResourceSelfSingle1() { - Container.BindFactory().FromPrefabResource("TestGameObjectFactoryOne/Cube").WithGameObjectName(GameObjName); + Container.BindFactory().FromComponentInPrefabResource("TestGameObjectFactoryOne/Cube").WithGameObjectName(GameObjName); AddFactoryUser(); @@ -64,7 +64,7 @@ public void TestPrefabResourceSelfSingle1() [Test] public void TestPrefabResourceConcreteSingle1() { - Container.BindFactory().To().FromPrefabResource("TestGameObjectFactoryOne/Cube").WithGameObjectName(GameObjName); + Container.BindFactory().To().FromComponentInPrefabResource("TestGameObjectFactoryOne/Cube").WithGameObjectName(GameObjName); AddFactoryUser(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs index aced264de..950b4db10 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs @@ -25,7 +25,7 @@ GameObject CubePrefab [Test] public void TestGameObjectSelf1() { - Container.BindFactory().FromGameObject().WithGameObjectName(GameObjName); + Container.BindFactory().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName); Initialize(); @@ -38,7 +38,7 @@ public void TestGameObjectSelf1() [Test] public void TestGameObjectConcreteSingle() { - Container.BindFactory().To().FromGameObject().WithGameObjectName(GameObjName); + Container.BindFactory().To().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName); Initialize(); @@ -51,7 +51,7 @@ public void TestGameObjectConcreteSingle() [Test] public void TestPrefabSelfSingle1() { - Container.BindFactory().FromPrefab(CubePrefab).WithGameObjectName(GameObjName); + Container.BindFactory().FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName); Initialize(); @@ -64,7 +64,7 @@ public void TestPrefabSelfSingle1() [Test] public void TestPrefabConcreteSingle1() { - Container.BindFactory().To().FromPrefab(CubePrefab).WithGameObjectName(GameObjName); + Container.BindFactory().To().FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName); Initialize(); @@ -78,7 +78,7 @@ public void TestPrefabConcreteSingle1() public void TestPrefabResourceSelfSingle1() { Container.BindFactory() - .FromPrefabResource(ResourcePrefix + "/Cube").WithGameObjectName(GameObjName); + .FromComponentInPrefabResource(ResourcePrefix + "/Cube").WithGameObjectName(GameObjName); Initialize(); @@ -92,7 +92,7 @@ public void TestPrefabResourceSelfSingle1() public void TestPrefabResourceConcreteSingle1() { Container.BindFactory() - .To().FromPrefabResource(ResourcePrefix + "/Cube").WithGameObjectName(GameObjName); + .To().FromComponentInPrefabResource(ResourcePrefix + "/Cube").WithGameObjectName(GameObjName); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryFive/FooInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryFive/FooInstaller.cs index c3dc7c253..86c6e8b7a 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryFive/FooInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryFive/FooInstaller.cs @@ -29,7 +29,7 @@ public override void InstallBindings() Container.BindInstance(_param4, true).WhenInjectedInto(); Container.BindInstance(_param5, true).WhenInjectedInto(); - Container.Bind().FromGameObject(); + Container.Bind().FromNewComponentOnNewGameObject(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryOne/FooInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryOne/FooInstaller.cs index 89b639a7b..ac36b0f3e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryOne/FooInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryOne/FooInstaller.cs @@ -16,7 +16,7 @@ public void Init(string param1) public override void InstallBindings() { Container.BindInstance(_param1, true).WhenInjectedInto(); - Container.Bind().FromGameObject(); + Container.Bind().FromNewComponentOnNewGameObject(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs index 06c705a07..80339b5f1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs @@ -20,8 +20,8 @@ public void CommonInstall() GameSettingsInstaller.InstallFromResource(Container); var gameSettings = Container.Resolve(); Container.Bind().AsSingle(); - Container.BindFactory().FromPrefab(gameSettings.AsteroidPrefab); - Container.Bind().WithId("Main").FromGameObject(); + Container.BindFactory().FromComponentInPrefab(gameSettings.AsteroidPrefab); + Container.Bind().WithId("Main").FromNewComponentOnNewGameObject(); Container.Bind().AsSingle(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs index 70e16fb99..ea1241527 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs @@ -61,7 +61,7 @@ void InstallAsteroids() // So any classes that want to create new asteroid objects can simply include an injected field // or constructor parameter of type Asteroid.Factory, then call Create() on that Container.BindFactory() - .FromPrefab(_settings.AsteroidPrefab) + .FromComponentInPrefab(_settings.AsteroidPrefab) // We can also tell Zenject what to name the new gameobject here .WithGameObjectName("Asteroid") // GameObjectGroup's are just game objects used for organization @@ -76,8 +76,8 @@ void InstallMisc() Container.BindInterfacesTo().AsSingle(); - Container.BindFactory().FromPrefab(_settings.ExplosionPrefab); - Container.BindFactory().FromPrefab(_settings.BrokenShipPrefab); + Container.BindFactory().FromComponentInPrefab(_settings.ExplosionPrefab); + Container.BindFactory().FromComponentInPrefab(_settings.BrokenShipPrefab); } void InstallShip() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyExplosionHandler.cs similarity index 66% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyExplosionHandler.cs index 57cdae37b..c6bd039be 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyExplosionHandler.cs @@ -7,33 +7,41 @@ namespace Zenject.SpaceFighter public class EnemyDeathHandler { readonly GameEvents _gameEvents; + readonly EnemyFacade.Pool _selfFactory; readonly Settings _settings; - readonly Explosion.Factory _explosionFactory; + readonly Explosion.Pool _explosionPool; readonly AudioPlayer _audioPlayer; readonly Enemy _enemy; + readonly EnemyFacade _facade; public EnemyDeathHandler( Enemy enemy, AudioPlayer audioPlayer, - Explosion.Factory explosionFactory, + Explosion.Pool explosionPool, Settings settings, - GameEvents gameEvents) + EnemyFacade.Pool selfFactory, + GameEvents gameEvents, + EnemyFacade facade) { + _facade = facade; _gameEvents = gameEvents; + _selfFactory = selfFactory; _settings = settings; - _explosionFactory = explosionFactory; + _explosionPool = explosionPool; _audioPlayer = audioPlayer; _enemy = enemy; } public void Die() { - var explosion = _explosionFactory.Spawn(); + var explosion = _explosionPool.Spawn(); explosion.transform.position = _enemy.Position; _audioPlayer.Play(_settings.DeathSound, _settings.DeathSoundVolume); _gameEvents.EnemyKilled(); + + _selfFactory.Despawn(_facade); } [Serializable] @@ -44,4 +52,3 @@ public class Settings } } } - diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyExplosionHandler.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyExplosionHandler.cs.meta index 0d0f070ae..2be865cfa 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyExplosionHandler.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: ee5bad9547ef3b044826da894e166bb8 -timeCreated: 1484525028 +guid: 4fa5943101a09d24a814427210cbd2e1 +timeCreated: 1485638339 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs index 5b4f8d63e..a89e42b1d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs @@ -4,11 +4,10 @@ namespace Zenject.SpaceFighter { - public class EnemyFacade : MonoBehaviour, IPoolable + public class EnemyFacade : MonoBehaviour { Enemy _enemy; EnemyTunables _tunables; - Factory _selfFactory; EnemyDeathHandler _deathHandler; // We can't use a constructor here because MonoFacade derives from @@ -16,11 +15,10 @@ public class EnemyFacade : MonoBehaviour, IPoolable [Inject] public void Construct( Enemy enemy, EnemyTunables tunables, - Factory selfFactory, EnemyDeathHandler deathHandler) + EnemyDeathHandler deathHandler) { _enemy = enemy; _tunables = tunables; - _selfFactory = selfFactory; _deathHandler = deathHandler; } @@ -32,34 +30,24 @@ public Vector3 Position set { _enemy.Position = value; } } - public void OnDespawned() - { - gameObject.SetActive(false); - } - public void Update() { // Always ensure we are on the main plane _enemy.Position = new Vector3(_enemy.Position.x, _enemy.Position.y, 0); } - public void OnSpawned(EnemyTunables tunables) - { - _tunables.Accuracy = tunables.Accuracy; - _tunables.Speed = tunables.Speed; - - gameObject.SetActive(true); - } - public void Die() { _deathHandler.Die(); - _selfFactory.Despawn(this); } - // Here we declare a parameter to our facade factory of type EnemyTunables - public class Factory : PooledFactory + public class Pool : MonoMemoryPool { + protected override void Reinitialize(EnemyFacade enemy, EnemyTunables tunables) + { + enemy._tunables.Accuracy = tunables.Accuracy; + enemy._tunables.Speed = tunables.Speed; + } } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs index b196df2e6..32ae1ab18 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/GameEvents.cs @@ -4,7 +4,7 @@ namespace Zenject.SpaceFighter { public class GameEvents { - public Action PlayerKilled = delegate {}; + public Action PlayerDied = delegate {}; public Action EnemyKilled = delegate {}; } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs index 6fd2d900b..5a610cf5e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateAttack.cs @@ -15,14 +15,14 @@ public class EnemyStateAttack : IEnemyState readonly PlayerFacade _player; readonly Settings _settings; readonly Enemy _enemy; - readonly Bullet.Factory _bulletFactory; + readonly Bullet.Pool _bulletPool; float _lastShootTime; bool _strafeRight; float _lastStrafeChangeTime; public EnemyStateAttack( - Bullet.Factory bulletFactory, + Bullet.Pool bulletPool, Enemy enemy, Settings settings, PlayerFacade player, @@ -38,7 +38,7 @@ public EnemyStateAttack( _player = player; _settings = settings; _enemy = enemy; - _bulletFactory = bulletFactory; + _bulletPool = bulletPool; _strafeRight = Random.Range(0.0f, 1.0f) < 0.5f; } @@ -96,7 +96,7 @@ public void FixedUpdate() void Fire() { - var bullet = _bulletFactory.Spawn( + var bullet = _bulletPool.Spawn( _settings.BulletSpeed, _settings.BulletLifetime, BulletTypes.FromEnemy); // Randomize our aim a bit diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs index 4a4d2ec3b..e3b7146ae 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs @@ -1,6 +1,6 @@ using System; +using System.Collections.Generic; using UnityEngine; -using System.Collections; using Zenject; namespace Zenject.SpaceFighter @@ -17,19 +17,19 @@ public override void InstallBindings() Container.BindInterfacesTo().AsSingle(); - Container.BindPooledFactory() + Container.BindMemoryPool() .FromSubContainerResolve() .ByPrefab(_settings.EnemyFacadePrefab) .UnderTransformGroup("Enemies"); - Container.BindPooledFactory().WithInitialSize(10).ExpandByDoubling() - .FromPrefab(_settings.BulletPrefab) + Container.BindMemoryPool().WithInitialSize(10).ExpandByDoubling() + .FromComponentInPrefab(_settings.BulletPrefab) .UnderTransformGroup("Bullets"); Container.Bind().AsSingle(); - Container.BindPooledFactory().WithInitialSize(3) - .FromPrefab(_settings.ExplosionPrefab) + Container.BindMemoryPool().WithInitialSize(3) + .FromComponentInPrefab(_settings.ExplosionPrefab) .UnderTransformGroup("Explosions"); Container.Bind().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs index 94f4cac79..6305fd186 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs @@ -10,7 +10,7 @@ public enum BulletTypes FromPlayer, } - public class Bullet : MonoBehaviour, IPoolable + public class Bullet : MonoBehaviour { float _startTime; BulletTypes _type; @@ -27,7 +27,7 @@ public class Bullet : MonoBehaviour, IPoolable Material _enemyMaterial = null; [Inject] - Factory _selfFactory; + Pool _bulletPool; public BulletTypes Type { @@ -39,24 +39,6 @@ public Vector3 MoveDirection get { return transform.right; } } - public void OnSpawned(float speed, float lifeTime, BulletTypes type) - { - _type = type; - _speed = speed; - _lifeTime = lifeTime; - - _renderer.material = type == BulletTypes.FromEnemy ? _enemyMaterial : _playerMaterial; - - _startTime = Time.realtimeSinceStartup; - - this.gameObject.SetActive(true); - } - - public void OnDespawned() - { - this.gameObject.SetActive(false); - } - public void OnTriggerEnter(Collider other) { var enemy = other.GetComponent(); @@ -88,11 +70,21 @@ public void Update() public void Despawn() { - _selfFactory.Despawn(this); + _bulletPool.Despawn(this); } - public class Factory : PooledFactory + public class Pool : MonoMemoryPool { + protected override void Reinitialize(Bullet bullet, float speed, float lifeTime, BulletTypes type) + { + bullet._type = type; + bullet._speed = speed; + bullet._lifeTime = lifeTime; + + bullet._renderer.material = type == BulletTypes.FromEnemy ? bullet._enemyMaterial : bullet._playerMaterial; + + bullet._startTime = Time.realtimeSinceStartup; + } } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/EnemySpawner.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/EnemySpawner.cs index 3dc6d7427..e207f5488 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/EnemySpawner.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/EnemySpawner.cs @@ -11,7 +11,7 @@ public class EnemySpawner : ITickable, IInitializable { readonly GameEvents _gameEvents; readonly LevelBoundary _levelBoundary; - readonly EnemyFacade.Factory _enemyFactory; + readonly EnemyFacade.Pool _enemyFactory; readonly Settings _settings; float _desiredNumEnemies; @@ -20,7 +20,7 @@ public class EnemySpawner : ITickable, IInitializable public EnemySpawner( Settings settings, - EnemyFacade.Factory enemyFactory, + EnemyFacade.Pool enemyFactory, LevelBoundary levelBoundary, GameEvents gameEvents) { diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs index a5659e7eb..ebf0794da 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Explosion.cs @@ -6,7 +6,7 @@ namespace Zenject.SpaceFighter { - public class Explosion : MonoBehaviour, IPoolable + public class Explosion : MonoBehaviour { [SerializeField] float _lifeTime; @@ -23,33 +23,25 @@ public class Explosion : MonoBehaviour, IPoolable float _startTime; [Inject] - Factory _selfFactory; - - public void OnSpawned() - { - gameObject.SetActive(true); - - _particleSystem.Clear(); - _particleSystem.Play(); - - _startTime = Time.realtimeSinceStartup; - } - - public void OnDespawned() - { - gameObject.SetActive(false); - } + Pool _pool; public void Update() { if (Time.realtimeSinceStartup - _startTime > _lifeTime) { - _selfFactory.Despawn(this); + _pool.Despawn(this); } } - public class Factory : PooledFactory + public class Pool : MonoMemoryPool { + protected override void Reinitialize(Explosion explosion) + { + explosion._particleSystem.Clear(); + explosion._particleSystem.Play(); + + explosion._startTime = Time.realtimeSinceStartup; + } } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameRestartHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameRestartHandler.cs index 3b4f9fa5c..3a0704a62 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameRestartHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/GameRestartHandler.cs @@ -23,12 +23,12 @@ public GameRestartHandler( public void Initialize() { - _gameEvents.PlayerKilled += OnPlayerKilled; + _gameEvents.PlayerDied += OnPlayerDied; } public void Dispose() { - _gameEvents.PlayerKilled -= OnPlayerKilled; + _gameEvents.PlayerDied -= OnPlayerDied; } public void Tick() @@ -42,7 +42,7 @@ public void Tick() } } - void OnPlayerKilled() + void OnPlayerDied() { // Wait a bit before restarting the scene _delayStartTime = Time.realtimeSinceStartup; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs index 92814b3fa..1eace6afb 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerHealthWatcher.cs @@ -9,12 +9,12 @@ public class PlayerHealthWatcher : ITickable readonly AudioPlayer _audioPlayer; readonly Settings _settings; readonly GameEvents _gameEvents; - readonly Explosion.Factory _explosionFactory; + readonly Explosion.Pool _explosionPool; readonly Player _player; public PlayerHealthWatcher( Player player, - Explosion.Factory explosionFactory, + Explosion.Pool explosionPool, GameEvents gameEvents, Settings settings, AudioPlayer audioPlayer) @@ -22,7 +22,7 @@ public PlayerHealthWatcher( _audioPlayer = audioPlayer; _settings = settings; _gameEvents = gameEvents; - _explosionFactory = explosionFactory; + _explosionPool = explosionPool; _player = player; } @@ -38,12 +38,12 @@ void Die() { _player.IsDead = true; - var explosion = _explosionFactory.Spawn(); + var explosion = _explosionPool.Spawn(); explosion.transform.position = _player.Position; _player.Renderer.enabled = false; - _gameEvents.PlayerKilled(); + _gameEvents.PlayerDied(); _audioPlayer.Play(_settings.DeathSound, _settings.DeathSoundVolume); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs index 716562fd9..47926be73 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Player/PlayerShootHandler.cs @@ -9,14 +9,14 @@ public class PlayerShootHandler : ITickable readonly AudioPlayer _audioPlayer; readonly Player _player; readonly Settings _settings; - readonly Bullet.Factory _bulletFactory; + readonly Bullet.Pool _bulletPool; readonly PlayerInputState _inputState; float _lastFireTime; public PlayerShootHandler( PlayerInputState inputState, - Bullet.Factory bulletFactory, + Bullet.Pool bulletPool, Settings settings, Player player, AudioPlayer audioPlayer) @@ -24,7 +24,7 @@ public PlayerShootHandler( _audioPlayer = audioPlayer; _player = player; _settings = settings; - _bulletFactory = bulletFactory; + _bulletPool = bulletPool; _inputState = inputState; } @@ -46,7 +46,7 @@ void Fire() { _audioPlayer.Play(_settings.Laser, _settings.LaserVolume); - var bullet = _bulletFactory.Spawn( + var bullet = _bulletPool.Spawn( _settings.BulletSpeed, _settings.BulletLifetime, BulletTypes.FromPlayer); bullet.transform.position = _player.Position + _player.LookDir * _settings.BulletOffsetDistance; diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs index cee0448f9..391f6a4ef 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs @@ -9,9 +9,9 @@ public enum PoolExpandMethods Fixed, } - public class PooledFactoryBindInfo + public class MemoryPoolBindInfo { - public PooledFactoryBindInfo() + public MemoryPoolBindInfo() { } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs index b8b50bd07..b4dce4eaf 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs @@ -74,7 +74,7 @@ public ConditionCopyNonLazyBinder FromResolve(object subIdentifier) #if !NOT_UNITY3D - public NameTransformConditionCopyNonLazyBinder FromGameObject() + public NameTransformConditionCopyNonLazyBinder FromNewComponentOnNewGameObject() { var gameObjectInfo = new GameObjectCreationParameters(); @@ -98,7 +98,7 @@ public NameTransformConditionCopyNonLazyBinder FromGameObject() return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public ConditionCopyNonLazyBinder FromComponent(GameObject gameObject) + public ConditionCopyNonLazyBinder FromNewComponentOn(GameObject gameObject) { BindingUtil.AssertIsValidGameObject(gameObject); BindingUtil.AssertIsComponent(ContractType); @@ -112,7 +112,7 @@ public ConditionCopyNonLazyBinder FromComponent(GameObject gameObject) return this; } - public NameTransformConditionCopyNonLazyBinder FromPrefab(UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder FromComponentInPrefab(UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); @@ -141,7 +141,7 @@ public NameTransformConditionCopyNonLazyBinder FromPrefab(UnityEngine.Object pre return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public NameTransformConditionCopyNonLazyBinder FromPrefabResource(string resourcePath) + public NameTransformConditionCopyNonLazyBinder FromComponentInPrefabResource(string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolBindingFinalizer.cs similarity index 72% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolBindingFinalizer.cs index 5f431abf7..8ebd15ce9 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolBindingFinalizer.cs @@ -3,18 +3,18 @@ namespace Zenject { - public class PooledFactoryBindingFinalizer : ProviderBindingFinalizer + public class MemoryPoolBindingFinalizer : ProviderBindingFinalizer { - readonly PooledFactoryBindInfo _poolBindInfo; + readonly MemoryPoolBindInfo _poolBindInfo; readonly FactoryBindInfo _factoryBindInfo; - public PooledFactoryBindingFinalizer( - BindInfo bindInfo, FactoryBindInfo factoryBindInfo, PooledFactoryBindInfo poolBindInfo) + public MemoryPoolBindingFinalizer( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, MemoryPoolBindInfo poolBindInfo) : base(bindInfo) { - // Note that it doesn't derive from PooledFactory - // when used with To<>, so we can only check IDynamicPooledFactory - Assert.That(factoryBindInfo.FactoryType.DerivesFrom()); + // Note that it doesn't derive from MemoryPool + // when used with To<>, so we can only check IMemoryPoolBase + Assert.That(factoryBindInfo.FactoryType.DerivesFrom()); _factoryBindInfo = factoryBindInfo; _poolBindInfo = poolBindInfo; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolBindingFinalizer.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolBindingFinalizer.cs.meta index ce905c20e..d8a147668 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyDeathHandler.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolBindingFinalizer.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 3e69d618f7492e1408cd595325667663 -timeCreated: 1484711332 +guid: 41eb30ac64078db4090dd136ccaf1fbe +timeCreated: 1485699960 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolExpandBinder.cs similarity index 55% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolExpandBinder.cs index 379709b8f..d69642769 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryExpandBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolExpandBinder.cs @@ -4,31 +4,31 @@ namespace Zenject { - public class PooledFactoryExpandBinder : FactoryToChoiceIdBinder + public class MemoryPoolExpandBinder : FactoryToChoiceIdBinder { - public PooledFactoryExpandBinder( - BindInfo bindInfo, FactoryBindInfo factoryBindInfo, PooledFactoryBindInfo poolBindInfo) + public MemoryPoolExpandBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, MemoryPoolBindInfo poolBindInfo) : base(bindInfo, factoryBindInfo) { - PooledFactoryBindInfo = poolBindInfo; + MemoryPoolBindInfo = poolBindInfo; ExpandByOneAtATime(); } - protected PooledFactoryBindInfo PooledFactoryBindInfo + protected MemoryPoolBindInfo MemoryPoolBindInfo { get; private set; } public FactoryToChoiceIdBinder ExpandByOneAtATime() { - PooledFactoryBindInfo.ExpandMethod = PoolExpandMethods.OneAtATime; + MemoryPoolBindInfo.ExpandMethod = PoolExpandMethods.OneAtATime; return this; } public FactoryToChoiceIdBinder ExpandByDoubling() { - PooledFactoryBindInfo.ExpandMethod = PoolExpandMethods.Double; + MemoryPoolBindInfo.ExpandMethod = PoolExpandMethods.Double; return this; } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolExpandBinder.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolExpandBinder.cs.meta index ee09f5257..b28207d65 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolExpandBinder.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 9633957b51f224f4da14fbaffe29a756 -timeCreated: 1484522322 +guid: 95b7c7be81364a740b952460f5a07bbf +timeCreated: 1485699961 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolInitialSizeBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolInitialSizeBinder.cs new file mode 100644 index 000000000..d64a64dfe --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolInitialSizeBinder.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public class MemoryPoolInitialSizeBinder : MemoryPoolExpandBinder + { + public MemoryPoolInitialSizeBinder( + BindInfo bindInfo, FactoryBindInfo factoryBindInfo, MemoryPoolBindInfo poolBindInfo) + : base(bindInfo, factoryBindInfo, poolBindInfo) + { + } + + public MemoryPoolExpandBinder WithInitialSize(int size) + { + MemoryPoolBindInfo.InitialSize = size; + return this; + } + + public FactoryToChoiceIdBinder WithFixedSize(int size) + { + MemoryPoolBindInfo.InitialSize = size; + MemoryPoolBindInfo.ExpandMethod = PoolExpandMethods.Fixed; + return this; + } + } +} + diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolInitialSizeBinder.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolInitialSizeBinder.cs.meta index 2f99449e7..2a903e120 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryBindingFinalizer.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/MemoryPoolInitialSizeBinder.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 30d358f8a701526438fa29e3509159c6 -timeCreated: 1484511595 +guid: 80ff9e6d501d30d4a82639f4ae453712 +timeCreated: 1485699961 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs deleted file mode 100644 index dc13db60d..000000000 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/Pooling/PooledFactoryInitialSizeBinder.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - public class PooledFactoryInitialSizeBinder : PooledFactoryExpandBinder - { - public PooledFactoryInitialSizeBinder( - BindInfo bindInfo, FactoryBindInfo factoryBindInfo, PooledFactoryBindInfo poolBindInfo) - : base(bindInfo, factoryBindInfo, poolBindInfo) - { - } - - public PooledFactoryExpandBinder WithInitialSize(int size) - { - PooledFactoryBindInfo.InitialSize = size; - return this; - } - - public FactoryToChoiceIdBinder WithFixedSize(int size) - { - PooledFactoryBindInfo.InitialSize = size; - PooledFactoryBindInfo.ExpandMethod = PoolExpandMethods.Fixed; - return this; - } - } -} - diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index 2c4c1936b..e4435d692 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -101,7 +101,7 @@ public ScopeArgConditionCopyNonLazyBinder FromFactory(Type factoryType) #if !NOT_UNITY3D - public ScopeArgConditionCopyNonLazyBinder FromComponent(GameObject gameObject) + public ScopeArgConditionCopyNonLazyBinder FromNewComponentOn(GameObject gameObject) { BindingUtil.AssertIsValidGameObject(gameObject); BindingUtil.AssertIsComponent(ConcreteTypes); @@ -115,7 +115,7 @@ public ScopeArgConditionCopyNonLazyBinder FromComponent(GameObject gameObject) return new ScopeArgConditionCopyNonLazyBinder(BindInfo); } - public ArgConditionCopyNonLazyBinder FromSiblingComponent() + public ArgConditionCopyNonLazyBinder FromNewSiblingComponent() { BindingUtil.AssertIsComponent(ConcreteTypes); BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); @@ -127,12 +127,12 @@ public ArgConditionCopyNonLazyBinder FromSiblingComponent() return new ArgConditionCopyNonLazyBinder(BindInfo); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromGameObject() + public NameTransformScopeArgConditionCopyNonLazyBinder FromNewComponentOnNewGameObject() { - return FromGameObject(new GameObjectCreationParameters()); + return FromNewComponentOnNewGameObject(new GameObjectCreationParameters()); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromGameObject( + public NameTransformScopeArgConditionCopyNonLazyBinder FromNewComponentOnNewGameObject( GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsAbstractOrComponentOrGameObject(BindInfo.ContractTypes); @@ -167,13 +167,13 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromGameObject( return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefab(UnityEngine.Object prefab) + public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefab(UnityEngine.Object prefab) { - return FromPrefab( + return FromComponentInPrefab( prefab, new GameObjectCreationParameters()); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefab( + public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefab( UnityEngine.Object prefab, GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsValidPrefab(prefab); @@ -185,12 +185,12 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefab( return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefabResource(string resourcePath) + public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefabResource(string resourcePath) { - return FromPrefabResource(resourcePath, new GameObjectCreationParameters()); + return FromComponentInPrefabResource(resourcePath, new GameObjectCreationParameters()); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromPrefabResource( + public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefabResource( string resourcePath, GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsValidResourcePath(resourcePath); diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs.meta deleted file mode 100644 index 226fcc7da..000000000 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 018cad9d9bbd69d449bdef072f22845c -timeCreated: 1484511595 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IMemoryPool.cs similarity index 50% rename from UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs rename to UnityProject/Assets/Zenject/Source/Factories/Pooling/IMemoryPool.cs index 5163ab6d1..9d9e75340 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IMemoryPool.cs @@ -1,46 +1,58 @@ +using System; namespace Zenject { - public interface IPooledFactory + public interface IMemoryPool { - int NumCreated { get; } + int NumTotal { get; } int NumActive { get; } int NumInactive { get; } + + Type ContractType + { + get; + } + + Type ConcreteType + { + get; + } + + void DespawnAll(); } - public interface IPooledFactory : IPooledFactory + public interface IMemoryPool : IMemoryPool { TValue Spawn(); void Despawn(TValue item); } - public interface IPooledFactory : IPooledFactory + public interface IMemoryPool : IMemoryPool { TValue Spawn(TParam1 param); void Despawn(TValue item); } - public interface IPooledFactory : IPooledFactory + public interface IMemoryPool : IMemoryPool { TValue Spawn(TParam1 param1, TParam2 param2); void Despawn(TValue item); } - public interface IPooledFactory : IPooledFactory + public interface IMemoryPool : IMemoryPool { TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3); void Despawn(TValue item); } - public interface IPooledFactory : IPooledFactory + public interface IMemoryPool : IMemoryPool { TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4); void Despawn(TValue item); } - public interface IPooledFactory : IPooledFactory + public interface IMemoryPool : IMemoryPool { TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5); void Despawn(TValue item); } } - diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IMemoryPool.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IMemoryPool.cs.meta new file mode 100644 index 000000000..7598a2b8b --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IMemoryPool.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 13b8377ec575a1a44a1028ee324ba17a +timeCreated: 1485699960 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs deleted file mode 100644 index 9d0cf2cfe..000000000 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Zenject -{ - public interface IPoolableBase - { - void OnDespawned(); - } - - public interface IPoolable : IPoolableBase - { - void OnSpawned(); - } - - public interface IPoolable : IPoolableBase - { - void OnSpawned(TParam1 p1); - } - - public interface IPoolable : IPoolableBase - { - void OnSpawned(TParam1 p1, TParam2 p2); - } - - public interface IPoolable : IPoolableBase - { - void OnSpawned(TParam1 p1, TParam2 p2, TParam3 p3); - } - - public interface IPoolable : IPoolableBase - { - void OnSpawned(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4); - } - - public interface IPoolable : IPoolableBase - { - void OnSpawned(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TParam5 p5); - } -} diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs.meta deleted file mode 100644 index 5fcbd6ddf..000000000 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPoolable.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 2865ca99e651a9748a36895660955f76 -timeCreated: 1484494442 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs.meta deleted file mode 100644 index 2e5113229..000000000 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/IPooledFactory.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a9da90f9975007c40951b87ea862e20c -timeCreated: 1484494442 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs new file mode 100644 index 000000000..ac4fe29f4 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + // Zero parameters + public abstract class MemoryPool : MemoryPoolBase, IMemoryPool + { + public TValue Spawn() + { + var item = GetInternal(); + Reinitialize(item); + return item; + } + + protected virtual void Reinitialize(TValue item) + { + // Optional + } + } + + // One parameter + public abstract class MemoryPool + : MemoryPoolBase, IMemoryPool + { + public TValue Spawn(TParam1 param) + { + var item = GetInternal(); + Reinitialize(item, param); + return item; + } + + protected virtual void Reinitialize(TValue item, TParam1 p1) + { + // Optional + } + } + + // Two parameters + public abstract class MemoryPool + : MemoryPoolBase, IMemoryPool + { + public TValue Spawn(TParam1 param1, TParam2 param2) + { + var item = GetInternal(); + Reinitialize(item, param1, param2); + return item; + } + + protected abstract void Reinitialize(TValue item, TParam1 p1, TParam2 p2); + } + + // Three parameters + public abstract class MemoryPool + : MemoryPoolBase, IMemoryPool + { + public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3) + { + var item = GetInternal(); + Reinitialize(item, param1, param2, param3); + return item; + } + + protected abstract void Reinitialize(TValue item, TParam1 p1, TParam2 p2, TParam3 p3); + } + + // Four parameters + public abstract class MemoryPool + : MemoryPoolBase, IMemoryPool + { + public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) + { + var item = GetInternal(); + Reinitialize(item, param1, param2, param3, param4); + return item; + } + + protected abstract void Reinitialize(TValue item, TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4); + } + + // Five parameters + public abstract class MemoryPool + : MemoryPoolBase, IMemoryPool + { + public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5) + { + var item = GetInternal(); + Reinitialize(item, param1, param2, param3, param4, param5); + return item; + } + + protected abstract void Reinitialize(TValue item, TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TParam5 p5); + } +} diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs.meta new file mode 100644 index 000000000..42e02ab4f --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 305d88c8b2af3f2479cb45ffb6f2923c +timeCreated: 1485699960 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPoolBase.cs similarity index 64% rename from UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs rename to UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPoolBase.cs index 0385b85a0..a23119430 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/DynamicPooledFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPoolBase.cs @@ -13,45 +13,14 @@ public PoolExceededFixedSizeException(string errorMessage) } } - public interface IDynamicPooledFactory : IValidatable + public abstract class MemoryPoolBase : IValidatable, IMemoryPool { - int NumCreated - { - get; - } - - int NumActive - { - get; - } - - int NumInactive - { - get; - } - - Type ContractType - { - get; - } + readonly HashSet _activeItems = new HashSet(); - Type ConcreteType - { - get; - } - } - - public abstract class DynamicPooledFactory : IDynamicPooledFactory - // don't add generic constraint 'where TContract : IPoolable' since - // we really only require that the concrete type implement that - where TContract : IPoolableBase - { - Stack _pool; + Stack _inactiveItems; Type _concreteType; InjectContext _injectContext; IProvider _provider; - int _numCreated; - int _numActive; PoolExpandMethods _expandMethod; [Inject] @@ -69,32 +38,32 @@ void Construct( _concreteType = concreteType; _injectContext = new InjectContext(container, concreteType); - _pool = new Stack(initialSize); + _inactiveItems = new Stack(initialSize); for (int i = 0; i < initialSize; i++) { - _pool.Push(AllocNew()); + _inactiveItems.Push(AllocNew()); } } public IEnumerable InactiveItems { - get { return _pool; } + get { return _inactiveItems; } } - public int NumCreated + public int NumTotal { - get { return _numCreated; } + get { return NumInactive + NumActive; } } - public int NumActive + public int NumInactive { - get { return _numActive; } + get { return _inactiveItems.Count; } } - public int NumInactive + public int NumActive { - get { return _pool.Count; } + get { return _activeItems.Count; } } public Type ContractType @@ -107,6 +76,29 @@ public Type ConcreteType get { return _concreteType; } } + public void DespawnAll() + { + foreach (var item in _activeItems.ToList()) + { + Despawn(item); + } + } + + public void Despawn(TContract item) + { + Assert.That(!_inactiveItems.Contains(item), + "Tried to return an item to pool {0} twice", this.GetType()); + + bool removed = _activeItems.Remove(item); + + Assert.That(removed, + "Tried to return an item to the pool that was not originally created in pool"); + + _inactiveItems.Push(item); + + OnDespawned(item); + } + TContract AllocNew() { try @@ -116,16 +108,9 @@ TContract AllocNew() Assert.IsNotNull(resultObj); Assert.That(resultObj.GetType().DerivesFromOrEqual(_concreteType)); - _numCreated++; - - var result = (TContract)resultObj; - - // While it might seem a bit weird to call OnDespawned before OnSpawned, - // this is necessary to ensure that MonoBehaviour's get a chance to deactive - // their game object - result.OnDespawned(); - - return result; + var item = (TContract)resultObj; + OnCreated(item); + return item; } catch (Exception e) { @@ -135,7 +120,7 @@ TContract AllocNew() } } - public virtual void Validate() + void IValidatable.Validate() { try { @@ -152,15 +137,18 @@ protected TContract GetInternal() { TContract item; - if (_pool.IsEmpty()) + if (_inactiveItems.IsEmpty()) { ExpandPool(); - Assert.That(!_pool.IsEmpty()); + Assert.That(!_inactiveItems.IsEmpty()); } - item = _pool.Pop(); + item = _inactiveItems.Pop(); - _numActive++; + bool added = _activeItems.Add(item); + Assert.That(added); + + OnSpawned(item); return item; } @@ -172,26 +160,26 @@ void ExpandPool() { throw new PoolExceededFixedSizeException( "Pool factory '{0}' exceeded its max size of '{1}'!" - .Fmt(this.GetType(), _numCreated)); + .Fmt(this.GetType(), NumTotal)); } case PoolExpandMethods.OneAtATime: { - _pool.Push(AllocNew()); + _inactiveItems.Push(AllocNew()); break; } case PoolExpandMethods.Double: { - if (_numCreated == 0) + if (NumTotal == 0) { - _pool.Push(AllocNew()); + _inactiveItems.Push(AllocNew()); } else { - var oldSize = _numCreated; + var oldSize = NumTotal; for (int i = 0; i < oldSize; i++) { - _pool.Push(AllocNew()); + _inactiveItems.Push(AllocNew()); } } break; @@ -203,18 +191,19 @@ void ExpandPool() } } - public void Despawn(TContract item) + protected virtual void OnDespawned(TContract item) { - Assert.That(!_pool.Contains(item), - "Tried to return an item to pool {0} twice", this.GetType()); - - _numActive--; - _pool.Push(item); + // Optional + } - Assert.That(_numActive >= 0, - "Tried to return an item to the pool that was not originally created in pool"); + protected virtual void OnSpawned(TContract item) + { + // Optional + } - item.OnDespawned(); + protected virtual void OnCreated(TContract item) + { + // Optional } } } diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPoolBase.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPoolBase.cs.meta new file mode 100644 index 000000000..10b91a441 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPoolBase.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ba9d727a5d866fb46a576ab76012b727 +timeCreated: 1485703991 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs new file mode 100644 index 000000000..8be790e26 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using ModestTree; + +namespace Zenject +{ + // Zero parameters + // NOTE: For this to work, the given component must be at the root game object of the thing + // you want to use in a pool + public abstract class MonoMemoryPool : MemoryPool + where TValue : Component + { + protected override void OnCreated(TValue item) + { + item.gameObject.SetActive(false); + } + + protected override void OnSpawned(TValue item) + { + item.gameObject.SetActive(true); + } + + protected override void OnDespawned(TValue item) + { + item.gameObject.SetActive(false); + } + } + + // One parameter + // NOTE: For this to work, the given component must be at the root game object of the thing + // you want to use in a pool + public abstract class MonoMemoryPool : MemoryPool + where TValue : Component + { + protected override void OnCreated(TValue item) + { + item.gameObject.SetActive(false); + } + + protected override void OnSpawned(TValue item) + { + item.gameObject.SetActive(true); + } + + protected override void OnDespawned(TValue item) + { + item.gameObject.SetActive(false); + } + } + + // Two parameters + // NOTE: For this to work, the given component must be at the root game object of the thing + // you want to use in a pool + public abstract class MonoMemoryPool + : MemoryPool + where TValue : Component + { + protected override void OnCreated(TValue item) + { + item.gameObject.SetActive(false); + } + + protected override void OnSpawned(TValue item) + { + item.gameObject.SetActive(true); + } + + protected override void OnDespawned(TValue item) + { + item.gameObject.SetActive(false); + } + } + + // Three parameters + // NOTE: For this to work, the given component must be at the root game object of the thing + // you want to use in a pool + public abstract class MonoMemoryPool + : MemoryPool + where TValue : Component + { + protected override void OnCreated(TValue item) + { + item.gameObject.SetActive(false); + } + + protected override void OnSpawned(TValue item) + { + item.gameObject.SetActive(true); + } + + protected override void OnDespawned(TValue item) + { + item.gameObject.SetActive(false); + } + } + + // Four parameters + // NOTE: For this to work, the given component must be at the root game object of the thing + // you want to use in a pool + public abstract class MonoMemoryPool + : MemoryPool + where TValue : Component + { + protected override void OnCreated(TValue item) + { + item.gameObject.SetActive(false); + } + + protected override void OnSpawned(TValue item) + { + item.gameObject.SetActive(true); + } + + protected override void OnDespawned(TValue item) + { + item.gameObject.SetActive(false); + } + } + + // Five parameters + // NOTE: For this to work, the given component must be at the root game object of the thing + // you want to use in a pool + public abstract class MonoMemoryPool + : MemoryPool + where TValue : Component + { + protected override void OnCreated(TValue item) + { + item.gameObject.SetActive(false); + } + + protected override void OnSpawned(TValue item) + { + item.gameObject.SetActive(true); + } + + protected override void OnDespawned(TValue item) + { + item.gameObject.SetActive(false); + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs.meta new file mode 100644 index 000000000..3cbc57168 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1334aecb808e6c145a993cb441f43bdb +timeCreated: 1485703991 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs deleted file mode 100644 index 05fe798ef..000000000 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Collections.Generic; -using ModestTree; - -namespace Zenject -{ - // Zero parameters - public class PooledFactory : DynamicPooledFactory, IPooledFactory - // This generic constraint might be undesirable if using an abstract pooled factory - // where the base class does not implement IPoolable, but this seems less important - // than catching the compiler error for the other much more common cases - where TValue : IPoolable - { - [Inject] - void Construct() - { - Assert.That(ConcreteType.DerivesFromOrEqual(), - "Expected pooled type '{0}' to derive from IPoolable", typeof(TValue)); - } - - // If you were hoping to override this method, use BindPooledFactory<>.ToFactory instead - public TValue Spawn() - { - var item = GetInternal(); - ((IPoolable)item).OnSpawned(); - return item; - } - } - - // One parameter - public class PooledFactory - : DynamicPooledFactory, IPooledFactory - // This generic constraint might be undesirable if using an abstract pooled factory - // where the base class does not implement IPoolable, but this seems less important - // than catching the compiler error for the other much more common cases - where TValue : IPoolable - { - [Inject] - void Construct() - { - Assert.That(ConcreteType.DerivesFromOrEqual>(), - "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); - } - - // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead - public TValue Spawn(TParam1 param) - { - var item = GetInternal(); - ((IPoolable)item).OnSpawned(param); - return item; - } - } - - // Two parameters - public class PooledFactory - : DynamicPooledFactory, IPooledFactory - // This generic constraint might be undesirable if using an abstract pooled factory - // where the base class does not implement IPoolable, but this seems less important - // than catching the compiler error for the other much more common cases - where TValue : IPoolable - { - [Inject] - void Construct() - { - Assert.That(ConcreteType.DerivesFromOrEqual>(), - "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); - } - - // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead - public TValue Spawn(TParam1 param1, TParam2 param2) - { - var item = GetInternal(); - ((IPoolable)item).OnSpawned(param1, param2); - return item; - } - } - - // Three parameters - public class PooledFactory - : DynamicPooledFactory, IPooledFactory - // This generic constraint might be undesirable if using an abstract pooled factory - // where the base class does not implement IPoolable, but this seems less important - // than catching the compiler error for the other much more common cases - where TValue : IPoolable - { - [Inject] - void Construct() - { - Assert.That(ConcreteType.DerivesFromOrEqual>(), - "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); - } - - // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead - public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3) - { - var item = GetInternal(); - ((IPoolable)item).OnSpawned(param1, param2, param3); - return item; - } - } - - // Four parameters - public class PooledFactory - : DynamicPooledFactory, IPooledFactory - // This generic constraint might be undesirable if using an abstract pooled factory - // where the base class does not implement IPoolable, but this seems less important - // than catching the compiler error for the other much more common cases - where TValue : IPoolable - { - [Inject] - void Construct() - { - Assert.That(ConcreteType.DerivesFromOrEqual>(), - "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); - } - - // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead - public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) - { - var item = GetInternal(); - ((IPoolable)item).OnSpawned(param1, param2, param3, param4); - return item; - } - } - - // Five parameters - public class PooledFactory - : DynamicPooledFactory, IPooledFactory - // This generic constraint might be undesirable if using an abstract pooled factory - // where the base class does not implement IPoolable, but this seems less important - // than catching the compiler error for the other much more common cases - where TValue : IPoolable - { - [Inject] - void Construct() - { - Assert.That(ConcreteType.DerivesFromOrEqual>(), - "Expected pooled type '{0}' to derive from {1}", typeof(TValue), typeof(IPoolable)); - } - - // If you were hoping to override this method, use BindPooledFactory<>.ToPooledFactory instead - public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5) - { - var item = GetInternal(); - ((IPoolable)item).OnSpawned(param1, param2, param3, param4, param5); - return item; - } - } -} diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs.meta deleted file mode 100644 index 34e6cd05a..000000000 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/PooledFactory.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: dd3c2dab9a7ec5740bc90affcbd4120b -timeCreated: 1484494443 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs index fea165088..51ffd1ab5 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs @@ -124,7 +124,7 @@ void InstallBindings( if (_kernel == null) { _container.Bind() - .To().FromComponent(this.gameObject).AsSingle().NonLazy(); + .To().FromNewComponentOn(this.gameObject).AsSingle().NonLazy(); } else { diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs index 4567844eb..5ceaf0631 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs @@ -165,13 +165,13 @@ void InstallBindings() // // Short answer is if you want to use IGuiRenderable then // you need to include the following in project context installer: - // `Container.Bind().FromGameObject().AsSingle().CopyIntoAllSubContainers().NonLazy();` + // `Container.Bind().FromNewComponentOnNewGameObject().AsSingle().CopyIntoAllSubContainers().NonLazy();` _container.Bind(typeof(TickableManager), typeof(InitializableManager), typeof(DisposableManager), typeof(GuiRenderableManager)) .ToSelf().AsSingle().CopyIntoAllSubContainers(); _container.Bind().FromInstance(this); - _container.Bind().FromComponent(this.gameObject).AsSingle().NonLazy(); + _container.Bind().FromNewComponentOn(this.gameObject).AsSingle().NonLazy(); InstallSceneBindings(); diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs index 011e91f57..4ec13d003 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs @@ -260,7 +260,7 @@ void InstallBindings() InstallSceneBindings(); - _container.Bind().FromComponent(this.gameObject).AsSingle().NonLazy(); + _container.Bind().FromNewComponentOn(this.gameObject).AsSingle().NonLazy(); _container.Bind().AsSingle(); diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 3d6902eac..e5cffbaf1 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -615,7 +615,7 @@ IEnumerable SafeGetInstances(ProviderPair providerPair, InjectContext co // Use the container associated with the provider to address some rare cases // which would otherwise result in an infinite loop. Like this: - // Container.Bind().FromPrefab(Prefab).AsTransient() + // Container.Bind().FromComponentInPrefab(Prefab).AsTransient() // With the prefab being a GameObjectContext containing a script that has a // ICharacter dependency. In this case, we would otherwise use the _resolvesInProgress // associated with the GameObjectContext container, which will allow the recursive @@ -1960,35 +1960,31 @@ public FactoryToChoiceIdBinder BindFactory() return BindFactoryInternal(); } - PooledFactoryInitialSizeBinder BindPooledFactoryInternal() - where TFactoryConcrete : TFactoryContract, IPooledFactory - where TFactoryContract : IPooledFactory + MemoryPoolInitialSizeBinder BindMemoryPoolInternal() + where TFactoryConcrete : TFactoryContract, IMemoryPool + where TFactoryContract : IMemoryPool { var bindInfo = new BindInfo(typeof(TFactoryContract)); // This interface is used in the optional class PoolCleanupChecker - bindInfo.ContractTypes.Add(typeof(IDynamicPooledFactory)); + // And also allow people to manually call DespawnAll() for all IMemoryPool + // if they want + bindInfo.ContractTypes.Add(typeof(IMemoryPool)); var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); - var poolBindInfo = new PooledFactoryBindInfo(); + var poolBindInfo = new MemoryPoolBindInfo(); - StartBinding().SubFinalizer = new PooledFactoryBindingFinalizer( + StartBinding().SubFinalizer = new MemoryPoolBindingFinalizer( bindInfo, factoryBindInfo, poolBindInfo); - return new PooledFactoryInitialSizeBinder( + return new MemoryPoolInitialSizeBinder( bindInfo, factoryBindInfo, poolBindInfo); } - public PooledFactoryInitialSizeBinder BindPooledFactory() - where TFactory : IPooledFactory + public MemoryPoolInitialSizeBinder BindMemoryPool() + where TFactory : IMemoryPool { - return BindPooledFactoryInternal(); - } - - public PooledFactoryInitialSizeBinder BindIPooledFactory() - where TContract : IPoolable - { - return BindPooledFactoryInternal, PooledFactory>(); + return BindMemoryPoolInternal(); } FactoryToChoiceIdBinder BindFactoryInternal() diff --git a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs index 2054da452..1c69f1608 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs @@ -53,7 +53,7 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co Assert.IsNotNull(context); Assert.That(context.ObjectType.DerivesFrom(), - "Object '{0}' can only be injected into MonoBehaviour's since it was bound with 'FromSiblingComponent'. Attempted to inject into non-MonoBehaviour '{1}'", + "Object '{0}' can only be injected into MonoBehaviour's since it was bound with 'FromNewSiblingComponent'. Attempted to inject into non-MonoBehaviour '{1}'", context.MemberType, context.ObjectType); object instance; diff --git a/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs b/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs index a828229dd..135dcb668 100644 --- a/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs +++ b/UnityProject/Assets/Zenject/Source/Usage/IGuiRenderable.cs @@ -2,10 +2,10 @@ namespace Zenject { // Note that if you want to bind to this class to have GuiRender called on // your non-MonoBehaviour classes, you also need to add - // `Container.Bind().FromGameObject().NonLazy()` to an installer somewhere + // `Container.Bind().FromNewComponentOnNewGameObject().NonLazy()` to an installer somewhere // Or, if you always want this to be supported in all scenes, then add the following inside // an installer that is attached to the ProjectContext: - // `Container.Bind().FromGameObject().AsSingle().CopyIntoAllSubContainers().NonLazy()` + // `Container.Bind().FromNewComponentOnNewGameObject().AsSingle().CopyIntoAllSubContainers().NonLazy()` public interface IGuiRenderable { void GuiRender(); diff --git a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs index 47c9f123c..4a1c5617a 100644 --- a/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs +++ b/UnityProject/Assets/Zenject/Source/Util/PoolCleanupChecker.cs @@ -9,11 +9,11 @@ namespace Zenject // Container.BindInterfaces().To().AsSingle().CopyIntoAllSubContainers().NonLazy() public class PoolCleanupChecker : ILateDisposable { - readonly List _poolFactories; + readonly List _poolFactories; public PoolCleanupChecker( [Inject(Optional = true, Source = InjectSources.Local)] - List poolFactories) + List poolFactories) { _poolFactories = poolFactories; } From b9436fb172a4e69a2fe7c234304356905639f298 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 29 Jan 2017 13:10:21 -0400 Subject: [PATCH 26/62] Added more tests for memory pools --- ...oledFactoryTo0.cs => TestMemoryPoolTo0.cs} | 88 ++++++-------- .../Bindings/TestMemoryPoolTo0.cs.meta} | 4 +- .../Factories/Bindings/TestMemoryPoolTo1.cs | 111 ++++++++++++++++++ ...yTo0.cs.meta => TestMemoryPoolTo1.cs.meta} | 4 +- .../Bindings/TestPooledFactoryTo1.cs | 102 ---------------- .../UnitTests/Editor/Validation.meta | 9 ++ ...ctoryBindInfo.cs => MemoryPoolBindInfo.cs} | 0 .../BindInfo/MemoryPoolBindInfo.cs.meta} | 4 +- 8 files changed, 164 insertions(+), 158 deletions(-) rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestPooledFactoryTo0.cs => TestMemoryPoolTo0.cs} (62%) rename UnityProject/Assets/Zenject/{Source/Binding/BindInfo/PooledFactoryBindInfo.cs.meta => OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs.meta} (76%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestPooledFactoryTo0.cs.meta => TestMemoryPoolTo1.cs.meta} (76%) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta rename UnityProject/Assets/Zenject/Source/Binding/BindInfo/{PooledFactoryBindInfo.cs => MemoryPoolBindInfo.cs} (100%) rename UnityProject/Assets/Zenject/{OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs.meta => Source/Binding/BindInfo/MemoryPoolBindInfo.cs.meta} (76%) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs similarity index 62% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs index e8d58ef94..f9eb3afc5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs @@ -7,124 +7,124 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestPooledFactoryTo0 : ZenjectUnitTestFixture + public class TestMemoryPoolTo0 : ZenjectUnitTestFixture { [Test] public void TestFactoryProperties() { - Container.BindPooledFactory(); + Container.BindMemoryPool(); - var factory = Container.Resolve(); + var factory = Container.Resolve(); Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 0); + Assert.IsEqual(factory.NumTotal, 0); Assert.IsEqual(factory.NumInactive, 0); var foo = factory.Spawn(); Assert.IsEqual(factory.NumActive, 1); - Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumTotal, 1); Assert.IsEqual(factory.NumInactive, 0); Assert.IsEqual(foo.ResetCount, 1); factory.Despawn(foo); Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumTotal, 1); Assert.IsEqual(factory.NumInactive, 1); Assert.IsEqual(foo.ResetCount, 1); foo = factory.Spawn(); Assert.IsEqual(factory.NumActive, 1); - Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumTotal, 1); Assert.IsEqual(factory.NumInactive, 0); Assert.IsEqual(foo.ResetCount, 2); var foo2 = factory.Spawn(); Assert.IsEqual(factory.NumActive, 2); - Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumTotal, 2); Assert.IsEqual(factory.NumInactive, 0); Assert.IsEqual(foo2.ResetCount, 1); factory.Despawn(foo); Assert.IsEqual(factory.NumActive, 1); - Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumTotal, 2); Assert.IsEqual(factory.NumInactive, 1); Assert.IsEqual(foo.ResetCount, 2); factory.Despawn(foo2); Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumTotal, 2); Assert.IsEqual(factory.NumInactive, 2); } [Test] public void TestExpandDouble() { - Container.BindPooledFactory().ExpandByDoubling(); + Container.BindMemoryPool().ExpandByDoubling(); - var factory = Container.Resolve(); + var factory = Container.Resolve(); Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 0); + Assert.IsEqual(factory.NumTotal, 0); Assert.IsEqual(factory.NumInactive, 0); var foo = factory.Spawn(); Assert.IsEqual(factory.NumActive, 1); - Assert.IsEqual(factory.NumCreated, 1); + Assert.IsEqual(factory.NumTotal, 1); Assert.IsEqual(factory.NumInactive, 0); var foo2 = factory.Spawn(); Assert.IsEqual(factory.NumActive, 2); - Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumTotal, 2); Assert.IsEqual(factory.NumInactive, 0); var foo3 = factory.Spawn(); Assert.IsEqual(factory.NumActive, 3); - Assert.IsEqual(factory.NumCreated, 4); + Assert.IsEqual(factory.NumTotal, 4); Assert.IsEqual(factory.NumInactive, 1); factory.Despawn(foo2); Assert.IsEqual(factory.NumActive, 2); - Assert.IsEqual(factory.NumCreated, 4); + Assert.IsEqual(factory.NumTotal, 4); Assert.IsEqual(factory.NumInactive, 2); var foo4 = factory.Spawn(); Assert.IsEqual(factory.NumActive, 3); - Assert.IsEqual(factory.NumCreated, 4); + Assert.IsEqual(factory.NumTotal, 4); Assert.IsEqual(factory.NumInactive, 1); } [Test] public void TestFixedSize() { - Container.BindPooledFactory().WithFixedSize(2); + Container.BindMemoryPool().WithFixedSize(2); - var factory = Container.Resolve(); + var factory = Container.Resolve(); Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumTotal, 2); Assert.IsEqual(factory.NumInactive, 2); var foo = factory.Spawn(); Assert.IsEqual(factory.NumActive, 1); - Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumTotal, 2); Assert.IsEqual(factory.NumInactive, 1); var foo2 = factory.Spawn(); Assert.IsEqual(factory.NumActive, 2); - Assert.IsEqual(factory.NumCreated, 2); + Assert.IsEqual(factory.NumTotal, 2); Assert.IsEqual(factory.NumInactive, 0); Assert.Throws(() => factory.Spawn()); @@ -133,12 +133,12 @@ public void TestFixedSize() [Test] public void TestInitialSize() { - Container.BindPooledFactory().WithInitialSize(5); + Container.BindMemoryPool().WithInitialSize(5); - var factory = Container.Resolve(); + var factory = Container.Resolve(); Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 5); + Assert.IsEqual(factory.NumTotal, 5); Assert.IsEqual(factory.NumInactive, 5); } @@ -148,12 +148,12 @@ public Bar() { } - public class Factory : Factory + public class Pool : MemoryPool { } } - class Foo : IPoolable + class Foo { public Foo() { @@ -164,26 +164,22 @@ public int ResetCount get; private set; } - public void OnDespawned() - { - } - - public void OnSpawned() - { - ResetCount++; - } - - public class Factory : PooledFactory + public class Pool : MemoryPool { + protected override void OnSpawned(Foo foo) + { + foo.ResetCount++; + } } } [Test] public void TestSubContainers() { - Container.BindPooledFactory().FromSubContainerResolve().ByMethod(InstallQux).NonLazy(); + Container.BindMemoryPool() + .FromSubContainerResolve().ByMethod(InstallQux).NonLazy(); - var factory = Container.Resolve(); + var factory = Container.Resolve(); var qux = factory.Spawn(); } @@ -192,17 +188,9 @@ void InstallQux(DiContainer subContainer) subContainer.Bind().AsSingle(); } - class Qux : IPoolable + class Qux { - public void OnDespawned() - { - } - - public void OnSpawned() - { - } - - public class Factory : PooledFactory + public class Pool : MemoryPool { } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs.meta index f118825b5..0cb582687 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: a6c4ab8068bafb94ba72dc8314d8ad56 -timeCreated: 1484520532 +guid: 11208da6895a449438447d414a0c20cb +timeCreated: 1485709788 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs new file mode 100644 index 000000000..043440cc2 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs @@ -0,0 +1,111 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Assert=ModestTree.Assert; + +#pragma warning disable 219 + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestMemoryPoolTo1 : ZenjectUnitTestFixture + { + [Test] + public void TestFactoryProperties() + { + Container.BindMemoryPool(); + + var pool = Container.Resolve(); + + Assert.IsEqual(pool.NumActive, 0); + Assert.IsEqual(pool.NumTotal, 0); + Assert.IsEqual(pool.NumInactive, 0); + + var foo = pool.Spawn("asdf"); + + Assert.IsEqual(pool.NumActive, 1); + Assert.IsEqual(pool.NumTotal, 1); + Assert.IsEqual(pool.NumInactive, 0); + Assert.IsEqual(foo.ResetCount, 1); + Assert.IsEqual(foo.Value, "asdf"); + + pool.Despawn(foo); + + Assert.IsEqual(pool.NumActive, 0); + Assert.IsEqual(pool.NumTotal, 1); + Assert.IsEqual(pool.NumInactive, 1); + Assert.IsEqual(foo.ResetCount, 1); + + foo = pool.Spawn("zxcv"); + + Assert.IsEqual(pool.NumActive, 1); + Assert.IsEqual(pool.NumTotal, 1); + Assert.IsEqual(pool.NumInactive, 0); + Assert.IsEqual(foo.ResetCount, 2); + Assert.IsEqual(foo.Value, "zxcv"); + + var foo2 = pool.Spawn("qwer"); + + Assert.IsEqual(pool.NumActive, 2); + Assert.IsEqual(pool.NumTotal, 2); + Assert.IsEqual(pool.NumInactive, 0); + Assert.IsEqual(foo2.ResetCount, 1); + Assert.IsEqual(foo2.Value, "qwer"); + + pool.Despawn(foo); + + Assert.IsEqual(pool.NumActive, 1); + Assert.IsEqual(pool.NumTotal, 2); + Assert.IsEqual(pool.NumInactive, 1); + Assert.IsEqual(foo.ResetCount, 2); + + pool.Despawn(foo2); + + Assert.IsEqual(pool.NumActive, 0); + Assert.IsEqual(pool.NumTotal, 2); + Assert.IsEqual(pool.NumInactive, 2); + + pool.Spawn("zxcv"); + pool.Spawn("bxzc"); + pool.Spawn("bxzc"); + + Assert.IsEqual(pool.NumActive, 3); + Assert.IsEqual(pool.NumTotal, 3); + Assert.IsEqual(pool.NumInactive, 0); + + pool.DespawnAll(); + + Assert.IsEqual(pool.NumActive, 0); + Assert.IsEqual(pool.NumTotal, 3); + Assert.IsEqual(pool.NumInactive, 3); + } + + class Foo + { + public Foo() + { + } + + public string Value + { + get; + private set; + } + + public int ResetCount + { + get; private set; + } + + public class Pool : MemoryPool + { + protected override void Reinitialize(Foo foo, string value) + { + foo.Value = value; + foo.ResetCount++; + } + } + } + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs.meta index 49e31b2a2..e6652ade9 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo0.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: b0a43e0c0ddc4a140869201945a9281f -timeCreated: 1484494442 +guid: 45212ad17d904b949906641839ce39da +timeCreated: 1485709788 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs deleted file mode 100644 index 8958b0cb1..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System.Collections.Generic; -using NUnit.Framework; -using Assert=ModestTree.Assert; - -#pragma warning disable 219 - -namespace Zenject.Tests.Bindings -{ - [TestFixture] - public class TestPooledFactoryTo1 : ZenjectUnitTestFixture - { - [Test] - public void TestFactoryProperties() - { - Container.BindPooledFactory(); - - var factory = Container.Resolve(); - - Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 0); - Assert.IsEqual(factory.NumInactive, 0); - - var foo = factory.Spawn("asdf"); - - Assert.IsEqual(factory.NumActive, 1); - Assert.IsEqual(factory.NumCreated, 1); - Assert.IsEqual(factory.NumInactive, 0); - Assert.IsEqual(foo.ResetCount, 1); - Assert.IsEqual(foo.Value, "asdf"); - - factory.Despawn(foo); - - Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 1); - Assert.IsEqual(factory.NumInactive, 1); - Assert.IsEqual(foo.ResetCount, 1); - - foo = factory.Spawn("zxcv"); - - Assert.IsEqual(factory.NumActive, 1); - Assert.IsEqual(factory.NumCreated, 1); - Assert.IsEqual(factory.NumInactive, 0); - Assert.IsEqual(foo.ResetCount, 2); - Assert.IsEqual(foo.Value, "zxcv"); - - var foo2 = factory.Spawn("qwer"); - - Assert.IsEqual(factory.NumActive, 2); - Assert.IsEqual(factory.NumCreated, 2); - Assert.IsEqual(factory.NumInactive, 0); - Assert.IsEqual(foo2.ResetCount, 1); - Assert.IsEqual(foo2.Value, "qwer"); - - factory.Despawn(foo); - - Assert.IsEqual(factory.NumActive, 1); - Assert.IsEqual(factory.NumCreated, 2); - Assert.IsEqual(factory.NumInactive, 1); - Assert.IsEqual(foo.ResetCount, 2); - - factory.Despawn(foo2); - - Assert.IsEqual(factory.NumActive, 0); - Assert.IsEqual(factory.NumCreated, 2); - Assert.IsEqual(factory.NumInactive, 2); - } - - class Foo : IPoolable - { - public Foo() - { - } - - public string Value - { - get; - private set; - } - - public int ResetCount - { - get; private set; - } - - public void OnDespawned() - { - } - - public void OnSpawned(string value) - { - Value = value; - ResetCount++; - } - - public class Factory : PooledFactory - { - } - } - } -} - - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta new file mode 100644 index 000000000..2f86c5428 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ab44aef4a43514d459389abc0dd0e481 +folderAsset: yes +timeCreated: 1485709788 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs similarity index 100% rename from UnityProject/Assets/Zenject/Source/Binding/BindInfo/PooledFactoryBindInfo.cs rename to UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs.meta index 89d951d4a..7305d187e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestPooledFactoryTo1.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: a059ebd93077af547b246a2dcc072524 -timeCreated: 1484522322 +guid: b7c8d1b2e9765964289bb6bcd23b9d2f +timeCreated: 1485709789 licenseType: Free MonoImporter: serializedVersion: 2 From 874f94ef955499997ac0e128beab7156edc30a77 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 29 Jan 2017 23:11:17 -0400 Subject: [PATCH 27/62] - Added FromComponentInChildren, FromComponentInParents, FromComponentInSiblings, and FromComponentInHierarchy bind methods - Minor optimizations - Added FromMethodMultiple - Removed support for using the prefab bind methods with game object directly since it was weird and not that useful - Added some more tests --- .../Bindings/Editor/TestBindGameObject.cs | 146 -------------- .../Editor/TestBindGameObject.cs.meta | 12 -- .../Editor/TestFromComponentInChildren.cs | 72 +++++++ .../TestFromComponentInChildren.cs.meta} | 4 +- .../Editor/TestFromComponentInHierarchy.cs | 60 ++++++ .../TestFromComponentInHierarchy.cs.meta} | 4 +- ...omComponentInHierarchyGameObjectContext.cs | 48 +++++ ...onentInHierarchyGameObjectContext.cs.meta} | 4 +- .../Editor/TestFromComponentInParents.cs | 74 +++++++ .../TestFromComponentInParents.cs.meta} | 4 +- .../Editor/TestFromComponentInSiblings.cs | 73 +++++++ .../TestFromComponentInSiblings.cs.meta | 12 ++ ...omponentInHierarchyGameObjectContext.meta} | 4 +- .../Foo.prefab | 125 ++++++++++++ .../Foo.prefab.meta | 8 + ...ComponentInHierarchyGameObjectContext.meta | 9 + .../Foo.cs | 12 ++ .../Foo.cs.meta | 12 ++ .../FooInstaller.cs | 20 ++ .../FooInstaller.cs.meta | 12 ++ .../Gorp.cs | 9 + .../Gorp.cs.meta | 12 ++ .../Editor/TestGameObjectFactoryOne.cs | 130 ------------ .../Editor/TestGameObjectFactoryZero.cs | 114 ----------- .../Factories/TestGameObjectFactoryOne/Foo.cs | 20 -- .../TestGameObjectFactoryOne/Foo.cs.meta | 12 -- .../Bindings/{TestTo.cs => TestFrom.cs} | 2 +- .../Editor/Bindings/TestFrom.cs.meta | 12 ++ .../{TestToFactory.cs => TestFromFactory.cs} | 2 +- .../Editor/Bindings/TestFromFactory.cs.meta | 12 ++ .../{TestToGetter.cs => TestFromGetter.cs} | 2 +- .../Editor/Bindings/TestFromGetter.cs.meta | 12 ++ ...{TestToInstance.cs => TestFromInstance.cs} | 2 +- .../Editor/Bindings/TestFromInstance.cs.meta | 12 ++ .../{TestToMethod.cs => TestFromMethod.cs} | 2 +- .../Editor/Bindings/TestFromMethod.cs.meta | 12 ++ .../Editor/Bindings/TestFromMethodMultiple.cs | 189 ++++++++++++++++++ .../Bindings/TestFromMethodMultiple.cs.meta | 12 ++ .../{TestToResolve.cs => TestFromResolve.cs} | 2 +- .../Editor/Bindings/TestFromResolve.cs.meta | 12 ++ ...er.cs => TestFromSubContainerInstaller.cs} | 2 +- .../TestFromSubContainerInstaller.cs.meta | 12 ++ ...ethod.cs => TestFromSubContainerMethod.cs} | 2 +- .../TestFromSubContainerMethod.cs.meta | 12 ++ .../UnitTests/Editor/Bindings/TestTo.cs.meta | 12 -- .../Editor/Bindings/TestToFactory.cs.meta | 12 -- .../Editor/Bindings/TestToGetter.cs.meta | 12 -- .../Editor/Bindings/TestToInstance.cs.meta | 12 -- .../Editor/Bindings/TestToMethod.cs.meta | 12 -- .../Editor/Bindings/TestToResolve.cs.meta | 12 -- .../TestToSubContainerInstaller.cs.meta | 12 -- .../Bindings/TestToSubContainerMethod.cs.meta | 12 -- ...{TestFactoryTo0.cs => TestFactoryFrom0.cs} | 2 +- .../Bindings/TestFactoryFrom0.cs.meta | 12 ++ ...{TestFactoryTo1.cs => TestFactoryFrom1.cs} | 2 +- .../Bindings/TestFactoryFrom1.cs.meta | 12 ++ ...{TestFactoryTo5.cs => TestFactoryFrom5.cs} | 2 +- .../Bindings/TestFactoryFrom5.cs.meta | 12 ++ ...Factory0.cs => TestFactoryFromFactory0.cs} | 2 +- .../Bindings/TestFactoryFromFactory0.cs.meta | 12 ++ ...Factory1.cs => TestFactoryFromFactory1.cs} | 2 +- .../Bindings/TestFactoryFromFactory1.cs.meta | 12 ++ ...ToGetter0.cs => TestFactoryFromGetter0.cs} | 2 +- .../Bindings/TestFactoryFromGetter0.cs.meta | 12 ++ ...stance0.cs => TestFactoryFromInstance0.cs} | 2 +- .../Bindings/TestFactoryFromInstance0.cs.meta | 12 ++ ...ToMethod0.cs => TestFactoryFromMethod0.cs} | 2 +- .../Bindings/TestFactoryFromMethod0.cs.meta | 12 ++ ...ToMethod1.cs => TestFactoryFromMethod1.cs} | 2 +- .../Bindings/TestFactoryFromMethod1.cs.meta | 12 ++ ...Resolve0.cs => TestFactoryFromResolve0.cs} | 2 +- .../Bindings/TestFactoryFromResolve0.cs.meta | 12 ++ ... TestFactoryFromSubContainerInstaller0.cs} | 2 +- ...tFactoryFromSubContainerInstaller0.cs.meta | 12 ++ ... TestFactoryFromSubContainerInstaller1.cs} | 2 +- ...tFactoryFromSubContainerInstaller1.cs.meta | 12 ++ ... => TestFactoryFromSubContainerMethod0.cs} | 2 +- ...TestFactoryFromSubContainerMethod0.cs.meta | 12 ++ ... => TestFactoryFromSubContainerMethod1.cs} | 2 +- ...TestFactoryFromSubContainerMethod1.cs.meta | 12 ++ .../Factories/Bindings/TestFactoryTo0.cs.meta | 12 -- .../Factories/Bindings/TestFactoryTo1.cs.meta | 12 -- .../Factories/Bindings/TestFactoryTo5.cs.meta | 12 -- .../Bindings/TestFactoryToFactory0.cs.meta | 12 -- .../Bindings/TestFactoryToFactory1.cs.meta | 12 -- .../Bindings/TestFactoryToGetter0.cs.meta | 12 -- .../Bindings/TestFactoryToInstance0.cs.meta | 12 -- .../Bindings/TestFactoryToMethod0.cs.meta | 12 -- .../Bindings/TestFactoryToMethod1.cs.meta | 12 -- .../Bindings/TestFactoryToResolve0.cs.meta | 12 -- ...estFactoryToSubContainerInstaller0.cs.meta | 12 -- ...estFactoryToSubContainerInstaller1.cs.meta | 12 -- .../TestFactoryToSubContainerMethod0.cs.meta | 12 -- .../TestFactoryToSubContainerMethod1.cs.meta | 12 -- ...estMemoryPoolTo0.cs => TestMemoryPool0.cs} | 2 +- .../Bindings/TestMemoryPool0.cs.meta | 12 ++ ...estMemoryPoolTo1.cs => TestMemoryPool1.cs} | 26 ++- .../Bindings/TestMemoryPool1.cs.meta | 12 ++ .../BindInfo/MemoryPoolBindInfo.cs.meta | 4 +- .../ConcreteBinders/ConcreteBinderGeneric.cs | 2 +- .../ConcreteBinderNonGeneric.cs | 2 +- .../Binders/Factory/FactoryFromBinderBase.cs | 75 ++----- .../Binding/Binders/FromBinders/FromBinder.cs | 71 +++---- .../Binders/FromBinders/FromBinderGeneric.cs | 69 +++++++ .../FromBinders/FromBinderNonGeneric.cs | 6 + .../Zenject/Source/Binding/BindingUtil.cs | 48 +---- .../Finalizers/PrefabBindingFinalizer.cs | 5 - .../PrefabResourceBindingFinalizer.cs | 11 +- .../Testing/ZenjectIntegrationTestFixture.cs | 3 +- .../Source/Install/Contexts/Context.cs | 2 + .../Source/Install/Contexts/ContextUtil.cs | 8 +- .../Install/Contexts/GameObjectContext.cs | 5 + .../Source/Install/Contexts/ProjectContext.cs | 5 + .../Source/Install/Contexts/SceneContext.cs | 5 + .../Install/Contexts/SceneDecoratorContext.cs | 7 + .../Zenject/Source/Internal/ReflectionUtil.cs | 36 ++++ .../Assets/Zenject/Source/Main/DiContainer.cs | 62 ++++-- .../Source/Providers/CachedProvider.cs | 9 +- .../Providers/MethodProviderMultiple.cs | 53 +++++ .../Providers/MethodProviderMultiple.cs.meta | 12 ++ .../PrefabResourceSingletonProviderCreator.cs | 2 +- .../Prefab/PrefabSingletonProviderCreator.cs | 2 +- .../Providers/Singleton/SingletonTypes.cs | 33 ++- .../StandardSingletonProviderCreator.cs | 8 +- ...inerSingletonProviderCreatorByInstaller.cs | 2 +- ...ntainerSingletonProviderCreatorByMethod.cs | 2 +- ...ntainerSingletonProviderCreatorByPrefab.cs | 2 +- ...ingletonProviderCreatorByPrefabResource.cs | 2 +- 128 files changed, 1455 insertions(+), 935 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInChildren.cs rename UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/{Factories/Editor/TestGameObjectFactoryZero.cs.meta => Bindings/Editor/TestFromComponentInChildren.cs.meta} (76%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchy.cs rename UnityProject/Assets/Zenject/OptionalExtras/{UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs.meta => IntegrationTests/Bindings/Editor/TestFromComponentInHierarchy.cs.meta} (76%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs rename UnityProject/Assets/Zenject/OptionalExtras/{UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs.meta => IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs.meta} (76%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInParents.cs rename UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/{Factories/Editor/TestGameObjectFactoryOne.cs.meta => Bindings/Editor/TestFromComponentInParents.cs.meta} (76%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/{Factories/TestGameObjectFactoryOne.meta => Bindings/Resources/TestFromComponentInHierarchyGameObjectContext.meta} (67%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext/Foo.prefab create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext/Foo.prefab.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Foo.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Foo.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/FooInstaller.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/FooInstaller.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Gorp.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Gorp.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne/Foo.cs delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne/Foo.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/{TestTo.cs => TestFrom.cs} (99%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/{TestToFactory.cs => TestFromFactory.cs} (98%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromFactory.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/{TestToGetter.cs => TestFromGetter.cs} (97%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromGetter.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/{TestToInstance.cs => TestFromInstance.cs} (96%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromInstance.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/{TestToMethod.cs => TestFromMethod.cs} (98%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethod.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethodMultiple.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethodMultiple.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/{TestToResolve.cs => TestFromResolve.cs} (98%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/{TestToSubContainerInstaller.cs => TestFromSubContainerInstaller.cs} (97%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/{TestToSubContainerMethod.cs => TestFromSubContainerMethod.cs} (98%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryTo0.cs => TestFactoryFrom0.cs} (95%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryTo1.cs => TestFactoryFrom1.cs} (95%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom1.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryTo5.cs => TestFactoryFrom5.cs} (96%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom5.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToFactory0.cs => TestFactoryFromFactory0.cs} (96%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToFactory1.cs => TestFactoryFromFactory1.cs} (95%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory1.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToGetter0.cs => TestFactoryFromGetter0.cs} (93%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromGetter0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToInstance0.cs => TestFactoryFromInstance0.cs} (93%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromInstance0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToMethod0.cs => TestFactoryFromMethod0.cs} (93%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToMethod1.cs => TestFactoryFromMethod1.cs} (95%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod1.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToResolve0.cs => TestFactoryFromResolve0.cs} (96%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromResolve0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToSubContainerInstaller0.cs => TestFactoryFromSubContainerInstaller0.cs} (94%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToSubContainerInstaller1.cs => TestFactoryFromSubContainerInstaller1.cs} (95%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToSubContainerMethod0.cs => TestFactoryFromSubContainerMethod0.cs} (93%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestFactoryToSubContainerMethod1.cs => TestFactoryFromSubContainerMethod1.cs} (95%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod1.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs.meta delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestMemoryPoolTo0.cs => TestMemoryPool0.cs} (98%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool0.cs.meta rename UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/{TestMemoryPoolTo1.cs => TestMemoryPool1.cs} (84%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Providers/MethodProviderMultiple.cs create mode 100644 UnityProject/Assets/Zenject/Source/Providers/MethodProviderMultiple.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs deleted file mode 100644 index ce4287787..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using UnityEngine; -using ModestTree; -using Assert=ModestTree.Assert; - -namespace Zenject.Tests.Bindings -{ - [TestFixture] - public class TestBindGameObject : ZenjectIntegrationTestFixture - { - const string GameObjName = "TestObj"; - - GameObject CubePrefab - { - get - { - return (GameObject)Resources.Load("TestBindGameObject/Cube"); - } - } - - [Test] - public void TestGameObjectSelfSingle1() - { - Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); - Container.BindRootResolve(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestGameObjectSelfSingle2() - { - Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); - Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); - Container.Bind().WithId("asdf").FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); - - Container.BindRootResolve(); - Container.BindRootResolve("asdf"); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - [ExpectedException] - public void TestGameObjectSelfSingleConflict() - { - Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); - Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName("asdf").AsSingle(); - - Container.BindRootResolve(); - - Initialize(); - } - - [Test] - public void TestGameObjectSelfTransient() - { - Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsTransient(); - Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsTransient(); - Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName("asdf").AsTransient(); - Container.BindRootResolve(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 3); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 2); - } - - [Test] - public void TestGameObjectConcreteSingle() - { - Container.Bind().To().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName).AsSingle(); - - Container.BindRootResolve(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestPrefabSelfSingle1() - { - Container.Bind().FromComponentInPrefab(CubePrefab) - .WithGameObjectName(GameObjName).AsSingle().NonLazy(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - - Assert.IsNotNull(Container.Resolve().GetComponent()); - } - - [Test] - public void TestPrefabConcreteSingle1() - { - Container.Bind().To() - .FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName).AsSingle().NonLazy(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - - Assert.IsNotNull(((GameObject)Container.Resolve()).GetComponent()); - } - - [Test] - public void TestPrefabResourceSelfSingle1() - { - Container.Bind().FromComponentInPrefabResource("TestBindGameObject/Cube").WithGameObjectName(GameObjName).AsSingle().NonLazy(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - - Assert.IsNotNull(Container.Resolve().GetComponent()); - } - - [Test] - public void TestPrefabResourceConcreteSingle1() - { - Container.Bind().To() - .FromComponentInPrefabResource("TestBindGameObject/Cube").WithGameObjectName(GameObjName).AsSingle().NonLazy(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - - Assert.IsNotNull(((GameObject)Container.Resolve()).GetComponent()); - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs.meta deleted file mode 100644 index c027c7fbf..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestBindGameObject.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4cb971f9d3f91fb4cbf577653ed1844a -timeCreated: 1459194367 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInChildren.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInChildren.cs new file mode 100644 index 000000000..3ddf074eb --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInChildren.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using ModestTree; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestFromComponentInChildren : ZenjectIntegrationTestFixture + { + Root _root; + Child _child1; + Child _child2; + Grandchild _grandchild; + + void InitScene() + { + _root = new GameObject().AddComponent(); + + _child1 = new GameObject().AddComponent(); + _child1.transform.SetParent(_root.transform); + + _child2 = new GameObject().AddComponent(); + _child2.transform.SetParent(_root.transform); + + _grandchild = new GameObject().AddComponent(); + _grandchild.transform.SetParent(_child1.transform); + } + + public override void SetUp() + { + InitScene(); + + base.SetUp(); + } + + [Test] + public void RunTest() + { + Container.Bind().FromComponentInChildren(); + Container.Bind().FromComponentInChildren(); + + Initialize(); + + Assert.IsEqual(_root.Grandchild, _grandchild); + Assert.IsEqual(_root.Childs[0], _child1); + Assert.IsEqual(_root.Childs[1], _child2); + } + + public class Root : MonoBehaviour + { + [Inject] + public Grandchild Grandchild; + + [Inject] + public List Childs; + } + + public class Child : MonoBehaviour + { + } + + public class Grandchild : MonoBehaviour + { + } + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInChildren.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInChildren.cs.meta index 80b15774f..3cb113440 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInChildren.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 6e8b0e0081a07c840a51d65ca79d8569 -timeCreated: 1476628483 +guid: 60e4db58b41116646b1675963b1c75a1 +timeCreated: 1485741160 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchy.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchy.cs new file mode 100644 index 000000000..4a9a1ea5c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchy.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using ModestTree; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestFromComponentInHierarchy : ZenjectIntegrationTestFixture + { + Foo _foo; + Bar _bar; + + void InitScene() + { + var root = new GameObject(); + + var child1 = new GameObject(); + child1.transform.SetParent(root.transform); + + var child2 = new GameObject(); + child2.transform.SetParent(root.transform); + + _foo = child2.AddComponent(); + _bar = child2.AddComponent(); + } + + public override void SetUp() + { + InitScene(); + + base.SetUp(); + } + + [Test] + public void RunTest() + { + Container.Bind().FromComponentInHierarchy(); + + Initialize(); + + Assert.IsEqual(_bar.Foo, _foo); + } + + public class Foo : MonoBehaviour + { + } + + public class Bar : MonoBehaviour + { + [Inject] + public Foo Foo; + } + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchy.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchy.cs.meta index 0cb582687..b3861f40e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchy.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 11208da6895a449438447d414a0c20cb -timeCreated: 1485709788 +guid: 33f32e2013960314f841932f66d9b92c +timeCreated: 1485743323 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs new file mode 100644 index 000000000..bf7653af6 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using ModestTree; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings.FromComponentInHierarchyGameObjectContext +{ + [TestFixture] + public class TestFromComponentInHierarchyGameObjectContext : ZenjectIntegrationTestFixture + { + GameObject FooPrefab + { + get + { + return FixtureUtil.GetPrefab("TestFromComponentInHierarchyGameObjectContext/Foo"); + } + } + + void InitScene() + { + new GameObject().AddComponent(); + new GameObject().AddComponent(); + } + + public override void SetUp() + { + InitScene(); + base.SetUp(); + } + + [Test] + public void TestCorrectHierarchy() + { + Container.Bind().FromSubContainerResolve() + .ByPrefab(FooPrefab).AsSingle().NonLazy(); + + Initialize(); + + var foo = Container.Resolve(); + + Assert.IsNotNull(foo.Gorp); + Assert.IsEqual(foo.gameObject.GetComponentsInChildren().Single(), foo.Gorp); + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs.meta index e6652ade9..42ddabf20 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 45212ad17d904b949906641839ce39da -timeCreated: 1485709788 +guid: e4a3a41ae23a4bb44b068790d065e7e4 +timeCreated: 1485743325 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInParents.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInParents.cs new file mode 100644 index 000000000..69df4541f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInParents.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using ModestTree; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestFromComponentInParents : ZenjectIntegrationTestFixture + { + Root _root; + Child _child1; + Child _child2; + Child _child3; + Grandchild _grandchild; + + void InitScene() + { + _root = new GameObject().AddComponent(); + + _child1 = new GameObject().AddComponent(); + _child1.transform.SetParent(_root.transform); + + _child2 = new GameObject().AddComponent(); + _child2.transform.SetParent(_child1.transform); + _child3 = _child2.gameObject.AddComponent(); + + _grandchild = new GameObject().AddComponent(); + _grandchild.transform.SetParent(_child2.transform); + } + + public override void SetUp() + { + InitScene(); + + base.SetUp(); + } + + [Test] + public void RunTest() + { + Container.Bind().FromComponentInParents(); + Container.Bind().FromComponentInParents(); + + Initialize(); + + Assert.IsEqual(_grandchild.Childs[0], _child2); + Assert.IsEqual(_grandchild.Childs[1], _child3); + Assert.IsEqual(_grandchild.Childs[2], _child1); + Assert.IsEqual(_grandchild.Root, _root); + } + + public class Root : MonoBehaviour + { + } + + public class Child : MonoBehaviour + { + } + + public class Grandchild : MonoBehaviour + { + [Inject] + public Root Root; + + [Inject] + public List Childs; + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInParents.cs.meta similarity index 76% rename from UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInParents.cs.meta index 54253ec86..c746357b6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInParents.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 6d1564f71f28ceb4f92fcb102a03689c -timeCreated: 1476628483 +guid: 9df118a8d9c898344bed28c6913a6d7e +timeCreated: 1485741161 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs new file mode 100644 index 000000000..a580dff7e --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using ModestTree; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestFromComponentSibling : ZenjectIntegrationTestFixture + { + Foo _foo; + Bar _bar; + Qux _qux1; + Qux _qux2; + + void InitScene() + { + _foo = new GameObject().AddComponent(); + + _bar = _foo.gameObject.AddComponent(); + _qux1 = _foo.gameObject.AddComponent(); + _qux2 = _foo.gameObject.AddComponent(); + } + + public override void SetUp() + { + InitScene(); + + base.SetUp(); + } + + [Test] + public void RunTest() + { + Container.Bind().FromComponentSibling(); + Container.Bind().FromComponentSibling(); + + Initialize(); + + Assert.IsEqual(_foo.Bar, _bar); + Assert.IsEqual(_foo.Qux[0], _qux1); + Assert.IsEqual(_foo.Qux[1], _qux2); + + // Should skip self + Assert.IsEqual(_foo.Qux[0].OtherQux, _foo.Qux[1]); + Assert.IsEqual(_foo.Qux[1].OtherQux, _foo.Qux[0]); + } + + public class Qux : MonoBehaviour + { + [Inject] + public Qux OtherQux; + } + + public class Bar : MonoBehaviour + { + } + + public class Foo : MonoBehaviour + { + [Inject] + public Bar Bar; + + [Inject] + public List Qux; + } + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs.meta new file mode 100644 index 000000000..995f9e7ee --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b0d37dd020d97b3459f64a7f3434ff96 +timeCreated: 1485741161 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext.meta similarity index 67% rename from UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext.meta index 3d89eda32..a54321faf 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: b471b5dacb7542e428d4b1875132dcb5 +guid: 803685e92a450bb4db649a0a2f48d07f folderAsset: yes -timeCreated: 1476628483 +timeCreated: 1485743427 licenseType: Free DefaultImporter: userData: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext/Foo.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext/Foo.prefab new file mode 100644 index 000000000..8ebdc6eba --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext/Foo.prefab @@ -0,0 +1,125 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &162920 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 406566} + - component: {fileID: 11460120} + - component: {fileID: 114030807952997706} + - component: {fileID: 114675924650911818} + m_Layer: 0 + m_Name: Foo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &406566 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 162920} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 4462927905753138} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11460120 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 162920} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 08eca9f7688a0a24685b89133b020c8e, type: 3} + m_Name: + m_EditorClassIdentifier: + _installers: + - {fileID: 114030807952997706} + _installerPrefabs: [] + _scriptableObjectInstallers: [] + _kernel: {fileID: 0} +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 162920} + m_IsPrefabParent: 1 +--- !u!1 &1681158058118644 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4462927905753138} + - component: {fileID: 114633679146737766} + m_Layer: 0 + m_Name: Gorp + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4462927905753138 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1681158058118644} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 406566} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &114030807952997706 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 162920} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cdb37bf9eda440448d25e272bf9cd32, type: 3} + m_Name: + m_EditorClassIdentifier: + _foo: {fileID: 114675924650911818} +--- !u!114 &114633679146737766 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1681158058118644} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 972b6ec83b1c10046b0f01f4692b1ddc, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &114675924650911818 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 162920} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: aface7ec58475d840a11bf38361406a2, type: 3} + m_Name: + m_EditorClassIdentifier: + Gorp: {fileID: 0} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext/Foo.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext/Foo.prefab.meta new file mode 100644 index 000000000..b2c4cc285 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromComponentInHierarchyGameObjectContext/Foo.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d4c39a49f38070643b06e8ef923e3648 +timeCreated: 1460509291 +licenseType: Pro +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext.meta new file mode 100644 index 000000000..c529b5a96 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 57ec93299bdbd4942b248df9c72a6c6b +folderAsset: yes +timeCreated: 1485743417 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Foo.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Foo.cs new file mode 100644 index 000000000..89a714569 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Foo.cs @@ -0,0 +1,12 @@ +using System; +using UnityEngine; + +namespace Zenject.Tests.Bindings.FromComponentInHierarchyGameObjectContext +{ + public class Foo : MonoBehaviour + { + [NonSerialized] + [Inject] + public Gorp Gorp; + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Foo.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Foo.cs.meta new file mode 100644 index 000000000..7389fa53a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Foo.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: aface7ec58475d840a11bf38361406a2 +timeCreated: 1485743976 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/FooInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/FooInstaller.cs new file mode 100644 index 000000000..90056c61a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/FooInstaller.cs @@ -0,0 +1,20 @@ +using UnityEngine; +using System.Collections; +using Zenject; + +#pragma warning disable 649 + +namespace Zenject.Tests.Bindings.FromComponentInHierarchyGameObjectContext +{ + public class FooInstaller : MonoInstaller + { + [SerializeField] + Foo _foo; + + public override void InstallBindings() + { + Container.Bind().FromInstance(_foo).AsSingle(); + Container.Bind().FromComponentInHierarchy(); + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/FooInstaller.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/FooInstaller.cs.meta new file mode 100644 index 000000000..d4ae7afc8 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/FooInstaller.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0cdb37bf9eda440448d25e272bf9cd32 +timeCreated: 1485743626 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Gorp.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Gorp.cs new file mode 100644 index 000000000..180a240e3 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Gorp.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace Zenject.Tests.Bindings.FromComponentInHierarchyGameObjectContext +{ + public class Gorp : MonoBehaviour + { + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Gorp.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Gorp.cs.meta new file mode 100644 index 000000000..c59989c2c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromComponentInHierarchyGameObjectContext/Gorp.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 972b6ec83b1c10046b0f01f4692b1ddc +timeCreated: 1485743627 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs deleted file mode 100644 index 11ca66cbf..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryOne.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using UnityEngine; -using ModestTree; -using Assert=ModestTree.Assert; -using Zenject.Tests.Factories.GameObjectFactoryOne; - -namespace Zenject.Tests.Factories -{ - [TestFixture] - public class TestGameObjectFactoryOne : ZenjectIntegrationTestFixture - { - GameObject CubePrefab - { - get - { - return FixtureUtil.GetPrefab("TestGameObjectFactoryOne/Cube"); - } - } - - const string GameObjName = "TestObj"; - - [Test] - public void TestPrefabSelfSingle1() - { - Container.BindFactory().FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName); - - AddFactoryUser(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestPrefabConcreteSingle1() - { - Container.BindFactory().To().FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName); - - AddFactoryUser(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestPrefabResourceSelfSingle1() - { - Container.BindFactory().FromComponentInPrefabResource("TestGameObjectFactoryOne/Cube").WithGameObjectName(GameObjName); - - AddFactoryUser(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestPrefabResourceConcreteSingle1() - { - Container.BindFactory().To().FromComponentInPrefabResource("TestGameObjectFactoryOne/Cube").WithGameObjectName(GameObjName); - - AddFactoryUser(); - - Initialize(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - void AddFactoryUser() - where T : IInitializable - { - Container.Bind().To().AsSingle(); - Container.BindExecutionOrder(-100); - } - - public class ObjectFactoryTester : IInitializable - { - readonly ObjectFactory _objectFactory; - - public ObjectFactoryTester(ObjectFactory objectFactory) - { - _objectFactory = objectFactory; - } - - public void Initialize() - { - var gameObject = (GameObject)_objectFactory.Create("asdf"); - - Assert.IsEqual(gameObject.GetComponentInChildren().Value, "asdf"); - - Log.Info("ObjectFactory initialized foo successfully"); - } - } - - public class CubeFactoryTester : IInitializable - { - readonly CubeFactory _cubeFactory; - - public CubeFactoryTester(CubeFactory cubeFactory) - { - _cubeFactory = cubeFactory; - } - - public void Initialize() - { - var gameObject = _cubeFactory.Create("asdf"); - - Assert.IsEqual(gameObject.GetComponentInChildren().Value, "asdf"); - - Log.Info("CubeFactory initialized foo successfully"); - } - } - - public class ObjectFactory : Factory - { - } - - public class CubeFactory : Factory - { - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs deleted file mode 100644 index 950b4db10..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestGameObjectFactoryZero.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using UnityEngine; -using ModestTree; -using Assert=ModestTree.Assert; -namespace Zenject.Tests.Factories -{ - [TestFixture] - public class TestGameObjectFactoryZero : ZenjectIntegrationTestFixture - { - const string ResourcePrefix = "TestGameObjectFactoryZero"; - - GameObject CubePrefab - { - get - { - return FixtureUtil.GetPrefab(ResourcePrefix + "/Cube"); - } - } - - const string GameObjName = "TestObj"; - - [Test] - public void TestGameObjectSelf1() - { - Container.BindFactory().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName); - - Initialize(); - - Container.Resolve().Create(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestGameObjectConcreteSingle() - { - Container.BindFactory().To().FromNewComponentOnNewGameObject().WithGameObjectName(GameObjName); - - Initialize(); - - Container.Resolve().Create(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestPrefabSelfSingle1() - { - Container.BindFactory().FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName); - - Initialize(); - - Container.Resolve().Create(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestPrefabConcreteSingle1() - { - Container.BindFactory().To().FromComponentInPrefab(CubePrefab).WithGameObjectName(GameObjName); - - Initialize(); - - Container.Resolve().Create(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestPrefabResourceSelfSingle1() - { - Container.BindFactory() - .FromComponentInPrefabResource(ResourcePrefix + "/Cube").WithGameObjectName(GameObjName); - - Initialize(); - - Container.Resolve().Create(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - [Test] - public void TestPrefabResourceConcreteSingle1() - { - Container.BindFactory() - .To().FromComponentInPrefabResource(ResourcePrefix + "/Cube").WithGameObjectName(GameObjName); - - Initialize(); - - Container.Resolve().Create(); - - FixtureUtil.AssertNumGameObjects(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, GameObjName, 1); - } - - public class ObjectFactory : Factory - { - } - - public class CubeFactory : Factory - { - } - } -} - diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne/Foo.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne/Foo.cs deleted file mode 100644 index 36009ff6c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne/Foo.cs +++ /dev/null @@ -1,20 +0,0 @@ -using UnityEngine; -using Zenject; - -namespace Zenject.Tests.Factories.GameObjectFactoryOne -{ - public class Foo : MonoBehaviour - { - [Inject] - public void Init(string value) - { - Value = value; - } - - public string Value - { - get; - private set; - } - } -} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne/Foo.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne/Foo.cs.meta deleted file mode 100644 index 5e06909e5..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestGameObjectFactoryOne/Foo.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5424aef515984fd4da14e474c7ab463c -timeCreated: 1459214388 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs similarity index 99% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs index 573386d15..f842e05db 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestTo : ZenjectUnitTestFixture + public class TestFrom : ZenjectUnitTestFixture { [Test] public void TestSelfSingle() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs.meta new file mode 100644 index 000000000..f6892b772 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6a67145dedecd9947bb94c542f6474ae +timeCreated: 1485738783 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromFactory.cs similarity index 98% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromFactory.cs index 57493f81d..c95c5a6ec 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromFactory.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestToFactory : ZenjectUnitTestFixture + public class TestFromFactory : ZenjectUnitTestFixture { static Foo StaticFoo = new Foo(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromFactory.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromFactory.cs.meta new file mode 100644 index 000000000..d61193790 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d88c26093930ebe4c9c294ae22d12754 +timeCreated: 1485738788 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromGetter.cs similarity index 97% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromGetter.cs index a8b16065e..e2d9589b0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromGetter.cs @@ -8,7 +8,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestToGetter : ZenjectUnitTestFixture + public class TestFromGetter : ZenjectUnitTestFixture { [Test] public void TestTransient() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromGetter.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromGetter.cs.meta new file mode 100644 index 000000000..3647b1df1 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromGetter.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1d62dc62d45050143ae156ca7f735abf +timeCreated: 1485738782 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromInstance.cs similarity index 96% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromInstance.cs index bd2e0ae80..9d0fda3b1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromInstance.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestToInstance : ZenjectUnitTestFixture + public class TestFromInstance : ZenjectUnitTestFixture { [Test] public void TestTransient() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromInstance.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromInstance.cs.meta new file mode 100644 index 000000000..7dd58f4ca --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromInstance.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7bf907a08d456614db4e71411381f66a +timeCreated: 1485738784 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethod.cs similarity index 98% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethod.cs index ff3d4b6c9..fb7c2233b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethod.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestToMethod : ZenjectUnitTestFixture + public class TestFromMethod : ZenjectUnitTestFixture { [Test] public void TestSingle() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethod.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethod.cs.meta new file mode 100644 index 000000000..22967eabc --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethod.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2f937d712d2be4042b394985b5b8f441 +timeCreated: 1485738782 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethodMultiple.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethodMultiple.cs new file mode 100644 index 000000000..41fa83499 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethodMultiple.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using Zenject; +using NUnit.Framework; +using System.Linq; +using ModestTree; +using Assert=ModestTree.Assert; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestFromMethodMultiple : ZenjectUnitTestFixture + { + [Test] + public void TestSingle() + { + var foo = new Foo(); + + Container.Bind().FromMethodMultiple((ctx) => new[] { foo }).AsSingle().NonLazy(); + + Assert.IsEqual(Container.Resolve(), foo); + } + + [Test] + public void TestSingle5() + { + // This is weird but consistent with how AsSingle is interpreted for other From types + // like FromSubcontainerResolve, FromComponentInPrefab, etc. + // The 'single' is really refering to the fact that it's a single resolve handler, not a + // single instance + Container.Bind().FromMethodMultiple((ctx) => new[] { new Foo(), new Foo() }).AsSingle().NonLazy(); + + Assert.IsEqual(Container.ResolveAll().Count, 2); + } + + [Test] + public void TestMisc() + { + var foo1 = new Foo(); + var foo2 = new Foo(); + + Container.Bind().FromMethodMultiple((ctx) => new[] { foo1, foo2 }); + + var foos = Container.ResolveAll(); + Assert.IsEqual(foos[0], foo1); + Assert.IsEqual(foos[1], foo2); + } + + [Test] + public void TestMisc2() + { + var foo1 = new Foo(); + var foo2 = new Foo(); + var foo3 = new Foo(); + var foo4 = new Foo(); + + Container.Bind().FromMethodMultiple((ctx) => new[] { foo1, foo2 }); + Container.Bind().FromMethodMultiple((ctx) => new[] { foo3, foo4 }); + + var foos = Container.ResolveAll(); + + Assert.IsEqual(foos[0], foo1); + Assert.IsEqual(foos[1], foo2); + Assert.IsEqual(foos[2], foo3); + Assert.IsEqual(foos[3], foo4); + } + + [Test] + public void TestTransient() + { + var foo = new Foo(); + + Container.Bind().FromMethodMultiple((ctx) => new[] { foo }).AsTransient().NonLazy(); + + Assert.IsEqual(Container.Resolve(), foo); + } + + [Test] + public void TestCached() + { + var foo = new Foo(); + + Container.Bind().FromMethodMultiple((ctx) => new[] { foo }).AsCached().NonLazy(); + + Assert.IsEqual(Container.Resolve(), foo); + } + + [Test] + [ExpectedException] + public void TestSingleConflict() + { + Container.Bind().FromMethodMultiple((ctx) => new[] { new Foo() }).AsSingle().NonLazy(); + Container.Bind().AsSingle().NonLazy(); + + Container.ResolveAll(); + } + + [Test] + public void TestSingle2() + { + var foo = new Foo(); + Func> method = (ctx) => new[] { foo }; + + Container.Bind().FromMethodMultiple(method).AsSingle().NonLazy(); + Container.Bind().To().FromMethodMultiple(method).AsSingle().NonLazy(); + + Assert.IsEqual(Container.Resolve(), Container.Resolve()); + Assert.IsEqual(Container.Resolve(), Container.Resolve()); + Assert.IsEqual(Container.Resolve(), foo); + } + + [Test] + public void TestSingle3() + { + Container.Bind().FromMethodMultiple(CreateFoos).AsSingle().NonLazy(); + Container.Bind().To().FromMethodMultiple(CreateFoos).AsSingle().NonLazy(); + + Assert.IsEqual(Container.Resolve(), Container.Resolve()); + Assert.IsEqual(Container.Resolve(), Container.Resolve()); + } + + IEnumerable CreateFoos(InjectContext ctx) + { + yield return new Foo(); + } + + [Test] + public void TestSingle4() + { + int numCalls = 0; + + Func> method = (ctx) => + { + numCalls++; + return new[] { new Foo() }; + }; + + Container.Bind().FromMethodMultiple(method).AsSingle().NonLazy(); + Container.Bind().To().FromMethodMultiple(method).AsSingle().NonLazy(); + + Container.Resolve(); + Container.Resolve(); + Container.Resolve(); + Container.Resolve(); + + Assert.IsEqual(numCalls, 1); + } + + [Test] + public void TestTransient2() + { + int numCalls = 0; + + Func> method = (ctx) => + { + numCalls++; + return new[] { new Foo() }; + }; + + Container.Bind().FromMethodMultiple(method).AsTransient().NonLazy(); + Container.Bind().To().FromMethodMultiple(method).AsTransient().NonLazy(); + + Container.Resolve(); + Container.Resolve(); + Container.Resolve(); + Container.Resolve(); + + Assert.IsEqual(numCalls, 4); + } + + [Test] + public void TestCached2() + { + Container.Bind(typeof(Foo), typeof(IFoo)).To().FromMethodMultiple((ctx) => new[] { new Foo() }).AsCached().NonLazy(); + + Assert.IsEqual(Container.Resolve(), Container.Resolve()); + Assert.IsEqual(Container.Resolve(), Container.Resolve()); + } + + interface IFoo + { + } + + class Foo : IFoo + { + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethodMultiple.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethodMultiple.cs.meta new file mode 100644 index 000000000..098735287 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromMethodMultiple.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fadc8263bac9f4941b06a03c82251f36 +timeCreated: 1485738789 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs similarity index 98% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs index 09879ac27..1819e105c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestToResolve : ZenjectUnitTestFixture + public class TestFromResolve : ZenjectUnitTestFixture { [Test] public void TestTransient() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs.meta new file mode 100644 index 000000000..49a60985c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0b37e8adbb14af84ba212744b2bd2804 +timeCreated: 1485738781 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs similarity index 97% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs index bab6ae033..ae05a8aac 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestToSubContainerInstaller : ZenjectUnitTestFixture + public class TestFromSubContainerInstaller : ZenjectUnitTestFixture { [Test] public void TestInstallerSelfSingle() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs.meta new file mode 100644 index 000000000..8ee8a9a2b --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0d941aa49ba79854487ffabb59b0a24f +timeCreated: 1485738781 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs similarity index 98% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs index 1a5910761..870bb9a8d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestToSubContainerMethod : ZenjectUnitTestFixture + public class TestFromSubContainerMethod : ZenjectUnitTestFixture { [Test] public void TestMethodSelfSingle() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs.meta new file mode 100644 index 000000000..b5c0f38fa --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0aca0ea3c3e68134886983eb884c26c0 +timeCreated: 1485738781 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs.meta deleted file mode 100644 index dd748f9f6..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestTo.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: fa7c4328a0ee6b34dac3a8780ff6a2a3 -timeCreated: 1461708055 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs.meta deleted file mode 100644 index 6985b5167..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToFactory.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 046da8ddecb5a2b429b00c2938caa154 -timeCreated: 1461708048 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs.meta deleted file mode 100644 index 223c1e2b5..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToGetter.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: b4b2b38a382831d4496374435a08c8a9 -timeCreated: 1461708053 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs.meta deleted file mode 100644 index a556b3b98..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToInstance.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: db79b26aa813ccb4eb40daabcd1e150c -timeCreated: 1461708054 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs.meta deleted file mode 100644 index 5399ed6c8..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToMethod.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f167cd2b40f26f149a22801049acf47b -timeCreated: 1461708055 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs.meta deleted file mode 100644 index 28b1e13ea..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToResolve.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a4809971b2b832144a7e4bbec2489570 -timeCreated: 1461708052 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs.meta deleted file mode 100644 index 463e7620c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerInstaller.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3acc1d72684583c46831f1d2f2310f3a -timeCreated: 1461708049 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs.meta deleted file mode 100644 index ae79d2439..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestToSubContainerMethod.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5ceae894bbde56243b72c8e8243f1f04 -timeCreated: 1461708050 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom0.cs similarity index 95% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom0.cs index 9fa850794..087fe1de3 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom0.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryTo0 : ZenjectUnitTestFixture + public class TestFactoryFrom0 : ZenjectUnitTestFixture { [Test] public void TestSelf1() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom0.cs.meta new file mode 100644 index 000000000..cce699553 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cd589059f4c2ff341a25698a4a1673d9 +timeCreated: 1485738788 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom1.cs similarity index 95% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom1.cs index 972927e42..b463312d8 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom1.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryTo1 : ZenjectUnitTestFixture + public class TestFactoryFrom1 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom1.cs.meta new file mode 100644 index 000000000..2e9e45f08 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2aeb922683e72ac4f9fd3806715e65df +timeCreated: 1485738782 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom5.cs similarity index 96% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom5.cs index efbe4acd6..85c5e797d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom5.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryTo5 : ZenjectUnitTestFixture + public class TestFactoryFrom5 : ZenjectUnitTestFixture { [Test] public void TestSelf1() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom5.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom5.cs.meta new file mode 100644 index 000000000..0527d8a58 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFrom5.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: db247dfbb1d6d284cae35a8f3ae55f17 +timeCreated: 1485738788 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory0.cs similarity index 96% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory0.cs index 8e484502e..b859787cc 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory0.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToFactory0 : ZenjectUnitTestFixture + public class TestFactoryFromFactory0 : ZenjectUnitTestFixture { static Foo StaticFoo = new Foo(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory0.cs.meta new file mode 100644 index 000000000..2b2e8047a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1ccf6a6010280bd4c80cd60ddfc3251c +timeCreated: 1485738782 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory1.cs similarity index 95% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory1.cs index be3ea9295..6bdfcf607 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory1.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToFactory1 : ZenjectUnitTestFixture + public class TestFactoryFromFactory1 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory1.cs.meta new file mode 100644 index 000000000..f7b5b7469 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromFactory1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ba619dabc8cdb2a4b853e8d7d88b9a23 +timeCreated: 1485738787 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromGetter0.cs similarity index 93% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromGetter0.cs index dbddbb551..fa1348ff0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromGetter0.cs @@ -8,7 +8,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToGetter0 : ZenjectUnitTestFixture + public class TestFactoryFromGetter0 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromGetter0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromGetter0.cs.meta new file mode 100644 index 000000000..04039dd53 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromGetter0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 02801e9ad7fdcd54990732b0e9ec2d0f +timeCreated: 1485738780 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromInstance0.cs similarity index 93% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromInstance0.cs index 7cc9c0d42..5b52ba2b1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromInstance0.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToInstance0 : ZenjectUnitTestFixture + public class TestFactoryFromInstance0 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromInstance0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromInstance0.cs.meta new file mode 100644 index 000000000..bbbfa0a68 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromInstance0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a07aa9c58bcc5094f8e29f0d10303fb8 +timeCreated: 1485738786 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod0.cs similarity index 93% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod0.cs index 11af6dbc2..ab01d5ee1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod0.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToMethod0 : ZenjectUnitTestFixture + public class TestFactoryFromMethod0 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod0.cs.meta new file mode 100644 index 000000000..3a777712f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8cac25659efcbbb47ab2876811408f52 +timeCreated: 1485738785 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod1.cs similarity index 95% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod1.cs index 2b0e0555a..ea2df95e7 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod1.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToMethod1 : ZenjectUnitTestFixture + public class TestFactoryFromMethod1 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod1.cs.meta new file mode 100644 index 000000000..15bebaac5 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromMethod1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 75b2bb6fc90254044b1eae12b63cafb3 +timeCreated: 1485738784 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromResolve0.cs similarity index 96% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromResolve0.cs index 765f7235f..123b250c8 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromResolve0.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToResolve0 : ZenjectUnitTestFixture + public class TestFactoryFromResolve0 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromResolve0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromResolve0.cs.meta new file mode 100644 index 000000000..2ffcaaf68 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromResolve0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bde11a0eb028e1a4d9f8cd47b9752dad +timeCreated: 1485738787 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller0.cs similarity index 94% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller0.cs index 03dc5ce5e..59db8b9d5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller0.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToSubContainerInstaller0 : ZenjectUnitTestFixture + public class TestFactoryFromSubContainerInstaller0 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller0.cs.meta new file mode 100644 index 000000000..f4b7e1df6 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a75a7d0a0d0a978459537926595a8f75 +timeCreated: 1485738786 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs similarity index 95% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs index 6d41dfef0..0ce9f7eca 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToSubContainerInstaller1 : ZenjectUnitTestFixture + public class TestFactoryFromSubContainerInstaller1 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs.meta new file mode 100644 index 000000000..d4edefc09 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0f5f5adb036584147968b4cf0e1b75a6 +timeCreated: 1485738781 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod0.cs similarity index 93% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod0.cs index fd1888400..a42e4c98d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod0.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToSubContainerMethod0 : ZenjectUnitTestFixture + public class TestFactoryFromSubContainerMethod0 : ZenjectUnitTestFixture { static Foo ConstFoo = new Foo(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod0.cs.meta new file mode 100644 index 000000000..0942f41bb --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 99958e9b2f0eefc429b100aafef684ae +timeCreated: 1485738785 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod1.cs similarity index 95% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod1.cs index 65c2f144a..1d2c5eb24 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod1.cs @@ -9,7 +9,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestFactoryToSubContainerMethod1 : ZenjectUnitTestFixture + public class TestFactoryFromSubContainerMethod1 : ZenjectUnitTestFixture { [Test] public void TestSelf() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod1.cs.meta new file mode 100644 index 000000000..f04f88e27 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerMethod1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 326764b6ac92ebd4daa3532846e523c9 +timeCreated: 1485738782 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs.meta deleted file mode 100644 index 7235675cb..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo0.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4d367f8a829b7a240a65fd80790ae603 -timeCreated: 1461708050 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs.meta deleted file mode 100644 index e1afe33f3..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo1.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 1b609a49c31524b449d1ed56179187f2 -timeCreated: 1461708048 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs.meta deleted file mode 100644 index 8fcc17bd6..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryTo5.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: d5322cdad8b3b0347b6c18df8569d916 -timeCreated: 1461708053 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs.meta deleted file mode 100644 index c58229646..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory0.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 71a3fffafc1b29349bcf839169cfb8b9 -timeCreated: 1461708051 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs.meta deleted file mode 100644 index fe186ebb0..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToFactory1.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a3d3ddbaf6c2737418eb7db4516baac5 -timeCreated: 1461708052 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs.meta deleted file mode 100644 index 4a0c50b20..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToGetter0.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 06adea240ab32a24db541cd3b569520a -timeCreated: 1461708048 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs.meta deleted file mode 100644 index e7f81977f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToInstance0.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: d81a5eca2e3e2cc4cae16c5fd6d4aa19 -timeCreated: 1461708054 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs.meta deleted file mode 100644 index 0c91d98b7..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod0.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 09d8d59ae59a66b4f823437d596d4df6 -timeCreated: 1461708048 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs.meta deleted file mode 100644 index 195a651d7..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToMethod1.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: c63648c67d14e4a4da43366aedb27b03 -timeCreated: 1461708053 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs.meta deleted file mode 100644 index 9b72a031c..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToResolve0.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 81b95224b89f39f4eb892abf79e15b3d -timeCreated: 1461708051 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs.meta deleted file mode 100644 index fbd2db38f..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller0.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: b8393f1414ca88c4c86a71a69490b839 -timeCreated: 1461708053 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs.meta deleted file mode 100644 index 3e4c8af6e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerInstaller1.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a513331f402e14c489035e3283c56e29 -timeCreated: 1461708052 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs.meta deleted file mode 100644 index b49917d7e..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod0.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a6d0b0c17a567eb41b35a0c9932776a6 -timeCreated: 1461708052 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs.meta deleted file mode 100644 index b0132cc47..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryToSubContainerMethod1.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 6dfdf5e156b709f4f9921b34aebfe695 -timeCreated: 1461708051 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool0.cs similarity index 98% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool0.cs index f9eb3afc5..a0b16e8ff 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo0.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool0.cs @@ -7,7 +7,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestMemoryPoolTo0 : ZenjectUnitTestFixture + public class TestMemoryPool0 : ZenjectUnitTestFixture { [Test] public void TestFactoryProperties() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool0.cs.meta new file mode 100644 index 000000000..d89fba9d0 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b37d028125ab96948b4da9012b9cd854 +timeCreated: 1485738787 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs similarity index 84% rename from UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs rename to UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs index 043440cc2..b98ede78f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPoolTo1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs @@ -7,7 +7,7 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestMemoryPoolTo1 : ZenjectUnitTestFixture + public class TestMemoryPool1 : ZenjectUnitTestFixture { [Test] public void TestFactoryProperties() @@ -105,6 +105,30 @@ protected override void Reinitialize(Foo foo, string value) } } } + + [Test] + public void TestAbstractMemoryPool() + { + Container.BindMemoryPool().To(); + + var pool = Container.Resolve(); + + var foo = pool.Spawn(5); + + Assert.IsEqual(foo.GetType(), typeof(Bar)); + } + + public interface IBar + { + } + + public class Bar : IBar + { + } + + public class BarPool : MemoryPool + { + } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs.meta new file mode 100644 index 000000000..36f5c44a0 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cbd440f1cea0e48489d651ea920baed1 +timeCreated: 1485738787 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs.meta index 7305d187e..6b72e89b0 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/MemoryPoolBindInfo.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: b7c8d1b2e9765964289bb6bcd23b9d2f -timeCreated: 1485709789 +guid: 3f8798fbf64bca945a7be04615c08c4f +timeCreated: 1485711462 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderGeneric.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderGeneric.cs index 12176e365..2168c64db 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderGeneric.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderGeneric.cs @@ -21,7 +21,7 @@ public FromBinderGeneric ToSelf() Assert.IsEqual(BindInfo.ToChoice, ToChoices.Self); SubFinalizer = new ScopableBindingFinalizer( - BindInfo, SingletonTypes.To, null, + BindInfo, SingletonTypes.FromNew, null, (container, type) => new TransientProvider( type, container, BindInfo.Arguments, BindInfo.ConcreteIdentifier, BindInfo.ContextInfo)); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderNonGeneric.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderNonGeneric.cs index 15bf64c35..d9cd67aac 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderNonGeneric.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderNonGeneric.cs @@ -21,7 +21,7 @@ public FromBinderNonGeneric ToSelf() Assert.IsEqual(BindInfo.ToChoice, ToChoices.Self); SubFinalizer = new ScopableBindingFinalizer( - BindInfo, SingletonTypes.To, null, + BindInfo, SingletonTypes.FromNew, null, (container, type) => new TransientProvider( type, container, BindInfo.Arguments, BindInfo.ConcreteIdentifier, BindInfo.ContextInfo)); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs index b4dce4eaf..f3e54aed6 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs @@ -76,24 +76,15 @@ public ConditionCopyNonLazyBinder FromResolve(object subIdentifier) public NameTransformConditionCopyNonLazyBinder FromNewComponentOnNewGameObject() { - var gameObjectInfo = new GameObjectCreationParameters(); + BindingUtil.AssertIsComponent(ContractType); + BindingUtil.AssertIsNotAbstract(ContractType); - if (ContractType == typeof(GameObject)) - { - ProviderFunc = - (container) => new EmptyGameObjectProvider( - container, gameObjectInfo); - } - else - { - BindingUtil.AssertIsComponent(ContractType); - BindingUtil.AssertIsNotAbstract(ContractType); + var gameObjectInfo = new GameObjectCreationParameters(); - ProviderFunc = - (container) => new AddToNewGameObjectComponentProvider( - container, ContractType, null, - new List(), gameObjectInfo); - } + ProviderFunc = + (container) => new AddToNewGameObjectComponentProvider( + container, ContractType, null, + new List(), gameObjectInfo); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } @@ -115,28 +106,16 @@ public ConditionCopyNonLazyBinder FromNewComponentOn(GameObject gameObject) public NameTransformConditionCopyNonLazyBinder FromComponentInPrefab(UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); + BindingUtil.AssertIsInterfaceOrComponent(ContractType); var gameObjectInfo = new GameObjectCreationParameters(); - if (ContractType == typeof(GameObject)) - { - ProviderFunc = - (container) => new PrefabGameObjectProvider( - new PrefabInstantiator( - container, gameObjectInfo, - new List(), new PrefabProvider(prefab))); - } - else - { - BindingUtil.AssertIsAbstractOrComponent(ContractType); - - ProviderFunc = - (container) => new GetFromPrefabComponentProvider( - ContractType, - new PrefabInstantiator( - container, gameObjectInfo, - new List(), new PrefabProvider(prefab))); - } + ProviderFunc = + (container) => new GetFromPrefabComponentProvider( + ContractType, + new PrefabInstantiator( + container, gameObjectInfo, + new List(), new PrefabProvider(prefab))); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } @@ -144,28 +123,16 @@ public NameTransformConditionCopyNonLazyBinder FromComponentInPrefab(UnityEngine public NameTransformConditionCopyNonLazyBinder FromComponentInPrefabResource(string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); + BindingUtil.AssertIsInterfaceOrComponent(ContractType); var gameObjectInfo = new GameObjectCreationParameters(); - if (ContractType == typeof(GameObject)) - { - ProviderFunc = - (container) => new PrefabGameObjectProvider( - new PrefabInstantiator( - container, gameObjectInfo, - new List(), new PrefabProviderResource(resourcePath))); - } - else - { - BindingUtil.AssertIsAbstractOrComponent(ContractType); - - ProviderFunc = - (container) => new GetFromPrefabComponentProvider( - ContractType, - new PrefabInstantiator( - container, gameObjectInfo, - new List(), new PrefabProviderResource(resourcePath))); - } + ProviderFunc = + (container) => new GetFromPrefabComponentProvider( + ContractType, + new PrefabInstantiator( + container, gameObjectInfo, + new List(), new PrefabProviderResource(resourcePath))); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index e4435d692..60b619783 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -69,7 +69,7 @@ public ScopeConditionCopyNonLazyBinder FromResolve(object subIdentifier) { SubFinalizer = new ScopableBindingFinalizer( BindInfo, - SingletonTypes.ToResolve, subIdentifier, + SingletonTypes.FromResolve, subIdentifier, (container, type) => new ResolveProvider(type, container, subIdentifier, false)); return new ScopeConditionCopyNonLazyBinder(BindInfo); @@ -92,7 +92,7 @@ public ScopeArgConditionCopyNonLazyBinder FromFactory(Type factoryType) SubFinalizer = new ScopableBindingFinalizer( BindInfo, - SingletonTypes.ToFactory, factoryType, + SingletonTypes.FromFactory, factoryType, (container, type) => new UntypedFactoryProvider( factoryType, container, BindInfo.Arguments)); @@ -108,7 +108,7 @@ public ScopeArgConditionCopyNonLazyBinder FromNewComponentOn(GameObject gameObje BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); SubFinalizer = new ScopableBindingFinalizer( - BindInfo, SingletonTypes.ToComponentGameObject, gameObject, + BindInfo, SingletonTypes.FromComponentGameObject, gameObject, (container, type) => new AddToExistingGameObjectComponentProvider( gameObject, container, type, BindInfo.ConcreteIdentifier, BindInfo.Arguments)); @@ -135,34 +135,17 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromNewComponentOnNewGame public NameTransformScopeArgConditionCopyNonLazyBinder FromNewComponentOnNewGameObject( GameObjectCreationParameters gameObjectInfo) { - BindingUtil.AssertIsAbstractOrComponentOrGameObject(BindInfo.ContractTypes); - BindingUtil.AssertIsComponentOrGameObject(ConcreteTypes); + BindingUtil.AssertIsComponent(ConcreteTypes); + BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); - if (ConcreteTypes.All(x => x == typeof(GameObject))) - { - SubFinalizer = new ScopableBindingFinalizer( - BindInfo, SingletonTypes.ToGameObject, gameObjectInfo, - (container, type) => - { - Assert.That(BindInfo.Arguments.IsEmpty(), "Cannot inject arguments into empty game object"); - return new EmptyGameObjectProvider( - container, gameObjectInfo); - }); - } - else - { - BindingUtil.AssertIsComponent(ConcreteTypes); - BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); - - SubFinalizer = new ScopableBindingFinalizer( - BindInfo, SingletonTypes.ToGameObject, gameObjectInfo, - (container, type) => new AddToNewGameObjectComponentProvider( - container, - type, - BindInfo.ConcreteIdentifier, - BindInfo.Arguments, - gameObjectInfo)); - } + SubFinalizer = new ScopableBindingFinalizer( + BindInfo, SingletonTypes.FromGameObject, gameObjectInfo, + (container, type) => new AddToNewGameObjectComponentProvider( + container, + type, + BindInfo.ConcreteIdentifier, + BindInfo.Arguments, + gameObjectInfo)); return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } @@ -177,7 +160,7 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefab( UnityEngine.Object prefab, GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsValidPrefab(prefab); - BindingUtil.AssertIsAbstractOrComponentOrGameObject(AllParentTypes); + BindingUtil.AssertIsInterfaceOrComponent(AllParentTypes); SubFinalizer = new PrefabBindingFinalizer( BindInfo, gameObjectInfo, prefab); @@ -194,7 +177,7 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefabReso string resourcePath, GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsValidResourcePath(resourcePath); - BindingUtil.AssertIsAbstractOrComponentOrGameObject(AllParentTypes); + BindingUtil.AssertIsInterfaceOrComponent(AllParentTypes); SubFinalizer = new PrefabResourceBindingFinalizer( BindInfo, gameObjectInfo, resourcePath); @@ -208,7 +191,7 @@ public ScopeConditionCopyNonLazyBinder FromResource(string resourcePath) SubFinalizer = new ScopableBindingFinalizer( BindInfo, - SingletonTypes.ToResource, + SingletonTypes.FromResource, resourcePath.ToLower(), (_, type) => new ResourceProvider(resourcePath, type)); @@ -221,7 +204,7 @@ public ScopeArgConditionCopyNonLazyBinder FromMethodUntyped(Func new MethodProviderUntyped(method, container)); return this; @@ -233,12 +216,24 @@ protected ScopeArgConditionCopyNonLazyBinder FromMethodBase(Func new MethodProvider(method, container)); return this; } + protected ScopeArgConditionCopyNonLazyBinder FromMethodMultipleBase(Func> method) + { + BindingUtil.AssertIsDerivedFromTypes(typeof(TConcrete), AllParentTypes); + + SubFinalizer = new ScopableBindingFinalizer( + BindInfo, + SingletonTypes.FromMethod, new SingletonImplIds.ToMethod(method), + (container, type) => new MethodProviderMultiple(method, container)); + + return this; + } + protected ScopeArgConditionCopyNonLazyBinder FromFactoryBase() where TFactory : IFactory { @@ -246,7 +241,7 @@ protected ScopeArgConditionCopyNonLazyBinder FromFactoryBase new FactoryProvider(container, BindInfo.Arguments)); return new ScopeArgConditionCopyNonLazyBinder(BindInfo); @@ -259,7 +254,7 @@ protected ScopeConditionCopyNonLazyBinder FromResolveGetterBase( SubFinalizer = new ScopableBindingFinalizer( BindInfo, - SingletonTypes.ToGetter, + SingletonTypes.FromGetter, new SingletonImplIds.ToGetter(identifier, method), (container, type) => new GetterProvider(identifier, method, container)); @@ -278,7 +273,7 @@ protected ScopeConditionCopyNonLazyBinder FromInstanceBase(object instance, bool BindingUtil.AssertInstanceDerivesFromOrEqual(instance, AllParentTypes); SubFinalizer = new ScopableBindingFinalizer( - BindInfo, SingletonTypes.ToInstance, instance, + BindInfo, SingletonTypes.FromInstance, instance, (container, type) => new InstanceProvider(container, type, instance)); return new ScopeConditionCopyNonLazyBinder(BindInfo); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs index 035bf5713..af9576807 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderGeneric.cs @@ -1,4 +1,11 @@ using System; +using System.Collections.Generic; +using ModestTree; +using System.Linq; + +#if !NOT_UNITY3D +using UnityEngine; +#endif namespace Zenject { @@ -30,6 +37,11 @@ public ScopeArgConditionCopyNonLazyBinder FromMethod(Func(method); } + public ScopeArgConditionCopyNonLazyBinder FromMethodMultiple(Func> method) + { + return FromMethodMultipleBase(method); + } + public ScopeConditionCopyNonLazyBinder FromResolveGetter(Func method) { return FromResolveGetter(null, method); @@ -49,5 +61,62 @@ public ScopeConditionCopyNonLazyBinder FromInstance(TContract instance, bool all { return FromInstanceBase(instance, allowNull); } + +#if !NOT_UNITY3D + + public ScopeArgConditionCopyNonLazyBinder FromComponentInChildren() + { + BindingUtil.AssertIsInterfaceOrComponent(AllParentTypes); + + return FromMethodMultiple((ctx) => + { + Assert.That(ctx.ObjectType.DerivesFromOrEqual()); + Assert.IsNotNull(ctx.ObjectInstance); + + return ((MonoBehaviour)ctx.ObjectInstance).GetComponentsInChildren() + .Where(x => !ReferenceEquals(x, ctx.ObjectInstance)); + }); + } + + public ScopeArgConditionCopyNonLazyBinder FromComponentInParents() + { + BindingUtil.AssertIsInterfaceOrComponent(AllParentTypes); + + return FromMethodMultiple((ctx) => + { + Assert.That(ctx.ObjectType.DerivesFromOrEqual()); + Assert.IsNotNull(ctx.ObjectInstance); + + return ((MonoBehaviour)ctx.ObjectInstance).GetComponentsInParent() + .Where(x => !ReferenceEquals(x, ctx.ObjectInstance)); + }); + } + + public ScopeArgConditionCopyNonLazyBinder FromComponentSibling() + { + BindingUtil.AssertIsInterfaceOrComponent(AllParentTypes); + + return FromMethodMultiple((ctx) => + { + Assert.That(ctx.ObjectType.DerivesFromOrEqual()); + Assert.IsNotNull(ctx.ObjectInstance); + + return ((MonoBehaviour)ctx.ObjectInstance).GetComponents() + .Where(x => !ReferenceEquals(x, ctx.ObjectInstance)); + }); + } + + public ScopeArgConditionCopyNonLazyBinder FromComponentInHierarchy() + { + BindingUtil.AssertIsInterfaceOrComponent(AllParentTypes); + + return FromMethodMultiple((ctx) => + { + return ctx.Container.Resolve().GetRootGameObjects() + .SelectMany(x => x.GetComponentsInChildren()) + .Where(x => !ReferenceEquals(x, ctx.ObjectInstance)); + }); + } +#endif } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderNonGeneric.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderNonGeneric.cs index 65b531c95..a5de6a144 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderNonGeneric.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinderNonGeneric.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Zenject { @@ -22,6 +23,11 @@ public ScopeArgConditionCopyNonLazyBinder FromMethod(Func(method); } + public ScopeArgConditionCopyNonLazyBinder FromMethodMultiple(Func> method) + { + return FromMethodMultipleBase(method); + } + public ScopeConditionCopyNonLazyBinder FromResolveGetter(Func method) { return FromResolveGetter(null, method); diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs b/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs index 2c62ba75d..da50a37d2 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs @@ -94,44 +94,25 @@ public static void AssertIsValidResourcePath(string resourcePath) // a way to do this besides loading it } - public static void AssertIsAbstractOrComponent(IEnumerable types) + public static void AssertIsInterfaceOrComponent(IEnumerable types) { foreach (var type in types) { - AssertIsAbstractOrComponent(type); + AssertIsInterfaceOrComponent(type); } } - public static void AssertIsAbstractOrComponent() + public static void AssertIsInterfaceOrComponent() { - AssertIsAbstractOrComponent(typeof(T)); + AssertIsInterfaceOrComponent(typeof(T)); } - public static void AssertIsAbstractOrComponent(Type type) + public static void AssertIsInterfaceOrComponent(Type type) { Assert.That(type.DerivesFrom(typeof(Component)) || type.IsInterface(), "Invalid type given during bind command. Expected type '{0}' to either derive from UnityEngine.Component or be an interface", type); } - public static void AssertIsAbstractOrComponentOrGameObject(IEnumerable types) - { - foreach (var type in types) - { - AssertIsAbstractOrComponentOrGameObject(type); - } - } - - public static void AssertIsAbstractOrComponentOrGameObject() - { - AssertIsAbstractOrComponentOrGameObject(typeof(T)); - } - - public static void AssertIsAbstractOrComponentOrGameObject(Type type) - { - Assert.That(type.DerivesFrom(typeof(Component)) || type.IsInterface() || type == typeof(GameObject) || type == typeof(UnityEngine.Object), - "Invalid type given during bind command. Expected type '{0}' to either derive from UnityEngine.Component or be an interface or be GameObject", type); - } - public static void AssertIsComponent(IEnumerable types) { foreach (var type in types) @@ -150,25 +131,6 @@ public static void AssertIsComponent(Type type) Assert.That(type.DerivesFrom(typeof(Component)), "Invalid type given during bind command. Expected type '{0}' to derive from UnityEngine.Component", type); } - - public static void AssertIsComponentOrGameObject(IEnumerable types) - { - foreach (var type in types) - { - AssertIsComponentOrGameObject(type); - } - } - - public static void AssertIsComponentOrGameObject() - { - AssertIsComponentOrGameObject(typeof(T)); - } - - public static void AssertIsComponentOrGameObject(Type type) - { - Assert.That(type.DerivesFrom(typeof(Component)) || type == typeof(GameObject), - "Invalid type given during bind command. Expected type '{0}' to derive from UnityEngine.Component", type); - } #else public static void AssertTypesAreNotComponents(IEnumerable types) { diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs index d248d9234..a960877f2 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs @@ -38,11 +38,6 @@ protected override void OnFinalizeBinding(DiContainer container) IProvider CreateProviderForType( Type contractType, IPrefabInstantiator instantiator) { - if (contractType == typeof(GameObject)) - { - return new PrefabGameObjectProvider(instantiator); - } - Assert.That(contractType.IsInterface() || contractType.DerivesFrom()); return new GetFromPrefabComponentProvider( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs index d9962b6f0..fd45fe55c 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs @@ -38,11 +38,6 @@ protected override void OnFinalizeBinding(DiContainer container) IProvider CreateProviderForType( Type contractType, IPrefabInstantiator instantiator) { - if (contractType == typeof(GameObject)) - { - return new PrefabGameObjectProvider(instantiator); - } - Assert.That(contractType.IsInterface() || contractType.DerivesFrom()); return new GetFromPrefabComponentProvider( @@ -111,7 +106,7 @@ void FinalizeBindingSelf(DiContainer container) case ScopeTypes.Singleton: { RegisterProviderPerContract( - container, + container, (_, contractType) => container.SingletonProviderCreator.CreateProviderForPrefabResource( _resourcePath, contractType, @@ -123,7 +118,7 @@ void FinalizeBindingSelf(DiContainer container) case ScopeTypes.Transient: { RegisterProviderPerContract( - container, + container, (_, contractType) => CreateProviderForType( contractType, @@ -144,7 +139,7 @@ void FinalizeBindingSelf(DiContainer container) new PrefabProviderResource(_resourcePath))); RegisterProviderPerContract( - container, + container, (_, contractType) => new CachedProvider( CreateProviderForType(contractType, prefabCreator))); diff --git a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs index 1bfbfcacf..a15f1c28c 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs @@ -28,9 +28,8 @@ protected DiContainer Container } [SetUp] - public void SetUp() + public virtual void SetUp() { - ClearScene(); _hasStarted = false; _isValidating = CurrentTestHasAttribute(); diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs index dea6797b9..a0969a07d 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs @@ -79,6 +79,8 @@ public void AddNormalInstaller(InstallerBase installer) _normalInstallers.Add(installer); } + public abstract IEnumerable GetRootGameObjects(); + void CheckInstallerPrefabTypes() { foreach (var installer in _installers) diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs index 1f13d3f5d..1a00bf1fd 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs @@ -51,7 +51,13 @@ public static IEnumerable GetInjectableComponents(GameObject gameObje public static IEnumerable GetRootGameObjects(Scene scene) { - // Note: We can't use activeScene.GetRootObjects() here because that apparently fails with an exception + if (scene.isLoaded) + { + return scene.GetRootGameObjects() + .Where(x => x.GetComponent() == null); + } + + // Note: We can't use scene.GetRootObjects() here because that apparently fails with an exception // about the scene not being loaded yet when executed in Awake // We also can't use GameObject.FindObjectsOfType() because that does not include inactive game objects // So we use Resources.FindObjectsOfTypeAll, even though that may include prefabs. However, our assumption here diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs index 51ffd1ab5..1afae7dde 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs @@ -28,6 +28,11 @@ public override DiContainer Container get { return _container; } } + public override IEnumerable GetRootGameObjects() + { + return new[] { this.gameObject }; + } + [Inject] public void Construct( DiContainer parentContainer, diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs index 5ceaf0631..ae340f050 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs @@ -59,6 +59,11 @@ public static bool ValidateOnNextRun } #endif + public override IEnumerable GetRootGameObjects() + { + return new[] { this.gameObject }; + } + public static GameObject TryGetPrefab() { var prefab = (GameObject)Resources.Load(ProjectContextResourcePath); diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs index 4ec13d003..bdf1fa916 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs @@ -121,6 +121,11 @@ public void Run() Resolve(); } + public override IEnumerable GetRootGameObjects() + { + return ContextUtil.GetRootGameObjects(gameObject.scene); + } + DiContainer GetParentContainer() { if (string.IsNullOrEmpty(_parentContractName)) diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs index 53978687e..1e81fbed4 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs @@ -31,6 +31,13 @@ public override DiContainer Container } } + public override IEnumerable GetRootGameObjects() + { + // This method should never be called because SceneDecoratorContext's are not bound + // to the container + throw Assert.CreateException(); + } + public void Initialize(DiContainer container) { Assert.IsNull(_container); diff --git a/UnityProject/Assets/Zenject/Source/Internal/ReflectionUtil.cs b/UnityProject/Assets/Zenject/Source/Internal/ReflectionUtil.cs index f81c12249..4c715a940 100644 --- a/UnityProject/Assets/Zenject/Source/Internal/ReflectionUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Internal/ReflectionUtil.cs @@ -164,6 +164,42 @@ public static string ToDebugString(this Func func) + { +#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR + return func.ToString(); +#else + return func.Method.ToDebugString(); +#endif + } + + public static string ToDebugString(this Func func) + { +#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR + return func.ToString(); +#else + return func.Method.ToDebugString(); +#endif + } + + public static string ToDebugString(this Func func) + { +#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR + return func.ToString(); +#else + return func.Method.ToDebugString(); +#endif + } + + public static string ToDebugString(this Func func) + { +#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR + return func.ToString(); +#else + return func.Method.ToDebugString(); +#endif + } + public interface IMemberInfo { Type MemberType diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index e5cffbaf1..8ddc03889 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -381,8 +381,11 @@ public IList ResolveAll(InjectContext context) return ReflectionUtil.CreateGenericList(context.MemberType, instances); } - Assert.That(context.Optional, - "Could not find required dependency with type '{0}' \nObject graph:\n {1}", context.MemberType, context.GetObjectGraphString()); + if (!context.Optional) + { + throw Assert.CreateException( + "Could not find required dependency with type '{0}' \nObject graph:\n {1}", context.MemberType, context.GetObjectGraphString()); + } return ReflectionUtil.CreateGenericList(context.MemberType, new object[] {}); } @@ -450,11 +453,14 @@ public Type ResolveType(InjectContext context) var result = TryGetUniqueProvider(context, out provider); - Assert.That(result != ProviderLookupResult.Multiple, - "Found multiple matches when only one was expected for type '{0}'{1}. \nObject graph:\n {2}", - context.MemberType, - (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), - context.GetObjectGraphString()); + if (result == ProviderLookupResult.Multiple) + { + throw Assert.CreateException( + "Found multiple matches when only one was expected for type '{0}'{1}. \nObject graph:\n {2}", + context.MemberType, + (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), + context.GetObjectGraphString()); + } if (result != ProviderLookupResult.Success) { @@ -558,11 +564,14 @@ public object Resolve(InjectContext context) var result = TryGetUniqueProvider(context, out providerPair); - Assert.That(result != ProviderLookupResult.Multiple, - "Found multiple matches when only one was expected for type '{0}'{1}. \nObject graph:\n {2}", - context.MemberType, - (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), - context.GetObjectGraphString()); + if (result == ProviderLookupResult.Multiple) + { + throw Assert.CreateException( + "Found multiple matches when only one was expected for type '{0}'{1}. \nObject graph:\n {2}", + context.MemberType, + (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), + context.GetObjectGraphString()); + } if (result == ProviderLookupResult.None) { @@ -597,8 +606,21 @@ public object Resolve(InjectContext context) var instances = SafeGetInstances(providerPair, context); - Assert.That(!instances.IsEmpty(), "Provider returned zero instances when one was expected!"); - Assert.That(instances.Count() == 1, "Provider returned multiple instances when one was expected!"); + if (instances.IsEmpty()) + { + throw Assert.CreateException("Provider returned zero instances when one was expected! While resolving type '{0}'{1}. \nObject graph:\n{2}", + context.MemberType.ToString() + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), + (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), + context.GetObjectGraphString()); + } + + if (instances.Count() > 1) + { + throw Assert.CreateException("Provider returned multiple instances when only one was expected! While resolving type '{0}'{1}. \nObject graph:\n{2}", + context.MemberType.ToString() + (context.Identifier == null ? "" : " with ID '{0}'".Fmt(context.Identifier.ToString())), + (context.ObjectType == null ? "" : " while building object with type '{0}'".Fmt(context.ObjectType)), + context.GetObjectGraphString()); + } return instances.First(); } @@ -623,9 +645,13 @@ IEnumerable SafeGetInstances(ProviderPair providerPair, InjectContext co // transient) and the process continues indefinitely var providerContainer = providerPair.Container; - // Allow one before giving up so that you can do circular dependencies via postinject or fields - Assert.That(providerContainer._resolvesInProgress.Where(x => x.Equals(lookupId)).Count() <= 1, - "Circular dependency detected! \nObject graph:\n {0}", context.GetObjectGraphString()); + + if (providerContainer._resolvesInProgress.Where(x => x.Equals(lookupId)).Count() > 1) + { + // Allow one before giving up so that you can do circular dependencies via postinject or fields + throw Assert.CreateException( + "Circular dependency detected! \nObject graph:\n {0}", context.GetObjectGraphString()); + } providerContainer._resolvesInProgress.Push(lookupId); try @@ -1929,7 +1955,7 @@ public IdScopeConditionCopyNonLazyBinder BindInstance(TContract insta var binding = StartBinding(); binding.SubFinalizer = new ScopableBindingFinalizer( - bindInfo, SingletonTypes.ToInstance, instance, + bindInfo, SingletonTypes.FromInstance, instance, (container, type) => new InstanceProvider(container, type, instance)); return new IdScopeConditionCopyNonLazyBinder(bindInfo); diff --git a/UnityProject/Assets/Zenject/Source/Providers/CachedProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/CachedProvider.cs index 7b80018fd..c73bc4657 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/CachedProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/CachedProvider.cs @@ -33,9 +33,12 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co // This should only happen with constructor injection // Field or property injection should allow circular dependencies - Assert.That(!_isCreatingInstance, - "Found circular dependency when creating type '{0}'. Object graph: {1}", - _creator.GetInstanceType(context), context.GetObjectGraphString()); + if (_isCreatingInstance) + { + throw Assert.CreateException( + "Found circular dependency when creating type '{0}'. Object graph: {1}", + _creator.GetInstanceType(context), context.GetObjectGraphString()); + } _isCreatingInstance = true; diff --git a/UnityProject/Assets/Zenject/Source/Providers/MethodProviderMultiple.cs b/UnityProject/Assets/Zenject/Source/Providers/MethodProviderMultiple.cs new file mode 100644 index 000000000..74f19c052 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Providers/MethodProviderMultiple.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using System.Linq; +using ModestTree.Util; + +namespace Zenject +{ + public class MethodProviderMultiple : IProvider + { + readonly DiContainer _container; + readonly Func> _method; + + public MethodProviderMultiple( + Func> method, + DiContainer container) + { + _container = container; + _method = method; + } + + public Type GetInstanceType(InjectContext context) + { + return typeof(TReturn); + } + + public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext context, List args) + { + Assert.IsEmpty(args); + Assert.IsNotNull(context); + + Assert.That(typeof(TReturn).DerivesFromOrEqual(context.MemberType)); + + if (_container.IsValidating && !DiContainer.CanCreateOrInjectDuringValidation(context.MemberType)) + { + yield return new List() { new ValidationMarker(typeof(TReturn)) }; + } + else + { + var result = _method(context); + + if (result == null) + { + throw Assert.CreateException( + "Method '{0}' returned null when list was expected. Object graph: {1}", + _method.ToDebugString(), context.GetObjectGraphString()); + } + + yield return result.Cast().ToList(); + } + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Providers/MethodProviderMultiple.cs.meta b/UnityProject/Assets/Zenject/Source/Providers/MethodProviderMultiple.cs.meta new file mode 100644 index 000000000..0b4e3d128 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Providers/MethodProviderMultiple.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0e5a590d4406d6e46ba319046057db53 +timeCreated: 1485738781 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabResourceSingletonProviderCreator.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabResourceSingletonProviderCreator.cs index 0557089ba..2c4a32586 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabResourceSingletonProviderCreator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabResourceSingletonProviderCreator.cs @@ -29,7 +29,7 @@ public IProvider CreateProvider( IPrefabInstantiator creator; _markRegistry.MarkSingleton( - resultType, concreteIdentifier, SingletonTypes.ToPrefabResource); + resultType, concreteIdentifier, SingletonTypes.FromPrefabResource); var prefabId = new PrefabId(concreteIdentifier, resourcePath); diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabSingletonProviderCreator.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabSingletonProviderCreator.cs index 55b590036..0d2fa22f4 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabSingletonProviderCreator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabSingletonProviderCreator.cs @@ -32,7 +32,7 @@ public IProvider CreateProvider( var prefabId = new PrefabId(concreteIdentifier, prefab); _markRegistry.MarkSingleton( - resultType, concreteIdentifier, SingletonTypes.ToPrefab); + resultType, concreteIdentifier, SingletonTypes.FromPrefab); if (_prefabCreators.TryGetValue(prefabId, out creator)) { diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonTypes.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonTypes.cs index bc52e2dca..4a9cbf78e 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonTypes.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonTypes.cs @@ -2,22 +2,21 @@ namespace Zenject { public enum SingletonTypes { - To, - ToMethod, - ToSubContainerMethod, - ToSubContainerInstaller, - ToInstance, - ToPrefab, - ToPrefabResource, - ToFactory, - ToGameObject, - ToComponent, - ToComponentGameObject, - ToGetter, - ToResolve, - ToResource, - ToSubContainerPrefab, - ToSubContainerPrefabResource, + FromNew, + FromMethod, + FromSubContainerMethod, + FromSubContainerInstaller, + FromInstance, + FromPrefab, + FromPrefabResource, + FromFactory, + FromGameObject, + FromComponent, + FromComponentGameObject, + FromGetter, + FromResolve, + FromResource, + FromSubContainerPrefab, + FromSubContainerPrefabResource, } } - diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Standard/StandardSingletonProviderCreator.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Standard/StandardSingletonProviderCreator.cs index d5860d7a6..bdfd0a59f 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Standard/StandardSingletonProviderCreator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Standard/StandardSingletonProviderCreator.cs @@ -25,10 +25,10 @@ public IProvider GetOrCreateProvider( //Assert.IsNotEqual(dec.Type, SingletonTypes.ToPrefab); //Assert.IsNotEqual(dec.Type, SingletonTypes.ToPrefabResource); - Assert.IsNotEqual(dec.Type, SingletonTypes.ToSubContainerInstaller); - Assert.IsNotEqual(dec.Type, SingletonTypes.ToSubContainerMethod); - Assert.IsNotEqual(dec.Type, SingletonTypes.ToSubContainerPrefab); - Assert.IsNotEqual(dec.Type, SingletonTypes.ToSubContainerPrefabResource); + Assert.IsNotEqual(dec.Type, SingletonTypes.FromSubContainerInstaller); + Assert.IsNotEqual(dec.Type, SingletonTypes.FromSubContainerMethod); + Assert.IsNotEqual(dec.Type, SingletonTypes.FromSubContainerPrefab); + Assert.IsNotEqual(dec.Type, SingletonTypes.FromSubContainerPrefabResource); _markRegistry.MarkSingleton(dec.Id, dec.Type); diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByInstaller.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByInstaller.cs index 9be0c7bfd..6c5d0984f 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByInstaller.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByInstaller.cs @@ -23,7 +23,7 @@ public IProvider CreateProvider( { _markRegistry.MarkSingleton( resultType, concreteIdentifier, - SingletonTypes.ToSubContainerInstaller); + SingletonTypes.FromSubContainerInstaller); var subContainerSingletonId = new InstallerSingletonId( concreteIdentifier, installerType); diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByMethod.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByMethod.cs index 7d977ce50..f2ca3063d 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByMethod.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByMethod.cs @@ -25,7 +25,7 @@ public IProvider CreateProvider( { _markRegistry.MarkSingleton( new SingletonId(resultType, concreteIdentifier), - SingletonTypes.ToSubContainerMethod); + SingletonTypes.FromSubContainerMethod); ISubContainerCreator subContainerCreator; diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs index 475946453..ac4756989 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs @@ -28,7 +28,7 @@ public IProvider CreateProvider( { _markRegistry.MarkSingleton( resultType, concreteIdentifier, - SingletonTypes.ToSubContainerPrefab); + SingletonTypes.FromSubContainerPrefab); var customSingletonId = new CustomSingletonId( concreteIdentifier, prefab); diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs index 5bde8453d..fc27b62d7 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs @@ -26,7 +26,7 @@ public IProvider CreateProvider( { _markRegistry.MarkSingleton( resultType, concreteIdentifier, - SingletonTypes.ToSubContainerPrefabResource); + SingletonTypes.FromSubContainerPrefabResource); var customSingletonId = new CustomSingletonId( concreteIdentifier, resourcePath); From abc15f95eea5546571a691db273cc0b03f20223c Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 29 Jan 2017 23:25:21 -0400 Subject: [PATCH 28/62] Incremented version to 5.0 --- UnityProject/Assets/Zenject/Version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnityProject/Assets/Zenject/Version.txt b/UnityProject/Assets/Zenject/Version.txt index ef216a53f..819e07a22 100644 --- a/UnityProject/Assets/Zenject/Version.txt +++ b/UnityProject/Assets/Zenject/Version.txt @@ -1 +1 @@ -4.8 +5.0 From 6d0d7aad35dee143af2d6127b5d2ad426221110d Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 29 Jan 2017 23:32:58 -0400 Subject: [PATCH 29/62] Added mention of bind order to the docs issue #195 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 60eaf6688..3e26cf9ce 100644 --- a/README.md +++ b/README.md @@ -1211,6 +1211,8 @@ public class Bar Also, if the empty list is valid, then you should mark your List constructor parameter (or [Inject] field) as optional (see here for details). +The order of the list will be the same as the order in which they were added with a Bind method. The list will also be sorted by subcontainer, with the first set of instances taken from the bottom most subcontainer, and then the parent, then the grandparent, etc. + ## Global Bindings Using Project Context This all works great for each individual scene, but what if you have dependencies that you wish to persist permanently across all scenes? In Zenject you can do this by adding installers to a ProjectContext object. From a2dc2e6ab59a61607011a0335cb4a49a2e2e8f01 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 30 Jan 2017 00:08:18 -0400 Subject: [PATCH 30/62] Fixed non unity build to compile again --- .../UnitTests/Editor/Zenject-tests.csproj | 25 --------- .../Factories/Pooling/MonoMemoryPool.cs | 4 ++ .../Zenject/Source/Runtime/GuiRenderer.cs | 4 ++ .../Assets/Zenject/Source/Zenject.csproj | 53 ++++++++++++++----- 4 files changed, 49 insertions(+), 37 deletions(-) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj index ea7c02207..88ef1c395 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Zenject-tests.csproj @@ -56,17 +56,10 @@ - - - - - - - @@ -77,13 +70,6 @@ - - - - - - - @@ -110,22 +96,11 @@ - - - - - - - - - - - diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs index 8be790e26..9f12e0efc 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs @@ -1,3 +1,5 @@ +#if !NOT_UNITY3D + using System; using System.Collections.Generic; using UnityEngine; @@ -141,3 +143,5 @@ protected override void OnDespawned(TValue item) } } } + +#endif diff --git a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs index 3c45b42be..c9d1215d4 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs @@ -1,3 +1,5 @@ +#if !NOT_UNITY3D + using System; using System.Collections.Generic; using System.Linq; @@ -23,3 +25,5 @@ public void OnGUI() } } } + +#endif diff --git a/UnityProject/Assets/Zenject/Source/Zenject.csproj b/UnityProject/Assets/Zenject/Source/Zenject.csproj index 0a0d899fe..ca17995b4 100644 --- a/UnityProject/Assets/Zenject/Source/Zenject.csproj +++ b/UnityProject/Assets/Zenject/Source/Zenject.csproj @@ -43,8 +43,41 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -65,13 +98,7 @@ - - - - - - @@ -100,16 +127,21 @@ + + + + + @@ -120,6 +152,8 @@ + + @@ -189,9 +223,6 @@ - - - @@ -213,8 +244,6 @@ - - From 752d38aad4623b67c8ba273b8e5633ae4e931744 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 5 Feb 2017 19:27:21 -0400 Subject: [PATCH 31/62] - Added fix for a major performance issue for scenes that have a lot of transforms Re issue #188. Also changed to not bother sorting bottom up since the lazy instance injector should always give us the correct injection order anyway. - Fixed a minor multithreading issue - Added EditorStaticInstaller class --- .../Binding/Binders/CopyNonLazyBinder.cs | 8 ++++- .../Source/Editor/EditorStaticInstaller.cs | 30 +++++++++++++++++ .../Editor/EditorStaticInstaller.cs.meta | 12 +++++++ .../Factories/Pooling/MonoMemoryPool.cs | 4 --- .../Source/Install/Contexts/ContextUtil.cs | 2 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 33 ++++++------------- .../Source/Providers/CachedProvider.cs | 2 ++ .../PrefabCreators/PrefabInstantiator.cs | 3 +- .../Zenject/Source/Runtime/GuiRenderer.cs | 4 --- .../Zenject/Source/Util/ZenUtilInternal.cs | 32 +++++------------- 10 files changed, 72 insertions(+), 58 deletions(-) create mode 100644 UnityProject/Assets/Zenject/Source/Editor/EditorStaticInstaller.cs create mode 100644 UnityProject/Assets/Zenject/Source/Editor/EditorStaticInstaller.cs.meta diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs index 4eb11f152..27871abc6 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/CopyNonLazyBinder.cs @@ -14,7 +14,13 @@ public NonLazyBinder CopyIntoAllSubContainers() return this; } - // Would this be useful? + // Would these variations be useful? + + // Only copy the binding into children and not grandchildren //public NonLazyBinder CopyIntoDirectSubContainers() + + // Do not apply the binding on the current container + //public NonLazyBinder MoveIntoAllSubContainers() + //public NonLazyBinder MoveIntoDirectSubContainers() } } diff --git a/UnityProject/Assets/Zenject/Source/Editor/EditorStaticInstaller.cs b/UnityProject/Assets/Zenject/Source/Editor/EditorStaticInstaller.cs new file mode 100644 index 000000000..acb6d1f48 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Editor/EditorStaticInstaller.cs @@ -0,0 +1,30 @@ + +namespace Zenject +{ + // Derive from this class, add [InitializeOnLoad], and then call Install + // in a static constructor to add some editor time bindings + // For example: + // + // [InitializeOnLoad] + // public class FooInstaller : EditorStaticInstaller + // { + // static FooInstaller() + // { + // Install(); + // } + // + // public override void InstallBindings() + // { + // Container.BindInstance("hello world"); + // } + // } + // + public abstract class EditorStaticInstaller : InstallerBase + where T : EditorStaticInstaller + { + public static void Install() + { + StaticContext.Container.Instantiate().InstallBindings(); + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Editor/EditorStaticInstaller.cs.meta b/UnityProject/Assets/Zenject/Source/Editor/EditorStaticInstaller.cs.meta new file mode 100644 index 000000000..e8e1ecb70 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Editor/EditorStaticInstaller.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fcb2e11e0ed56de48b0ba9b5e3ae10c9 +timeCreated: 1486079412 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs index 9f12e0efc..8be790e26 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MonoMemoryPool.cs @@ -1,5 +1,3 @@ -#if !NOT_UNITY3D - using System; using System.Collections.Generic; using UnityEngine; @@ -143,5 +141,3 @@ protected override void OnDespawned(TValue item) } } } - -#endif diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs index 1a00bf1fd..c3321c651 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs @@ -26,7 +26,7 @@ public static IEnumerable GetInjectableComponents(Scene scene) public static IEnumerable GetInjectableComponents(GameObject gameObject) { - foreach (var component in ZenUtilInternal.GetInjectableComponentsBottomUp(gameObject, true)) + foreach (var component in ZenUtilInternal.GetInjectableComponents(gameObject)) { if (component == null) { diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 8ddc03889..a1cdbe9b7 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -1054,8 +1054,7 @@ public GameObject InstantiatePrefabExplicit( var gameObj = CreateAndParentPrefab(prefab, gameObjectBindInfo); - InjectGameObjectExplicit( - gameObj, true, extraArgs, useAllArgs); + InjectGameObjectExplicit(gameObj, extraArgs, useAllArgs); return gameObj; } @@ -1472,45 +1471,34 @@ public object InstantiatePrefabResourceForComponentExplicit( #if !NOT_UNITY3D // Inject dependencies into any and all child components on the given game object - public void InjectGameObject( - GameObject gameObject) - { - InjectGameObject(gameObject, true); - } - - public void InjectGameObject( - GameObject gameObject, bool recursive) + public void InjectGameObject(GameObject gameObject) { - InjectGameObject(gameObject, recursive, new object[0]); + InjectGameObject(gameObject, new object[0]); } public void InjectGameObject( - GameObject gameObject, bool recursive, IEnumerable extraArgs) + GameObject gameObject, IEnumerable extraArgs) { InjectGameObjectExplicit( - gameObject, recursive, - InjectUtil.CreateArgList(extraArgs)); + gameObject, InjectUtil.CreateArgList(extraArgs)); } public void InjectGameObjectExplicit( - GameObject gameObject, bool recursive, - List extraArgs) + GameObject gameObject, List extraArgs) { // We have to pass in a null InjectContext here because we aren't // asking for any particular type InjectGameObjectExplicit( - gameObject, recursive, extraArgs, true); + gameObject, extraArgs, true); } public void InjectGameObjectExplicit( - GameObject gameObject, bool recursive, - List extraArgs, bool useAllArgs) + GameObject gameObject, List extraArgs, bool useAllArgs) { FlushBindings(); // Inject on the children first since the parent objects are more likely to use them in their post inject methods - foreach (var component in ZenUtilInternal.GetInjectableComponentsBottomUp( - gameObject, recursive).ToList()) + foreach (var component in ZenUtilInternal.GetInjectableComponents(gameObject)) { if (component == null) { @@ -1549,8 +1537,7 @@ public Component InjectGameObjectForComponentExplicit( Component requestedScript = null; // Inject on the children first since the parent objects are more likely to use them in their post inject methods - foreach (var component in ZenUtilInternal.GetInjectableComponentsBottomUp( - gameObject, true).ToList()) + foreach (var component in ZenUtilInternal.GetInjectableComponents(gameObject)) { if (component == null) { diff --git a/UnityProject/Assets/Zenject/Source/Providers/CachedProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/CachedProvider.cs index c73bc4657..7487abff4 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/CachedProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/CachedProvider.cs @@ -31,6 +31,7 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co yield break; } +#if !ZEN_MULTITHREADING // This should only happen with constructor injection // Field or property injection should allow circular dependencies if (_isCreatingInstance) @@ -39,6 +40,7 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co "Found circular dependency when creating type '{0}'. Object graph: {1}", _creator.GetInstanceType(context), context.GetObjectGraphString()); } +#endif _isCreatingInstance = true; diff --git a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs index 91a247ed9..358dc732b 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs @@ -49,8 +49,7 @@ public IEnumerator Instantiate(List args) // Return it before inject so we can do circular dependencies yield return gameObject; - _container.InjectGameObjectExplicit( - gameObject, true, _extraArguments.Concat(args).ToList()); + _container.InjectGameObjectExplicit(gameObject, _extraArguments.Concat(args).ToList()); } } } diff --git a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs index c9d1215d4..3c45b42be 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs +++ b/UnityProject/Assets/Zenject/Source/Runtime/GuiRenderer.cs @@ -1,5 +1,3 @@ -#if !NOT_UNITY3D - using System; using System.Collections.Generic; using System.Linq; @@ -25,5 +23,3 @@ public void OnGUI() } } } - -#endif diff --git a/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs b/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs index 4d0976125..8dc0481e6 100644 --- a/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs +++ b/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs @@ -49,32 +49,18 @@ public static IEnumerable GetAllSceneContexts() } // NOTE: This method will not return components that are within a GameObjectContext - public static IEnumerable GetInjectableComponentsBottomUp( - GameObject gameObject, bool recursive) + public static List GetInjectableComponents(GameObject gameObject) { - var context = gameObject.GetComponent(); + var childMonoBehaviours = gameObject.GetComponentsInChildren(); - if (context != null) - { - yield return context; - yield break; - } + var subContexts = childMonoBehaviours.OfType().Select(x => x.transform).ToList(); - if (recursive) - { - foreach (Transform child in gameObject.transform) - { - foreach (var component in GetInjectableComponentsBottomUp(child.gameObject, recursive)) - { - yield return component; - } - } - } - - foreach (var component in gameObject.GetComponents()) - { - yield return component; - } + // Need to make sure we don't inject on any MonoBehaviour's that are below a GameObjectContext + // Since that is the responsibility of the GameObjectContext + // BUT we do want to inject on the GameObjectContext itself + return childMonoBehaviours.Where(x => x != null && x.transform.GetParents().Intersect(subContexts).IsEmpty() + && (x.GetComponent() == null || x is GameObjectContext)) + .ToList(); } #endif } From 42418c2ae21cf31bc6638a3692d0a9b329415f8b Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 5 Feb 2017 20:05:56 -0400 Subject: [PATCH 32/62] Minor code cleanup to previous change --- .../Source/Install/Contexts/Context.cs | 2 +- .../Source/Install/Contexts/ContextUtil.cs | 81 ------------------- .../Install/Contexts/ContextUtil.cs.meta | 12 --- .../Install/Contexts/GameObjectContext.cs | 23 +++--- .../Source/Install/Contexts/ProjectContext.cs | 5 +- .../Source/Install/Contexts/SceneContext.cs | 7 +- .../Install/Contexts/SceneDecoratorContext.cs | 5 +- .../Zenject/Source/Util/ZenUtilInternal.cs | 46 ++++++++++- 8 files changed, 64 insertions(+), 117 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs delete mode 100644 UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs.meta diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs index a0969a07d..8a3391e1a 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs @@ -248,7 +248,7 @@ void InstallZenjectBinding(ZenjectBinding binding) } } - protected abstract IEnumerable GetInjectableComponents(); + protected abstract IEnumerable GetInjectableComponents(); } } diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs deleted file mode 100644 index c3321c651..000000000 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs +++ /dev/null @@ -1,81 +0,0 @@ -#if !NOT_UNITY3D - -using System.Collections.Generic; -using System.Linq; -using ModestTree; -using UnityEngine; -using UnityEngine.SceneManagement; -using Zenject.Internal; - -namespace Zenject -{ - public static class ContextUtil - { - public static IEnumerable GetInjectableComponents(Scene scene) - { - foreach (var gameObject in GetRootGameObjects(scene)) - { - foreach (var component in GetInjectableComponents(gameObject)) - { - yield return component; - } - } - - yield break; - } - - public static IEnumerable GetInjectableComponents(GameObject gameObject) - { - foreach (var component in ZenUtilInternal.GetInjectableComponents(gameObject)) - { - if (component == null) - { - // This warning about fiBackupSceneStorage appears in normal cases so just ignore - // Not sure what it is - if (gameObject.name != "fiBackupSceneStorage") - { - Log.Warn("Zenject: Found null component on game object '{0}'. Possible missing script.", gameObject.name); - } - continue; - } - - if (component.GetType().DerivesFrom()) - { - // Do not inject on installers since these are always injected before they are installed - continue; - } - - yield return component; - } - } - - public static IEnumerable GetRootGameObjects(Scene scene) - { - if (scene.isLoaded) - { - return scene.GetRootGameObjects() - .Where(x => x.GetComponent() == null); - } - - // Note: We can't use scene.GetRootObjects() here because that apparently fails with an exception - // about the scene not being loaded yet when executed in Awake - // We also can't use GameObject.FindObjectsOfType() because that does not include inactive game objects - // So we use Resources.FindObjectsOfTypeAll, even though that may include prefabs. However, our assumption here - // is that prefabs do not have their "scene" property set correctly so this should work - // - // It's important here that we only inject into root objects that are part of our scene, to properly support - // multi-scene editing features of Unity 5.x - // - // Also, even with older Unity versions, if there is an object that is marked with DontDestroyOnLoad, then it will - // be injected multiple times when another scene is loaded - // - // We also make sure not to inject into the project root objects which are injected by ProjectContext. - return Resources.FindObjectsOfTypeAll() - .Where(x => x.transform.parent == null - && x.GetComponent() == null - && x.scene == scene); - } - } -} - -#endif diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs.meta b/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs.meta deleted file mode 100644 index 783ac06c5..000000000 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ContextUtil.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3e1cfb1920362094e9726ab68b48bc2f -timeCreated: 1477001002 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs index 1afae7dde..aebef9c7e 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs @@ -7,6 +7,7 @@ using ModestTree.Util; using UnityEngine; using UnityEngine.Serialization; +using Zenject.Internal; #pragma warning disable 649 @@ -84,37 +85,35 @@ public void Construct( Log.Debug("GameObjectContext: Initialized successfully"); } - protected override IEnumerable GetInjectableComponents() + protected override IEnumerable GetInjectableComponents() { // We inject on all components on the root except ourself - foreach (var component in GetComponents()) + foreach (var monoBehaviour in GetComponents()) { - if (component == null) + if (monoBehaviour == null) { - Log.Warn("Zenject: Found null component on game object '{0}'. Possible missing script.", gameObject.name); + // Missing script continue; } - if (component.GetType().DerivesFrom()) + if (monoBehaviour.GetType().DerivesFrom()) { // Do not inject on installers since these are always injected before they are installed continue; } - if (component == this) + if (monoBehaviour == this) { continue; } - yield return component; + yield return monoBehaviour; } - foreach (var gameObject in UnityUtil.GetDirectChildren(this.gameObject)) + foreach (var monoBehaviour in UnityUtil.GetDirectChildren(this.gameObject) + .SelectMany(ZenUtilInternal.GetInjectableComponents)) { - foreach (var component in ContextUtil.GetInjectableComponents(gameObject)) - { - yield return component; - } + yield return monoBehaviour; } } diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs index ae340f050..34fe0cb77 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; +using Zenject.Internal; #if UNITY_EDITOR using UnityEditor; @@ -154,9 +155,9 @@ void Initialize() _dependencyRoots.AddRange(_container.ResolveDependencyRoots()); } - protected override IEnumerable GetInjectableComponents() + protected override IEnumerable GetInjectableComponents() { - return ContextUtil.GetInjectableComponents(this.gameObject); + return ZenUtilInternal.GetInjectableComponents(this.gameObject); } void InstallBindings() diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs index bdf1fa916..127d0e3ac 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs @@ -8,6 +8,7 @@ using UnityEngine; using UnityEngine.Serialization; using UnityEngine.SceneManagement; +using Zenject.Internal; namespace Zenject { @@ -123,7 +124,7 @@ public void Run() public override IEnumerable GetRootGameObjects() { - return ContextUtil.GetRootGameObjects(gameObject.scene); + return ZenUtilInternal.GetRootGameObjects(gameObject.scene); } DiContainer GetParentContainer() @@ -286,9 +287,9 @@ void InstallBindings() InstallInstallers(); } - protected override IEnumerable GetInjectableComponents() + protected override IEnumerable GetInjectableComponents() { - return ContextUtil.GetInjectableComponents(this.gameObject.scene); + return ZenUtilInternal.GetInjectableComponents(this.gameObject.scene); } // These methods can be used for cases where you need to create the SceneContext entirely in code diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs index 1e81fbed4..59ca92c76 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs @@ -6,6 +6,7 @@ using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.Serialization; +using Zenject.Internal; namespace Zenject { @@ -58,9 +59,9 @@ public void InstallDecoratorInstallers() InstallInstallers(); } - protected override IEnumerable GetInjectableComponents() + protected override IEnumerable GetInjectableComponents() { - return ContextUtil.GetInjectableComponents(this.gameObject.scene); + return ZenUtilInternal.GetInjectableComponents(this.gameObject.scene); } } } diff --git a/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs b/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs index 8dc0481e6..c7033667f 100644 --- a/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs +++ b/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs @@ -55,13 +55,51 @@ public static List GetInjectableComponents(GameObject gameObject) var subContexts = childMonoBehaviours.OfType().Select(x => x.transform).ToList(); - // Need to make sure we don't inject on any MonoBehaviour's that are below a GameObjectContext - // Since that is the responsibility of the GameObjectContext - // BUT we do want to inject on the GameObjectContext itself - return childMonoBehaviours.Where(x => x != null && x.transform.GetParents().Intersect(subContexts).IsEmpty() + return childMonoBehaviours.Where(x => + // Can be null for broken component references + x != null + // Do not inject on installers since these are always injected before they are installed + && !x.GetType().DerivesFrom() + // Need to make sure we don't inject on any MonoBehaviour's that are below a GameObjectContext + // Since that is the responsibility of the GameObjectContext + // BUT we do want to inject on the GameObjectContext itself + && UnityUtil.GetParents(x.transform).Intersect(subContexts).IsEmpty() && (x.GetComponent() == null || x is GameObjectContext)) .ToList(); } + + public static IEnumerable GetInjectableComponents(Scene scene) + { + return GetRootGameObjects(scene) + .SelectMany(ZenUtilInternal.GetInjectableComponents); + } + + public static IEnumerable GetRootGameObjects(Scene scene) + { + if (scene.isLoaded) + { + return scene.GetRootGameObjects() + .Where(x => x.GetComponent() == null); + } + + // Note: We can't use scene.GetRootObjects() here because that apparently fails with an exception + // about the scene not being loaded yet when executed in Awake + // We also can't use GameObject.FindObjectsOfType() because that does not include inactive game objects + // So we use Resources.FindObjectsOfTypeAll, even though that may include prefabs. However, our assumption here + // is that prefabs do not have their "scene" property set correctly so this should work + // + // It's important here that we only inject into root objects that are part of our scene, to properly support + // multi-scene editing features of Unity 5.x + // + // Also, even with older Unity versions, if there is an object that is marked with DontDestroyOnLoad, then it will + // be injected multiple times when another scene is loaded + // + // We also make sure not to inject into the project root objects which are injected by ProjectContext. + return Resources.FindObjectsOfTypeAll() + .Where(x => x.transform.parent == null + && x.GetComponent() == null + && x.scene == scene); + } #endif } } From 8ccd3eb1caecafafe145ca6ac42e72ccdc06baca Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 5 Feb 2017 23:47:48 -0400 Subject: [PATCH 33/62] Fixed asteroids sample to work again --- .../Scripts/Installers/GameInstaller.cs | 4 +- .../Scripts/Ship/States/ShipStateDead.cs | 6 +-- .../UnitTests/Editor/Validation.meta | 9 ---- .../Source/Factories/GameObjectFactory.cs | 44 +++++++++++++++++++ .../Factories/GameObjectFactory.cs.meta | 12 +++++ 5 files changed, 60 insertions(+), 15 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta create mode 100644 UnityProject/Assets/Zenject/Source/Factories/GameObjectFactory.cs create mode 100644 UnityProject/Assets/Zenject/Source/Factories/GameObjectFactory.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs index ea1241527..7aff3f502 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs @@ -76,8 +76,8 @@ void InstallMisc() Container.BindInterfacesTo().AsSingle(); - Container.BindFactory().FromComponentInPrefab(_settings.ExplosionPrefab); - Container.BindFactory().FromComponentInPrefab(_settings.BrokenShipPrefab); + Container.Bind().AsSingle().WithArguments(_settings.ExplosionPrefab); + Container.Bind().AsSingle().WithArguments(_settings.BrokenShipPrefab); } void InstallShip() diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs index 934d8f623..88b16df52 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/States/ShipStateDead.cs @@ -6,11 +6,11 @@ namespace Zenject.Asteroids { - public class ExplosionFactory : Factory + public class ExplosionFactory : GameObjectFactory { } - public class BrokenShipFactory : Factory + public class BrokenShipFactory : GameObjectFactory { } @@ -76,8 +76,6 @@ public override void Update() [Serializable] public class Settings { - public GameObject brokenTemplate; - public GameObject explosionTemplate; public float explosionForce; } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta deleted file mode 100644 index 2f86c5428..000000000 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Validation.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: ab44aef4a43514d459389abc0dd0e481 -folderAsset: yes -timeCreated: 1485709788 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Factories/GameObjectFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/GameObjectFactory.cs new file mode 100644 index 000000000..7a90f5ad1 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/GameObjectFactory.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Zenject +{ + // This factory type can be useful if you want to instantiate from a prefab but there isn't + // a particular component that you want to grab from it + // You could use GameObject.Instantiate directly but then any MonoBehaviour's that might be + // on it would not be injected unlike if you use GameObjectFactory + // + // This is also nicer because any using code doesn't need access to the prefab and you can + // just bind it in an installer instead + // + // Example usage: + // + // public class ExplosionFactory : GameObjectFactory + // { + // } + // + // Then in an installer: + // + // Container.Bind().AsSingle().WithArguments(explosionPrefab) + + public class GameObjectFactory : IFactory + { + DiContainer _container; + UnityEngine.Object _prefab; + + [Inject] + public void Construct( + UnityEngine.Object prefab, + DiContainer container) + { + _container = container; + _prefab = prefab; + } + + public GameObject Create() + { + return _container.InstantiatePrefab(_prefab); + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Factories/GameObjectFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/GameObjectFactory.cs.meta new file mode 100644 index 000000000..a206d34a6 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Factories/GameObjectFactory.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: abc6818244c164c45be7985e17c29868 +timeCreated: 1486352695 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 4a57a0442b46f4d90f33406ab7c0943069e3dce4 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Wed, 8 Feb 2017 23:12:05 -0400 Subject: [PATCH 34/62] - Added some more tests of all the DiContainer methods - Removed support for passing arguments to InjectGameObject() and InstantiatePrefab since this wasn't needed and is bad practice and is a maintenance headache issue #125 - Fixed context menu to work properly when creating installers etc. issue #200 - Fixed issue with ZenUtilInternal.InjectGameObjectForComponent method to support looking up non-monobehaviours. - Also added InjectGameObjectForComponent method --- README.md | 3 +- .../Bindings/Editor/TestDiContainerMethods.cs | 125 +++++ .../Editor/TestDiContainerMethods.cs.meta | 12 + .../Bindings/Editor/TestFromPrefab.cs | 48 +- .../Bindings/Editor/TestFromPrefabResource.cs | 9 +- .../Resources/TestDiContainerMethods.meta | 9 + .../TestDiContainerMethods/Camera.prefab | 100 ++++ .../TestDiContainerMethods/Camera.prefab.meta | 8 + .../TestDiContainerMethods/Foo.prefab | 53 ++ .../TestDiContainerMethods/Foo.prefab.meta | 8 + .../TestDiContainerMethods/Gorp.prefab | 53 ++ .../TestDiContainerMethods/Gorp.prefab.meta | 8 + .../Resources/TestFromPrefab/Gorp.prefab | 53 ++ .../Resources/TestFromPrefab/Gorp.prefab.meta | 8 + .../TestFromPrefab/GorpAndQux.prefab | 24 +- .../TestFromPrefab/GorpAndQux.prefab.meta | 2 +- .../Resources/TestFromPrefab/Norf.prefab | 24 +- .../TestFromPrefabResource/Gorp.prefab | 53 ++ .../TestFromPrefabResource/Gorp.prefab.meta | 8 + .../Bindings/TestDiContainerMethods.meta | 9 + .../Bindings/TestDiContainerMethods/Foo.cs | 23 + .../TestDiContainerMethods/Foo.cs.meta | 12 + .../Bindings/TestDiContainerMethods/Gorp.cs | 25 + .../TestDiContainerMethods/Gorp.cs.meta | 12 + .../Bindings/TestFromPrefab/Gorp.cs | 5 + .../Factories/Editor/TestBindFactory.cs | 94 +++- .../Resources/TestBindFactory/Camera.prefab | 100 ++++ .../TestBindFactory/Camera.prefab.meta | 8 + .../Binders/Factory/FactoryFromBinderBase.cs | 4 +- .../Finalizers/PrefabBindingFinalizer.cs | 20 + .../PrefabResourceBindingFinalizer.cs | 20 + .../Zenject/Source/Editor/ZenMenuItems.cs | 7 +- .../Source/Editor/ZenUnityEditorUtil.cs | 40 +- .../Source/Install/Contexts/Context.cs | 4 +- .../Install/Contexts/GameObjectContext.cs | 6 +- .../Source/Install/Contexts/ProjectContext.cs | 6 +- .../Source/Install/Contexts/SceneContext.cs | 6 +- .../Install/Contexts/SceneDecoratorContext.cs | 6 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 512 ++++++++---------- .../Zenject/Source/Main/IInstantiator.cs | 73 +-- .../PrefabCreators/IPrefabInstantiator.cs | 6 + .../PrefabCreators/PrefabInstantiator.cs | 35 +- .../PrefabInstantiatorCached.cs | 6 + .../PrefabResourceSingletonProviderCreator.cs | 1 + .../Prefab/PrefabSingletonProviderCreator.cs | 2 +- .../Singleton/SingletonProviderCreator.cs | 3 +- .../SubContainerCreatorByPrefab.cs | 3 +- .../SubContainerCreatorByPrefabWithParams.cs | 3 +- .../Zenject/Source/Util/ZenUtilInternal.cs | 6 +- .../Assets/Zenject/Source/Zenject.csproj | 3 - 50 files changed, 1211 insertions(+), 457 deletions(-) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Camera.prefab create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Camera.prefab.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo.prefab create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo.prefab.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp.prefab create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp.prefab.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Gorp.prefab create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Gorp.prefab.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefabResource/Gorp.prefab create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefabResource/Gorp.prefab.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Resources/TestBindFactory/Camera.prefab create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Resources/TestBindFactory/Camera.prefab.meta diff --git a/README.md b/README.md index 3e26cf9ce..4fc71724b 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,10 @@ For general troubleshooting / support, please use the [zenject subreddit](http:/ * Support for global, project-wide bindings to add dependencies for all scenes * Convention based binding, based on class name, namespace, or any other criteria * Ability to validate object graphs at editor time (including dynamic object graphs created via factories) -* Commands and Signals * Automatic binding on components in the scene using the `ZenjectBinding` component * Auto-Mocking using the Moq library +* Built-in support for memory pools +* Just-in-time resolving using the Lazy<> construct ## Installation diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs new file mode 100644 index 000000000..cc0f642ca --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject.Tests.Bindings.DiContainerMethods; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestDiContainerMethods : ZenjectIntegrationTestFixture + { + GameObject FooPrefab + { + get { return GetPrefab("Foo"); } + } + + GameObject GorpPrefab + { + get { return GetPrefab("Gorp"); } + } + + GameObject CameraPrefab + { + get { return GetPrefab("Camera"); } + } + + [Test] + public void InjectGameObject() + { + Initialize(); + + var go = GameObject.Instantiate(FooPrefab); + + var foo = go.GetComponentInChildren(); + + Assert.That(!foo.WasInjected); + Container.InjectGameObject(go); + Assert.That(foo.WasInjected); + } + + [Test] + public void InjectGameObjectForMonoBehaviour() + { + Initialize(); + + var go = GameObject.Instantiate(GorpPrefab); + + Assert.Throws(() => Container.InjectGameObject(go)); + + var gorp = Container.InjectGameObjectForComponent(go, new object[] { "asdf" }); + + Assert.IsEqual(gorp.Arg, "asdf"); + } + + [Test] + public void InjectGameObjectForComponent() + { + Initialize(); + + var go = GameObject.Instantiate(CameraPrefab); + + Container.InjectGameObjectForComponent(go, new object[0]); + } + + [Test] + public void InjectGameObjectForComponentMistake() + { + Initialize(); + + var go = GameObject.Instantiate(CameraPrefab); + + Assert.Throws(() => Container.InjectGameObjectForComponent(go, new object[] { "sdf" })); + } + + [Test] + public void InstantiatePrefab() + { + Initialize(); + + var go = Container.InstantiatePrefab(FooPrefab); + + var foo = go.GetComponentInChildren(); + + Assert.That(foo.WasInjected); + } + + [Test] + public void InstantiatePrefabForMonoBehaviour() + { + Initialize(); + + Assert.Throws(() => Container.InstantiatePrefab(GorpPrefab)); + + var gorp = Container.InstantiatePrefabForComponent(GorpPrefab, new object[] { "asdf" }); + + Assert.IsEqual(gorp.Arg, "asdf"); + } + + [Test] + public void InstantiatePrefabForComponent() + { + Initialize(); + + var camera = Container.InstantiatePrefabForComponent(CameraPrefab, new object[0]); + Assert.IsNotNull(camera); + } + + [Test] + public void InstantiatePrefabForComponentMistake() + { + Initialize(); + + Assert.Throws(() => Container.InstantiatePrefabForComponent(CameraPrefab, new object[] { "sdf" })); + } + + GameObject GetPrefab(string name) + { + return FixtureUtil.GetPrefab("TestDiContainerMethods/{0}".Fmt(name)); + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs.meta new file mode 100644 index 000000000..88b3a07ad --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: aaf3d9c26b0d0d642844da6a229929cb +timeCreated: 1486604780 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs index f4d447a46..7cbef575b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs @@ -14,42 +14,32 @@ public class TestFromPrefab : ZenjectIntegrationTestFixture { GameObject FooPrefab { - get - { - return GetPrefab("Foo"); - } + get { return GetPrefab("Foo"); } } GameObject FooPrefab2 { - get - { - return GetPrefab("Foo2"); - } + get { return GetPrefab("Foo2"); } + } + + GameObject GorpPrefab + { + get { return GetPrefab("Gorp"); } } GameObject GorpAndQuxPrefab { - get - { - return GetPrefab("GorpAndQux"); - } + get { return GetPrefab("GorpAndQux"); } } GameObject NorfPrefab { - get - { - return GetPrefab("Norf"); - } + get { return GetPrefab("Norf"); } } GameObject JimAndBobPrefab { - get - { - return GetPrefab("JimAndBob"); - } + get { return GetPrefab("JimAndBob"); } } [Test] @@ -131,18 +121,28 @@ public void TestWithArgumentsFail() } [Test] - public void TestWithArguments() + [ExpectedException] + public void TestWithArgumentsFail2() { Container.Bind(typeof(Gorp), typeof(Qux)) - .FromComponentInPrefab(GorpAndQuxPrefab).WithGameObjectName("GorpAndQux").AsCached() + .FromComponentInPrefab(GorpAndQuxPrefab).WithGameObjectName("Gorp").AsCached() .WithArguments(5, "test1").NonLazy(); Initialize(); + } + + [Test] + public void TestWithArgumentsSuccess() + { + Container.Bind().FromComponentInPrefab(GorpPrefab) + .WithGameObjectName("Gorp").AsCached() + .WithArguments("test1").NonLazy(); + + Initialize(); FixtureUtil.AssertNumGameObjects(Container, 1); FixtureUtil.AssertComponentCount(Container, 1); - FixtureUtil.AssertComponentCount(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, "GorpAndQux", 1); + FixtureUtil.AssertNumGameObjectsWithName(Container, "Gorp", 1); } [Test] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs index 0a200b10f..56e2d15f1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs @@ -106,16 +106,15 @@ public void TestWithArgumentsFail() [Test] public void TestWithArguments() { - Container.Bind(typeof(Gorp), typeof(Qux)) - .FromComponentInPrefabResource(PathPrefix + "GorpAndQux").WithGameObjectName("GorpAndQux").AsCached() - .WithArguments(5, "test1").NonLazy(); + Container.Bind(typeof(Gorp)) + .FromComponentInPrefabResource(PathPrefix + "Gorp").WithGameObjectName("Gorp").AsCached() + .WithArguments("test1").NonLazy(); Initialize(); FixtureUtil.AssertNumGameObjects(Container, 1); FixtureUtil.AssertComponentCount(Container, 1); - FixtureUtil.AssertComponentCount(Container, 1); - FixtureUtil.AssertNumGameObjectsWithName(Container, "GorpAndQux", 1); + FixtureUtil.AssertNumGameObjectsWithName(Container, "Gorp", 1); } [Test] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods.meta new file mode 100644 index 000000000..76f49df91 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ae273adaa7c1c564487be2bde343fd8f +folderAsset: yes +timeCreated: 1486605497 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Camera.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Camera.prefab new file mode 100644 index 000000000..eab3b4e9f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Camera.prefab @@ -0,0 +1,100 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1701984141030306} + m_IsPrefabParent: 1 +--- !u!1 &1701984141030306 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4917894310632104} + - component: {fileID: 20112712621694618} + - component: {fileID: 124440584488477408} + - component: {fileID: 92371959540391994} + - component: {fileID: 81115495585236142} + m_Layer: 0 + m_Name: Camera + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4917894310632104 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1701984141030306} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 233.15675, y: 367.62057, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!20 &20112712621694618 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1701984141030306} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 + m_StereoMirrorMode: 0 +--- !u!81 &81115495585236142 +AudioListener: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1701984141030306} + m_Enabled: 1 +--- !u!92 &92371959540391994 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1701984141030306} + m_Enabled: 1 +--- !u!124 &124440584488477408 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1701984141030306} + m_Enabled: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Camera.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Camera.prefab.meta new file mode 100644 index 000000000..7a90f9b8f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Camera.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0e8cb14a39fd6f249a44c7943b3fa7c0 +timeCreated: 1486605718 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo.prefab new file mode 100644 index 000000000..33ae050b0 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo.prefab @@ -0,0 +1,53 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1430110355770212} + m_IsPrefabParent: 1 +--- !u!1 &1430110355770212 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4724547747360102} + - component: {fileID: 114632795606949010} + m_Layer: 0 + m_Name: Foo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4724547747360102 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1430110355770212} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &114632795606949010 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1430110355770212} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 576295a2c4f9589448e9441994df8491, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo.prefab.meta new file mode 100644 index 000000000..da6eb15e8 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d193bc261e49cce4eb82e05b80485388 +timeCreated: 1486605527 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp.prefab new file mode 100644 index 000000000..1bca0d50e --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp.prefab @@ -0,0 +1,53 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1475120265837186} + m_IsPrefabParent: 1 +--- !u!1 &1475120265837186 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4016417502563626} + - component: {fileID: 114277461040308946} + m_Layer: 0 + m_Name: Gorp + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4016417502563626 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1475120265837186} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 233.15675, y: 367.62057, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &114277461040308946 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1475120265837186} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 33197ae07a0a36e41bf9fa09aa8d0ce6, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp.prefab.meta new file mode 100644 index 000000000..0ced8bea8 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 956d91076f66be1488d99299c06d37b8 +timeCreated: 1486605550 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Gorp.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Gorp.prefab new file mode 100644 index 000000000..c68f2e7c1 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Gorp.prefab @@ -0,0 +1,53 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &154292 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 496146} + - component: {fileID: 11470700} + m_Layer: 0 + m_Name: Gorp + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &496146 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 154292} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11470700 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 154292} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: cc679fbba1bf0a645957d68235c4771d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 154292} + m_IsPrefabParent: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Gorp.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Gorp.prefab.meta new file mode 100644 index 000000000..9bbd80e8a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Gorp.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1eb53b39cb1d1114782475a86c1e55f1 +timeCreated: 1459002680 +licenseType: Pro +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab index aceb9451e..2e662722c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab @@ -8,8 +8,8 @@ GameObject: serializedVersion: 5 m_Component: - component: {fileID: 496146} - - component: {fileID: 11461012} - component: {fileID: 11470700} + - component: {fileID: 114629866799586768} m_Layer: 0 m_Name: GorpAndQux m_TagString: Untagged @@ -30,17 +30,6 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &11461012 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 154292} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 914f813dee2b8b248bce3b21eafa7b6e, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!114 &11470700 MonoBehaviour: m_ObjectHideFlags: 1 @@ -63,3 +52,14 @@ Prefab: m_ParentPrefab: {fileID: 0} m_RootGameObject: {fileID: 154292} m_IsPrefabParent: 1 +--- !u!114 &114629866799586768 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 154292} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 914f813dee2b8b248bce3b21eafa7b6e, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab.meta index 73ce7c0b8..64bc5cc01 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/GorpAndQux.prefab.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a9f9ff1c71e66294f910610d2194c731 +guid: d4e9c6984a3aba946bdf015abbc6488f timeCreated: 1459002680 licenseType: Pro NativeFormatImporter: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Norf.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Norf.prefab index 01df16e53..a7bc65edf 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Norf.prefab +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefab/Norf.prefab @@ -9,8 +9,8 @@ GameObject: m_Component: - component: {fileID: 431222} - component: {fileID: 11449184} - - component: {fileID: 11420968} - component: {fileID: 11461460} + - component: {fileID: 114984624536322558} m_Layer: 0 m_Name: Norf m_TagString: Untagged @@ -31,17 +31,6 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &11420968 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 199570} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 91f7cce5532e4cc4796d58d33d783a80, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!114 &11449184 MonoBehaviour: m_ObjectHideFlags: 1 @@ -75,3 +64,14 @@ Prefab: m_ParentPrefab: {fileID: 0} m_RootGameObject: {fileID: 199570} m_IsPrefabParent: 1 +--- !u!114 &114984624536322558 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 199570} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 91f7cce5532e4cc4796d58d33d783a80, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefabResource/Gorp.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefabResource/Gorp.prefab new file mode 100644 index 000000000..60857f8f1 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefabResource/Gorp.prefab @@ -0,0 +1,53 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &154292 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 496146} + - component: {fileID: 11419060} + m_Layer: 0 + m_Name: Gorp + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &496146 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 154292} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &11419060 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 154292} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 93bd1149166ed44478c2e59b34fbfc9b, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 154292} + m_IsPrefabParent: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefabResource/Gorp.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefabResource/Gorp.prefab.meta new file mode 100644 index 000000000..446e1aee6 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromPrefabResource/Gorp.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 889ca6448cbd11b4a9fd4511513f21ac +timeCreated: 1459015737 +licenseType: Pro +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods.meta new file mode 100644 index 000000000..addc4cd15 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3a875c53fb6af544392d924deaee54bc +folderAsset: yes +timeCreated: 1486605381 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo.cs new file mode 100644 index 000000000..8e54c36f3 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo.cs @@ -0,0 +1,23 @@ +using UnityEngine; + +namespace Zenject.Tests.Bindings.DiContainerMethods +{ + public interface IFoo + { + } + + public class Foo : MonoBehaviour, IFoo + { + public bool WasInjected + { + get; + private set; + } + + [Inject] + public void Construct() + { + WasInjected = true; + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo.cs.meta new file mode 100644 index 000000000..918a82348 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 576295a2c4f9589448e9441994df8491 +timeCreated: 1486605381 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp.cs new file mode 100644 index 000000000..137e69631 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp.cs @@ -0,0 +1,25 @@ +using ModestTree; +using UnityEngine; +using Zenject; + +#pragma warning disable 649 + +namespace Zenject.Tests.Bindings.DiContainerMethods +{ + public class Gorp : MonoBehaviour + { + [Inject] + string _arg; + + public string Arg + { + get { return _arg; } + } + + [Inject] + public void Initialize() + { + Log.Trace("Received arg '{0}' in Gorp", _arg); + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp.cs.meta new file mode 100644 index 000000000..44f0515c8 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 33197ae07a0a36e41bf9fa09aa8d0ce6 +timeCreated: 1486605381 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromPrefab/Gorp.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromPrefab/Gorp.cs index cf6345e88..4f69f0f96 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromPrefab/Gorp.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromPrefab/Gorp.cs @@ -11,6 +11,11 @@ public class Gorp : MonoBehaviour [Inject] string _arg; + public string Arg + { + get { return _arg; } + } + [Inject] public void Initialize() { diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs index cf3953b78..516fc22e1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs @@ -14,46 +14,78 @@ public class TestBindFactory : ZenjectIntegrationTestFixture { GameObject FooPrefab { - get - { - return FixtureUtil.GetPrefab("TestBindFactory/Foo"); - } + get { return FixtureUtil.GetPrefab("TestBindFactory/Foo"); } + } + + GameObject CameraPrefab + { + get { return FixtureUtil.GetPrefab("TestBindFactory/Camera"); } } GameObject FooSubContainerPrefab { - get - { - return FixtureUtil.GetPrefab("TestBindFactory/FooSubContainer"); - } + get { return FixtureUtil.GetPrefab("TestBindFactory/FooSubContainer"); } } [Test] - public void TestToGameObjectSelf() + public void TestFromNewComponentOnNewGameObject() { Container.BindFactory().FromNewComponentOnNewGameObject(); Initialize(); FixtureUtil.CallFactoryCreateMethod(Container); - FixtureUtil.AssertComponentCount(Container, 1); FixtureUtil.AssertNumGameObjects(Container, 1); } [Test] - [ExpectedException] - public void TestToGameObjectSelfFail() + public void TestFromNewComponentOnNewGameObjectComponent() + { + Container.BindFactory().FromNewComponentOnNewGameObject(); + + Initialize(); + + FixtureUtil.CallFactoryCreateMethod(Container); + FixtureUtil.AssertComponentCount(Container, 1); + FixtureUtil.AssertNumGameObjects(Container, 1); + } + + [Test] + public void TestFromNewComponentOnNewGameObjectComponentFailure() + { + Container.BindFactory().FromNewComponentOnNewGameObject(); + + Initialize(); + + Assert.Throws(() => Container.Resolve().Create("asdf")); + } + + [Test] + public void TestFromNewComponentOnNewGameObjectWithParamsSuccess() + { + Container.BindFactory().FromNewComponentOnNewGameObject(); + + Initialize(); + + Container.Resolve().Create(5); + + FixtureUtil.AssertComponentCount(Container, 1); + FixtureUtil.AssertNumGameObjects(Container, 1); + } + + [Test] + public void TestFromNewComponentOnNewGameObjectWithParamsFailure() { Container.BindFactory().FromNewComponentOnNewGameObject(); Initialize(); - FixtureUtil.CallFactoryCreateMethod(Container); + Assert.Throws(() => Container.Resolve().Create()); } [Test] - public void TestToGameObjectConcrete() + public void TestFromNewComponentOnNewGameObjectConcrete() { Container.BindFactory().To().FromNewComponentOnNewGameObject(); @@ -65,7 +97,7 @@ public void TestToGameObjectConcrete() } [Test] - public void TestToMonoBehaviourSelf() + public void TestFromNewComponentOnSelf() { var gameObject = Container.CreateEmptyGameObject("foo"); @@ -80,7 +112,7 @@ public void TestToMonoBehaviourSelf() [Test] [ExpectedException] - public void TestToMonoBehaviourSelfFail() + public void TestFromNewComponentOnSelfFail() { Container.BindFactory().FromNewComponentOn((GameObject)null); @@ -88,7 +120,7 @@ public void TestToMonoBehaviourSelfFail() } [Test] - public void TestToMonoBehaviourConcrete() + public void TestFromNewComponentOnConcrete() { var gameObject = Container.CreateEmptyGameObject("foo"); @@ -102,7 +134,7 @@ public void TestToMonoBehaviourConcrete() } [Test] - public void TestToPrefabSelf() + public void TestFromComponentInPrefab() { Container.BindFactory().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); @@ -115,6 +147,20 @@ public void TestToPrefabSelf() FixtureUtil.AssertNumGameObjectsWithName(Container, "asdf", 1); } + [Test] + public void TestFromComponentInPrefabComponent() + { + Container.BindFactory().FromComponentInPrefab(CameraPrefab).WithGameObjectName("asdf"); + + Initialize(); + + FixtureUtil.CallFactoryCreateMethod(Container); + + FixtureUtil.AssertComponentCount(Container, 1); + FixtureUtil.AssertNumGameObjects(Container, 1); + FixtureUtil.AssertNumGameObjectsWithName(Container, "asdf", 1); + } + [Test] [ExpectedException] public void TestToPrefabSelfFail() @@ -293,6 +339,14 @@ public void TestUnderTransformGetter() Assert.IsNotNull(tempGameObject.transform.GetChild(0).GetComponent()); } + public class CameraFactory2 : Factory + { + } + + public class CameraFactory : Factory + { + } + public class Foo3 : MonoBehaviour { public class Factory : Factory @@ -308,6 +362,10 @@ public class Foo2 : MonoBehaviour public class Factory : Factory { } + + public class Factory2 : Factory + { + } } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Resources/TestBindFactory/Camera.prefab b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Resources/TestBindFactory/Camera.prefab new file mode 100644 index 000000000..553f70d71 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Resources/TestBindFactory/Camera.prefab @@ -0,0 +1,100 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 1976089539457028} + m_IsPrefabParent: 1 +--- !u!1 &1976089539457028 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 4820708267059456} + - component: {fileID: 20551869419536700} + - component: {fileID: 124884577352525608} + - component: {fileID: 92930362624271806} + - component: {fileID: 81582071896233372} + m_Layer: 0 + m_Name: Camera + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4820708267059456 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1976089539457028} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!20 &20551869419536700 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1976089539457028} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 + m_StereoMirrorMode: 0 +--- !u!81 &81582071896233372 +AudioListener: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1976089539457028} + m_Enabled: 1 +--- !u!92 &92930362624271806 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1976089539457028} + m_Enabled: 1 +--- !u!124 &124884577352525608 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1976089539457028} + m_Enabled: 1 diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Resources/TestBindFactory/Camera.prefab.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Resources/TestBindFactory/Camera.prefab.meta new file mode 100644 index 000000000..3d704c5ae --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Resources/TestBindFactory/Camera.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4b06f8082448e80458c9e2a87fef6131 +timeCreated: 1486607599 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs index f3e54aed6..29727f078 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs @@ -115,7 +115,7 @@ public NameTransformConditionCopyNonLazyBinder FromComponentInPrefab(UnityEngine ContractType, new PrefabInstantiator( container, gameObjectInfo, - new List(), new PrefabProvider(prefab))); + ContractType, new List(), new PrefabProvider(prefab))); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } @@ -132,7 +132,7 @@ public NameTransformConditionCopyNonLazyBinder FromComponentInPrefabResource(str ContractType, new PrefabInstantiator( container, gameObjectInfo, - new List(), new PrefabProviderResource(resourcePath))); + ContractType, new List(), new PrefabProviderResource(resourcePath))); return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs index a960877f2..18eaa2d79 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs @@ -72,16 +72,26 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) new PrefabInstantiator( container, _gameObjectBindInfo, + concreteType, BindInfo.Arguments, new PrefabProvider(_prefab)))); break; } case ScopeTypes.Cached: { + var argumentTarget = concreteTypes.OnlyOrDefault(); + + if (argumentTarget == null) + { + Assert.That(BindInfo.Arguments.IsEmpty(), + "Cannot provide arguments to prefab instantiator when using more than one concrete type"); + } + var prefabCreator = new PrefabInstantiatorCached( new PrefabInstantiator( container, _gameObjectBindInfo, + argumentTarget, BindInfo.Arguments, new PrefabProvider(_prefab))); @@ -125,16 +135,26 @@ void FinalizeBindingSelf(DiContainer container) new PrefabInstantiator( container, _gameObjectBindInfo, + contractType, BindInfo.Arguments, new PrefabProvider(_prefab)))); break; } case ScopeTypes.Cached: { + var argumentTarget = BindInfo.ContractTypes.OnlyOrDefault(); + + if (argumentTarget == null) + { + Assert.That(BindInfo.Arguments.IsEmpty(), + "Cannot provide arguments to prefab instantiator when using more than one concrete type"); + } + var prefabCreator = new PrefabInstantiatorCached( new PrefabInstantiator( container, _gameObjectBindInfo, + argumentTarget, BindInfo.Arguments, new PrefabProvider(_prefab))); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs index fd45fe55c..f848ed116 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs @@ -72,16 +72,26 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) new PrefabInstantiator( container, _gameObjectBindInfo, + concreteType, BindInfo.Arguments, new PrefabProviderResource(_resourcePath)))); break; } case ScopeTypes.Cached: { + var argumentTarget = concreteTypes.OnlyOrDefault(); + + if (argumentTarget == null) + { + Assert.That(BindInfo.Arguments.IsEmpty(), + "Cannot provide arguments to prefab instantiator when using more than one concrete type"); + } + var prefabCreator = new PrefabInstantiatorCached( new PrefabInstantiator( container, _gameObjectBindInfo, + argumentTarget, BindInfo.Arguments, new PrefabProviderResource(_resourcePath))); @@ -125,16 +135,26 @@ void FinalizeBindingSelf(DiContainer container) new PrefabInstantiator( container, _gameObjectBindInfo, + contractType, BindInfo.Arguments, new PrefabProviderResource(_resourcePath)))); break; } case ScopeTypes.Cached: { + var argumentTarget = BindInfo.ContractTypes.OnlyOrDefault(); + + if (argumentTarget == null) + { + Assert.That(BindInfo.Arguments.IsEmpty(), + "Cannot provide arguments to prefab instantiator when using more than one concrete type"); + } + var prefabCreator = new PrefabInstantiatorCached( new PrefabInstantiator( container, _gameObjectBindInfo, + argumentTarget, BindInfo.Arguments, new PrefabProviderResource(_resourcePath))); diff --git a/UnityProject/Assets/Zenject/Source/Editor/ZenMenuItems.cs b/UnityProject/Assets/Zenject/Source/Editor/ZenMenuItems.cs index 29f267421..7dce161e9 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/ZenMenuItems.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/ZenMenuItems.cs @@ -238,10 +238,9 @@ static void CreateProjectContextInternal(string absoluteDir) static void AddCSharpClassTemplate( string friendlyName, string defaultFileName, bool editorOnly, string templateStr) { - var currentDir = ZenUnityEditorUtil.ConvertFullAbsolutePathToAssetPath( - ZenUnityEditorUtil.TryGetSelectedFolderPathInProjectsTab()); + var folderPath = ZenUnityEditorUtil.GetCurrentDirectoryAssetPathFromSelection(); - if (editorOnly && !currentDir.Contains("/Editor")) + if (editorOnly && !folderPath.Contains("/Editor")) { EditorUtility.DisplayDialog("Error", "Editor window classes must have a parent folder above them named 'Editor'. Please create or find an Editor folder and try again", "Ok"); @@ -250,7 +249,7 @@ static void AddCSharpClassTemplate( var absolutePath = EditorUtility.SaveFilePanel( "Choose name for " + friendlyName, - currentDir, + folderPath, defaultFileName + ".cs", "cs"); diff --git a/UnityProject/Assets/Zenject/Source/Editor/ZenUnityEditorUtil.cs b/UnityProject/Assets/Zenject/Source/Editor/ZenUnityEditorUtil.cs index c300651cd..603fa51c9 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/ZenUnityEditorUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/ZenUnityEditorUtil.cs @@ -118,9 +118,43 @@ static IEnumerable GetAllSceneContexts() public static string ConvertFullAbsolutePathToAssetPath(string fullPath) { - return "Assets/" + Path.GetFullPath(fullPath) - .Remove(0, Path.GetFullPath(Application.dataPath).Length + 1) - .Replace("\\", "/"); + fullPath = Path.GetFullPath(fullPath); + + var assetFolderFullPath = Path.GetFullPath(Application.dataPath); + + if (fullPath.Length == assetFolderFullPath.Length) + { + Assert.IsEqual(fullPath, assetFolderFullPath); + return "Assets"; + } + + var assetPath = fullPath.Remove(0, assetFolderFullPath.Length + 1).Replace("\\", "/"); + return "Assets/" + assetPath; + } + + public static string GetCurrentDirectoryAssetPathFromSelection() + { + return ZenUnityEditorUtil.ConvertFullAbsolutePathToAssetPath( + GetCurrentDirectoryAbsolutePathFromSelection()); + } + + public static string GetCurrentDirectoryAbsolutePathFromSelection() + { + var folderPath = ZenUnityEditorUtil.TryGetSelectedFolderPathInProjectsTab(); + + if (folderPath != null) + { + return folderPath; + } + + var filePath = ZenUnityEditorUtil.TryGetSelectedFilePathInProjectsTab(); + + if (filePath != null) + { + return Path.GetDirectoryName(filePath); + } + + return Application.dataPath; } public static string TryGetSelectedFilePathInProjectsTab() diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs index 8a3391e1a..0fbbd4c90 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/Context.cs @@ -157,7 +157,7 @@ protected void InstallInstallers() protected void InstallSceneBindings() { - foreach (var binding in GetInjectableComponents().OfType()) + foreach (var binding in GetInjectableMonoBehaviours().OfType()) { if (binding == null) { @@ -248,7 +248,7 @@ void InstallZenjectBinding(ZenjectBinding binding) } } - protected abstract IEnumerable GetInjectableComponents(); + protected abstract IEnumerable GetInjectableMonoBehaviours(); } } diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs index aebef9c7e..b4f061319 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs @@ -45,7 +45,7 @@ public void Construct( _container = parentContainer.CreateSubContainer(); _container.LazyInstanceInjector - .AddInstances(GetInjectableComponents().Cast()); + .AddInstances(GetInjectableMonoBehaviours().Cast()); foreach (var instance in _container.LazyInstanceInjector.Instances) { @@ -85,7 +85,7 @@ public void Construct( Log.Debug("GameObjectContext: Initialized successfully"); } - protected override IEnumerable GetInjectableComponents() + protected override IEnumerable GetInjectableMonoBehaviours() { // We inject on all components on the root except ourself foreach (var monoBehaviour in GetComponents()) @@ -111,7 +111,7 @@ protected override IEnumerable GetInjectableComponents() } foreach (var monoBehaviour in UnityUtil.GetDirectChildren(this.gameObject) - .SelectMany(ZenUtilInternal.GetInjectableComponents)) + .SelectMany(ZenUtilInternal.GetInjectableMonoBehaviours)) { yield return monoBehaviour; } diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs index 34fe0cb77..5ac74d8b3 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs @@ -135,7 +135,7 @@ void Initialize() StaticContext.Container, isValidating); _container.LazyInstanceInjector.AddInstances( - GetInjectableComponents().Cast()); + GetInjectableMonoBehaviours().Cast()); _container.IsInstalling = true; @@ -155,9 +155,9 @@ void Initialize() _dependencyRoots.AddRange(_container.ResolveDependencyRoots()); } - protected override IEnumerable GetInjectableComponents() + protected override IEnumerable GetInjectableMonoBehaviours() { - return ZenUtilInternal.GetInjectableComponents(this.gameObject); + return ZenUtilInternal.GetInjectableMonoBehaviours(this.gameObject); } void InstallBindings() diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs index 127d0e3ac..feb37a1e6 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs @@ -218,7 +218,7 @@ public void Install() // InitialComponentsInjecter will also guarantee that any component that is injected into // another component has itself been injected _container.LazyInstanceInjector - .AddInstances(GetInjectableComponents().Cast()); + .AddInstances(GetInjectableMonoBehaviours().Cast()); foreach (var decoratorContext in _decoratorContexts) { @@ -287,9 +287,9 @@ void InstallBindings() InstallInstallers(); } - protected override IEnumerable GetInjectableComponents() + protected override IEnumerable GetInjectableMonoBehaviours() { - return ZenUtilInternal.GetInjectableComponents(this.gameObject.scene); + return ZenUtilInternal.GetInjectableMonoBehaviours(this.gameObject.scene); } // These methods can be used for cases where you need to create the SceneContext entirely in code diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs index 59ca92c76..fb50ecce4 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs @@ -45,7 +45,7 @@ public void Initialize(DiContainer container) _container = container; container.LazyInstanceInjector - .AddInstances(GetInjectableComponents().Cast()); + .AddInstances(GetInjectableMonoBehaviours().Cast()); } public void InstallDecoratorSceneBindings() @@ -59,9 +59,9 @@ public void InstallDecoratorInstallers() InstallInstallers(); } - protected override IEnumerable GetInjectableComponents() + protected override IEnumerable GetInjectableMonoBehaviours() { - return ZenUtilInternal.GetInjectableComponents(this.gameObject.scene); + return ZenUtilInternal.GetInjectableMonoBehaviours(this.gameObject.scene); } } } diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index a1cdbe9b7..a18b98ea0 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -23,8 +23,9 @@ public class InjectArgs } // Responsibilities: - // - Expose methods to configure object graph via Bind() methods - // - Build object graphs via Resolve() method + // - Expose methods to configure object graph via BindX() methods + // - Look up bound values via Resolve() method + // - Instantiate new values via InstantiateX() methods public class DiContainer : IInstantiator { public const string DependencyRootIdentifier = "DependencyRoot"; @@ -701,38 +702,6 @@ public IEnumerable GetDependencyContracts(Type contract) } } - public T InstantiateExplicit(List extraArgs) - { - return (T)InstantiateExplicit(typeof(T), extraArgs); - } - - public object InstantiateExplicit(Type concreteType, List extraArgs) - { - bool autoInject = true; - - return InstantiateExplicit( - concreteType, - autoInject, - new InjectArgs() - { - ExtraArgs = extraArgs, - Context = new InjectContext(this, concreteType, null), - ConcreteIdentifier = null, - UseAllArgs = true, - }); - } - - // See comment in IInstantiator.cs for description of this method - public object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs args) - { -#if UNITY_EDITOR - using (ProfileBlock.Start("Zenject.Instantiate({0})", concreteType)) -#endif - { - return InstantiateInternal(concreteType, autoInject, args); - } - } - public static bool CanCreateOrInjectDuringValidation(Type type) { // During validation, do not instantiate or inject anything except for @@ -993,72 +962,6 @@ public void InjectExplicit( #if !NOT_UNITY3D - public GameObject InstantiatePrefabResourceExplicit( - string resourcePath, List extraArgs) - { - return InstantiatePrefabResourceExplicit( - resourcePath, extraArgs, null); - } - - public GameObject InstantiatePrefabResourceExplicit( - string resourcePath, List extraArgs, string groupName) - { - return InstantiatePrefabResourceExplicit( - resourcePath, extraArgs, groupName, true); - } - - // Note: extraArgs must be non null - public GameObject InstantiatePrefabResourceExplicit( - string resourcePath, List extraArgs, - string groupName, bool useAllArgs) - { - var prefab = (GameObject)Resources.Load(resourcePath); - Assert.IsNotNull(prefab, "Could not find prefab at resource location '{0}'".Fmt(resourcePath)); - - return InstantiatePrefabExplicit( - prefab, extraArgs, groupName, useAllArgs); - } - - // Note: extraArgs must be non null - public GameObject InstantiatePrefabExplicit( - UnityEngine.Object prefab, List extraArgs) - { - return InstantiatePrefabExplicit( - prefab, extraArgs, null); - } - - // Note: extraArgs must be non null - public GameObject InstantiatePrefabExplicit( - UnityEngine.Object prefab, List extraArgs, - string groupName) - { - return InstantiatePrefabExplicit( - prefab, extraArgs, groupName, true); - } - - // Note: extraArgs must be non null - public GameObject InstantiatePrefabExplicit( - UnityEngine.Object prefab, List extraArgs, - string groupName, bool useAllArgs) - { - return InstantiatePrefabExplicit( - prefab, extraArgs, new GameObjectCreationParameters() { GroupName = groupName }, useAllArgs); - } - - // Note: extraArgs must be non null - public GameObject InstantiatePrefabExplicit( - UnityEngine.Object prefab, List extraArgs, - GameObjectCreationParameters gameObjectBindInfo, bool useAllArgs) - { - FlushBindings(); - - var gameObj = CreateAndParentPrefab(prefab, gameObjectBindInfo); - - InjectGameObjectExplicit(gameObj, extraArgs, useAllArgs); - - return gameObj; - } - // Don't use this unless you know what you're doing // You probably want to use InstantiatePrefab instead // This one will only create the prefab and will not inject into it @@ -1126,69 +1029,6 @@ public GameObject CreateEmptyGameObject(GameObjectCreationParameters gameObjectB return gameObj; } - public T InstantiatePrefabForComponentExplicit( - UnityEngine.Object prefab, List extraArgs) - { - return (T)InstantiatePrefabForComponentExplicit( - typeof(T), prefab, extraArgs); - } - - // Note: Any arguments that are used will be removed from extraArgs - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, List extraArgs) - { - return InstantiatePrefabForComponentExplicit( - componentType, prefab, extraArgs, null); - } - - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, List extraArgs, - string groupName) - { - return InstantiatePrefabForComponentExplicit( - componentType, prefab, groupName, - new InjectArgs() - { - ExtraArgs = extraArgs, - Context = new InjectContext(this, componentType, null), - ConcreteIdentifier = null, - UseAllArgs = true, - }); - } - - // Note: Any arguments that are used will be removed from extraArgs - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, string groupName, InjectArgs args) - { - return InstantiatePrefabForComponentExplicit( - componentType, prefab, new GameObjectCreationParameters() { GroupName = groupName }, args); - } - - // Note: Any arguments that are used will be removed from extraArgs - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, - GameObjectCreationParameters gameObjectBindInfo, InjectArgs args) - { - Assert.That(!AssertOnNewGameObjects, - "Given DiContainer does not support creating new game objects"); - - FlushBindings(); - - Assert.That(prefab != null, "Null prefab found when instantiating game object"); - - Assert.That(componentType.IsInterface() || componentType.DerivesFrom(), - "Expected type '{0}' to derive from UnityEngine.Component", componentType); - - GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); - - var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); - - gameObj.transform.SetParent(GetTransformGroup(gameObjectBindInfo), false); - - return InjectGameObjectForComponentExplicit( - gameObj, componentType, args); - } - Transform GetTransformGroup(GameObjectCreationParameters gameObjectBindInfo) { Assert.That(!AssertOnNewGameObjects, @@ -1248,7 +1088,6 @@ public T Instantiate() return Instantiate(new object[0]); } - // See comment in IInstantiator.cs for description of this method public T Instantiate(IEnumerable extraArgs) { var result = Instantiate(typeof(T), extraArgs); @@ -1267,7 +1106,6 @@ public object Instantiate(Type concreteType) return Instantiate(concreteType, new object[0]); } - // See comment in IInstantiator.cs for description of this method public object Instantiate( Type concreteType, IEnumerable extraArgs) { @@ -1278,15 +1116,50 @@ public object Instantiate( concreteType, InjectUtil.CreateArgList(extraArgs)); } + public T InstantiateExplicit(List extraArgs) + { + return (T)InstantiateExplicit(typeof(T), extraArgs); + } + + public object InstantiateExplicit(Type concreteType, List extraArgs) + { + bool autoInject = true; + + return InstantiateExplicit( + concreteType, + autoInject, + new InjectArgs() + { + ExtraArgs = extraArgs, + Context = new InjectContext(this, concreteType, null), + ConcreteIdentifier = null, + UseAllArgs = true, + }); + } + + public object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs args) + { +#if UNITY_EDITOR + using (ProfileBlock.Start("Zenject.Instantiate({0})", concreteType)) +#endif + { + return InstantiateInternal(concreteType, autoInject, args); + } + } + #if !NOT_UNITY3D - // See comment in IInstantiator.cs for description of this method + // Add new component to existing game object and fill in its dependencies + // This is the same as AddComponent except the [Inject] fields will be filled in + // NOTE: Gameobject here is not a prefab prototype, it is an instance public TContract InstantiateComponent(GameObject gameObject) where TContract : Component { return InstantiateComponent(gameObject, new object[0]); } - // See comment in IInstantiator.cs for description of this method + // Add new component to existing game object and fill in its dependencies + // This is the same as AddComponent except the [Inject] fields will be filled in + // NOTE: Gameobject here is not a prefab prototype, it is an instance public TContract InstantiateComponent( GameObject gameObject, IEnumerable extraArgs) where TContract : Component @@ -1294,13 +1167,18 @@ public TContract InstantiateComponent( return (TContract)InstantiateComponent(typeof(TContract), gameObject, extraArgs); } + // Add new component to existing game object and fill in its dependencies + // This is the same as AddComponent except the [Inject] fields will be filled in + // NOTE: Gameobject here is not a prefab prototype, it is an instance public Component InstantiateComponent( Type componentType, GameObject gameObject) { return InstantiateComponent(componentType, gameObject, new object[0]); } - // See comment in IInstantiator.cs for description of this method + // Add new component to existing game object and fill in its dependencies + // This is the same as AddComponent except the [Inject] fields will be filled in + // NOTE: Gameobject here is not a prefab prototype, it is an instance public Component InstantiateComponent( Type componentType, GameObject gameObject, IEnumerable extraArgs) { @@ -1308,6 +1186,19 @@ public Component InstantiateComponent( componentType, gameObject, InjectUtil.CreateArgList(extraArgs)); } + public T InstantiateComponentOnNewGameObject() + where T : Component + { + return InstantiateComponentOnNewGameObject(typeof(T).Name); + } + + public T InstantiateComponentOnNewGameObject(string gameObjectName) + where T : Component + { + return InstantiateComponent( + CreateEmptyGameObject(new GameObjectCreationParameters() { Name = gameObjectName })); + } + public Component InstantiateComponentExplicit( Type componentType, GameObject gameObject, List extraArgs) { @@ -1320,79 +1211,60 @@ public Component InstantiateComponentExplicit( return monoBehaviour; } - // Note: extraArgs must be non null + // Create a new game object from a prefab and fill in dependencies for all children public GameObject InstantiatePrefab(UnityEngine.Object prefab) { - return InstantiatePrefab(prefab, new object[0]); + return InstantiatePrefab(prefab, (string)null); } - // Note: extraArgs must be non null + // Create a new game object from a prefab and fill in dependencies for all children public GameObject InstantiatePrefab( - UnityEngine.Object prefab, IEnumerable extraArgs) + UnityEngine.Object prefab, string groupName) { - return InstantiatePrefab(prefab, extraArgs, (string)null); + return InstantiatePrefab( + prefab, new GameObjectCreationParameters() { GroupName = groupName }); } - // Note: extraArgs must be non null + // Create a new game object from a prefab and fill in dependencies for all children public GameObject InstantiatePrefab( - UnityEngine.Object prefab, IEnumerable extraArgs, string groupName) + UnityEngine.Object prefab, GameObjectCreationParameters gameObjectBindInfo) { - return InstantiatePrefab(prefab, extraArgs, - new GameObjectCreationParameters() { GroupName = groupName }); - } + FlushBindings(); - // Note: extraArgs must be non null - internal GameObject InstantiatePrefab( - UnityEngine.Object prefab, IEnumerable extraArgs, - GameObjectCreationParameters gameObjectBindInfo) - { - return InstantiatePrefabExplicit( - prefab, InjectUtil.CreateArgList(extraArgs), gameObjectBindInfo, true); - } + var gameObj = CreateAndParentPrefab(prefab, gameObjectBindInfo); - // See comment in IInstantiator.cs for description of this method - public GameObject InstantiatePrefabResource(string resourcePath) - { - return InstantiatePrefabResource(resourcePath, new object[0]); + InjectGameObject(gameObj); + + return gameObj; } - // See comment in IInstantiator.cs for description of this method - public GameObject InstantiatePrefabResource( - string resourcePath, IEnumerable extraArgs) + // Create a new game object from a resource path and fill in dependencies for all children + public GameObject InstantiatePrefabResource(string resourcePath) { - return InstantiatePrefabResource( - resourcePath, extraArgs, null); + return InstantiatePrefabResource(resourcePath, null); } - // See comment in IInstantiator.cs for description of this method + // Create a new game object from a resource path and fill in dependencies for all children public GameObject InstantiatePrefabResource( - string resourcePath, IEnumerable extraArgs, string groupName) + string resourcePath, string groupName) { - return InstantiatePrefabResourceExplicit( - resourcePath, InjectUtil.CreateArgList(extraArgs), - groupName); - } - - /////////////// InstantiatePrefabForComponent + var prefab = (GameObject)Resources.Load(resourcePath); - public T InstantiateComponentOnNewGameObject() - where T : Component - { - return InstantiateComponentOnNewGameObject(typeof(T).Name); - } + Assert.IsNotNull(prefab, + "Could not find prefab at resource location '{0}'".Fmt(resourcePath)); - public T InstantiateComponentOnNewGameObject(string gameObjectName) - where T : Component - { - return InstantiateComponent( - CreateEmptyGameObject(new GameObjectCreationParameters() { Name = gameObjectName })); + return InstantiatePrefab(prefab, groupName); } + // Same as InstantiatePrefab but returns a component after it's initialized + // and optionally allows extra arguments for the given component type public T InstantiatePrefabForComponent(UnityEngine.Object prefab) { return InstantiatePrefabForComponent(prefab, new object[0]); } + // Same as InstantiatePrefab but returns a component after it's initialized + // and optionally allows extra arguments for the given component type public T InstantiatePrefabForComponent( UnityEngine.Object prefab, IEnumerable extraArgs) { @@ -1400,6 +1272,8 @@ public T InstantiatePrefabForComponent( typeof(T), prefab, extraArgs); } + // Same as InstantiatePrefab but returns a component after it's initialized + // and optionally allows extra arguments for the given component type public object InstantiatePrefabForComponent( Type concreteType, UnityEngine.Object prefab, IEnumerable extraArgs) { @@ -1408,22 +1282,23 @@ public object InstantiatePrefabForComponent( InjectUtil.CreateArgList(extraArgs)); } - /////////////// InstantiatePrefabForComponent - - // See comment in IInstantiator.cs for description of this method + // Same as InstantiatePrefabResource but returns a component after it's initialized + // and optionally allows extra arguments for the given component type public T InstantiatePrefabResourceForComponent(string resourcePath) { return InstantiatePrefabResourceForComponent(resourcePath, new object[0]); } - // See comment in IInstantiator.cs for description of this method + // Same as InstantiatePrefabResource but returns a component after it's initialized + // and optionally allows extra arguments for the given component type public T InstantiatePrefabResourceForComponent( string resourcePath, IEnumerable extraArgs) { return (T)InstantiatePrefabResourceForComponent(typeof(T), resourcePath, extraArgs); } - // See comment in IInstantiator.cs for description of this method + // Same as InstantiatePrefabResource but returns a component after it's initialized + // and optionally allows extra arguments for the given component type public object InstantiatePrefabResourceForComponent( Type concreteType, string resourcePath, IEnumerable extraArgs) { @@ -1434,6 +1309,8 @@ public object InstantiatePrefabResourceForComponent( concreteType, resourcePath, InjectUtil.CreateArgList(extraArgs)); } + // Same as InstantiatePrefabResourceForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList public T InstantiatePrefabResourceForComponentExplicit( string resourcePath, List extraArgs) { @@ -1441,7 +1318,8 @@ public T InstantiatePrefabResourceForComponentExplicit( typeof(T), resourcePath, extraArgs); } - // Note: Any arguments that are used will be removed from extraArgs + // Same as InstantiatePrefabResourceForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabResourceForComponentExplicit( Type componentType, string resourcePath, List extraArgs) { @@ -1456,7 +1334,9 @@ public object InstantiatePrefabResourceForComponentExplicit( }); } - // Note: Any arguments that are used will be removed from extraArgs + + // Same as InstantiatePrefabResourceForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabResourceForComponentExplicit( Type componentType, string resourcePath, string groupName, InjectArgs args) { @@ -1467,111 +1347,155 @@ public object InstantiatePrefabResourceForComponentExplicit( componentType, prefab, groupName, args); } -#endif + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public T InstantiatePrefabForComponentExplicit( + UnityEngine.Object prefab, List extraArgs) + { + return (T)InstantiatePrefabForComponentExplicit( + typeof(T), prefab, extraArgs); + } -#if !NOT_UNITY3D - // Inject dependencies into any and all child components on the given game object - public void InjectGameObject(GameObject gameObject) + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, List extraArgs) { - InjectGameObject(gameObject, new object[0]); + return InstantiatePrefabForComponentExplicit( + componentType, prefab, extraArgs, null); } - public void InjectGameObject( - GameObject gameObject, IEnumerable extraArgs) + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, List extraArgs, + string groupName) { - InjectGameObjectExplicit( - gameObject, InjectUtil.CreateArgList(extraArgs)); + return InstantiatePrefabForComponentExplicit( + componentType, prefab, groupName, + new InjectArgs() + { + ExtraArgs = extraArgs, + Context = new InjectContext(this, componentType, null), + ConcreteIdentifier = null, + UseAllArgs = true, + }); } - public void InjectGameObjectExplicit( - GameObject gameObject, List extraArgs) + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, string groupName, InjectArgs args) { - // We have to pass in a null InjectContext here because we aren't - // asking for any particular type - InjectGameObjectExplicit( - gameObject, extraArgs, true); + return InstantiatePrefabForComponentExplicit( + componentType, prefab, new GameObjectCreationParameters() { GroupName = groupName }, args); } - public void InjectGameObjectExplicit( - GameObject gameObject, List extraArgs, bool useAllArgs) + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, + GameObjectCreationParameters gameObjectBindInfo, InjectArgs args) { + Assert.That(!AssertOnNewGameObjects, + "Given DiContainer does not support creating new game objects"); + FlushBindings(); - // Inject on the children first since the parent objects are more likely to use them in their post inject methods - foreach (var component in ZenUtilInternal.GetInjectableComponents(gameObject)) - { - if (component == null) - { - Log.Warn("Found null component while injecting game object '{0}'. Possible missing script.", gameObject.name); - continue; - } + Assert.That(prefab != null, "Null prefab found when instantiating game object"); - if (component.GetType().DerivesFrom()) - { - // Do not inject on installers since these are always injected before they are installed - continue; - } + Assert.That(componentType.IsInterface() || componentType.DerivesFrom(), + "Expected type '{0}' to derive from UnityEngine.Component", componentType); - InjectExplicit(component, component.GetType(), - new InjectArgs() - { - ExtraArgs = extraArgs, - Context = new InjectContext(this, component.GetType()), - ConcreteIdentifier = null, - UseAllArgs = false, - }); - } + GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); + + var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); + + gameObj.transform.SetParent(GetTransformGroup(gameObjectBindInfo), false); - if (useAllArgs && !extraArgs.IsEmpty()) + return InjectGameObjectForComponentExplicit( + gameObj, componentType, args); + } + + // Inject dependencies into any and all child components on the given game object + public void InjectGameObject(GameObject gameObject) + { + FlushBindings(); + + foreach (var monoBehaviour in ZenUtilInternal.GetInjectableMonoBehaviours(gameObject)) { - throw Assert.CreateException( - "Passed unnecessary parameters when injecting into game object '{0}'. \nExtra Parameters: {1}", - gameObject.name, string.Join(",", extraArgs.Select(x => x.Type.ToString()).ToArray())); + Inject(monoBehaviour); } } - public Component InjectGameObjectForComponentExplicit( - GameObject gameObject, Type componentType, - InjectArgs args) + // Same as InjectGameObject except it will also search the game object for the + // given component, and also optionally allow passing extra inject arguments into the + // given component + public T InjectGameObjectForComponent(GameObject gameObject) + where T : Component { - Component requestedScript = null; + return InjectGameObjectForComponent(gameObject, new object[0]); + } - // Inject on the children first since the parent objects are more likely to use them in their post inject methods - foreach (var component in ZenUtilInternal.GetInjectableComponents(gameObject)) - { - if (component == null) - { - Log.Warn("Found null component while injecting into game object '{0}'. Possible missing script.", gameObject.name); - continue; - } + // Same as InjectGameObject except it will also search the game object for the + // given component, and also optionally allow passing extra inject arguments into the + // given component + public T InjectGameObjectForComponent( + GameObject gameObject, IEnumerable extraArgs) + where T : Component + { + return (T)InjectGameObjectForComponent(gameObject, typeof(T), extraArgs); + } - if (component.GetType().DerivesFrom()) + // Same as InjectGameObject except it will also search the game object for the + // given component, and also optionally allow passing extra inject arguments into the + // given component + public object InjectGameObjectForComponent( + GameObject gameObject, Type componentType, IEnumerable extraArgs) + { + return InjectGameObjectForComponentExplicit( + gameObject, componentType, + new InjectArgs() { - // Do not inject on installers since these are always injected before they are installed - continue; - } + ExtraArgs = InjectUtil.CreateArgList(extraArgs), + Context = new InjectContext(this, componentType, null), + ConcreteIdentifier = null, + UseAllArgs = true, + }); + } - if (component.GetType().DerivesFromOrEqual(componentType)) - { - Assert.IsNull(requestedScript, - "Found multiple matches with type '{0}' when injecting into game object '{1}'", componentType, gameObject.name); - requestedScript = component; + // Same as InjectGameObjectForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public Component InjectGameObjectForComponentExplicit( + GameObject gameObject, Type componentType, InjectArgs args) + { + if (!componentType.DerivesFrom() && !args.ExtraArgs.IsEmpty()) + { + throw Assert.CreateException( + "Cannot inject into non-monobehaviours! Argument list must be zero length"); + } - InjectExplicit(component, component.GetType(), args); + foreach (var monoBehaviour in ZenUtilInternal.GetInjectableMonoBehaviours(gameObject)) + { + if (monoBehaviour.GetType().DerivesFromOrEqual(componentType)) + { + InjectExplicit(monoBehaviour, monoBehaviour.GetType(), args); } else { - Inject(component); + Inject(monoBehaviour); } } - if (requestedScript == null) - { - throw Assert.CreateException( - "Could not find component with type '{0}' when instantiating new game object", componentType); - } + var matches = gameObject.GetComponentsInChildren(componentType); + + Assert.That(!matches.IsEmpty(), + "Expected to find component with type '{0}' when injecting into game object '{1}'", componentType, gameObject.name); + + Assert.That(matches.Length == 1, + "Found multiple component with type '{0}' when injecting into game object '{1}'", componentType, gameObject.name); - return requestedScript; + return matches[0]; } #endif @@ -1584,6 +1508,7 @@ public void Inject(object injectable) Inject(injectable, new object[0]); } + // Same as Inject(injectable) except allows adding extra values to be injected public void Inject(object injectable, IEnumerable extraArgs) { InjectExplicit( @@ -1631,6 +1556,7 @@ public object TryResolve(Type contractType, object identifier) return Resolve(new InjectContext(this, contractType, identifier, true)); } + // Non generic version public object Resolve(Type contractType) { return Resolve(new InjectContext(this, contractType, null)); @@ -1700,12 +1626,14 @@ public IList ResolveAll(Type contractType, object identifier, bool optional) return ResolveAll(context); } + // Removes all bindings public void UnbindAll() { FlushBindings(); _providers.Clear(); } + // Remove all bindings bound to the given contract type public bool Unbind() { return Unbind(null); diff --git a/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs b/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs index 4b34535be..b95c6ff43 100644 --- a/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs @@ -54,24 +54,18 @@ Component InstantiateComponentExplicit( // Create a new game object from a prefab and fill in dependencies for all children GameObject InstantiatePrefab(UnityEngine.Object prefab); GameObject InstantiatePrefab( - UnityEngine.Object prefab, IEnumerable extraArgs); - + UnityEngine.Object prefab, string groupName); GameObject InstantiatePrefab( - UnityEngine.Object prefab, IEnumerable extraArgs, string groupName); + UnityEngine.Object prefab, GameObjectCreationParameters gameObjectBindInfo); // Create a new game object from a resource path and fill in dependencies for all children GameObject InstantiatePrefabResource(string resourcePath); GameObject InstantiatePrefabResource( - string resourcePath, IEnumerable extraArgs); - - GameObject InstantiatePrefabResource( - string resourcePath, IEnumerable extraArgs, string groupName); - - /////////////// InstantiatePrefabForComponent + string resourcePath, string groupName); // Same as InstantiatePrefab but returns a component after it's initialized - + // and optionally allows extra arguments for the given component type T InstantiatePrefabForComponent(UnityEngine.Object prefab); T InstantiatePrefabForComponent( @@ -80,8 +74,8 @@ T InstantiatePrefabForComponent( object InstantiatePrefabForComponent( Type concreteType, UnityEngine.Object prefab, IEnumerable extraArgs); - /////////////// InstantiatePrefabResourceForComponent - + // Same as InstantiatePrefabResource but returns a component after it's initialized + // and optionally allows extra arguments for the given component type T InstantiatePrefabResourceForComponent(string resourcePath); T InstantiatePrefabResourceForComponent( @@ -90,66 +84,35 @@ T InstantiatePrefabResourceForComponent( object InstantiatePrefabResourceForComponent( Type concreteType, string resourcePath, IEnumerable extraArgs); - // Create a new game object from a given prefab - // Without returning any particular component - // If you want to retrieve a specific component use InstantiatePrefabForComponent - GameObject InstantiatePrefabExplicit( - UnityEngine.Object prefab, List extraArgs); - - GameObject InstantiatePrefabExplicit( - UnityEngine.Object prefab, List extraArgs, - string groupName); - - GameObject InstantiatePrefabExplicit( - UnityEngine.Object prefab, List extraArgs, - string groupName, bool useAllArgs); - - //// - - GameObject InstantiatePrefabResourceExplicit( + // Same as InstantiatePrefabResourceForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + T InstantiatePrefabResourceForComponentExplicit( string resourcePath, List extraArgs); - GameObject InstantiatePrefabResourceExplicit( - string resourcePath, List extraArgs, - string groupName); - - GameObject InstantiatePrefabResourceExplicit( - string resourcePath, List extraArgs, - string groupName, bool useAllArgs); + object InstantiatePrefabResourceForComponentExplicit( + Type concreteType, string resourcePath, List extraArgs); - // Instantiate the given prefab, inject on all components, then return the instance of 'componentType' - // Any arguments supplied are assumed to be used as extra parameters into 'componentType' + object InstantiatePrefabResourceForComponentExplicit( + Type concreteType, string resourcePath, string groupName, InjectArgs args); - // This is used instead of Instantiate to support specifying null values - // Note: Any arguments that are used will be removed from extraArgs + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList T InstantiatePrefabForComponentExplicit( UnityEngine.Object prefab, List extraArgs); - // Note: Any arguments that are used will be removed from extraArgs object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, List extraArgs); - // Note: Any arguments that are used will be removed from extraArgs object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, List extraArgs, string groupName); - // Note: Any arguments that are used will be removed from extraArgs object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, string groupName, InjectArgs args); - // This is used instead of Instantiate to support specifying null values - // Note: Any arguments that are used will be removed from extraArgs - T InstantiatePrefabResourceForComponentExplicit( - string resourcePath, List extraArgs); - - // Note: Any arguments that are used will be removed from extraArgs - object InstantiatePrefabResourceForComponentExplicit( - Type concreteType, string resourcePath, List extraArgs); - - // Note: Any arguments that are used will be removed from extraArgs - object InstantiatePrefabResourceForComponentExplicit( - Type concreteType, string resourcePath, string groupName, InjectArgs args); + object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, + GameObjectCreationParameters gameObjectBindInfo, InjectArgs args); GameObject CreateEmptyGameObject(string name); #endif diff --git a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/IPrefabInstantiator.cs b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/IPrefabInstantiator.cs index 15f4ed28a..636d4eba6 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/IPrefabInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/IPrefabInstantiator.cs @@ -1,5 +1,6 @@ #if !NOT_UNITY3D +using System; using System.Collections.Generic; using UnityEngine; @@ -7,6 +8,11 @@ namespace Zenject { public interface IPrefabInstantiator { + Type ArgumentTarget + { + get; + } + List ExtraArguments { get; diff --git a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs index 358dc732b..f40d163b3 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs @@ -1,5 +1,6 @@ #if !NOT_UNITY3D +using System; using System.Collections.Generic; using System.Linq; using ModestTree; @@ -13,10 +14,12 @@ public class PrefabInstantiator : IPrefabInstantiator readonly DiContainer _container; readonly List _extraArguments; readonly GameObjectCreationParameters _gameObjectBindInfo; + readonly Type _argumentTarget; public PrefabInstantiator( DiContainer container, GameObjectCreationParameters gameObjectBindInfo, + Type argumentTarget, List extraArguments, IPrefabProvider prefabProvider) { @@ -24,6 +27,7 @@ public PrefabInstantiator( _extraArguments = extraArguments; _container = container; _gameObjectBindInfo = gameObjectBindInfo; + _argumentTarget = argumentTarget; } public GameObjectCreationParameters GameObjectCreationParameters @@ -31,6 +35,11 @@ public GameObjectCreationParameters GameObjectCreationParameters get { return _gameObjectBindInfo; } } + public Type ArgumentTarget + { + get { return _argumentTarget; } + } + public List ExtraArguments { get { return _extraArguments; } @@ -49,7 +58,31 @@ public IEnumerator Instantiate(List args) // Return it before inject so we can do circular dependencies yield return gameObject; - _container.InjectGameObjectExplicit(gameObject, _extraArguments.Concat(args).ToList()); + var allArgs = _extraArguments.Concat(args).ToList(); + + if (_argumentTarget == null) + { + Assert.That(allArgs.IsEmpty(), + "Unexpected arguments provided to prefab instantiator. Arguments are not allowed if binding multiple components in the same binding"); + } + + if (_argumentTarget == null || allArgs.IsEmpty()) + { + _container.InjectGameObject(gameObject); + } + else + { + var injectArgs = new InjectArgs() + { + ExtraArgs = allArgs, + UseAllArgs = true, + Context = new InjectContext(_container, _argumentTarget, null), + ConcreteIdentifier = null, + }; + + _container.InjectGameObjectForComponentExplicit( + gameObject, _argumentTarget, injectArgs); + } } } } diff --git a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiatorCached.cs b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiatorCached.cs index e99a9c26a..0caed8ed2 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiatorCached.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiatorCached.cs @@ -1,5 +1,6 @@ #if !NOT_UNITY3D +using System; using System.Collections.Generic; using ModestTree; using UnityEngine; @@ -22,6 +23,11 @@ public List ExtraArguments get { return _subInstantiator.ExtraArguments; } } + public Type ArgumentTarget + { + get { return _subInstantiator.ArgumentTarget; } + } + public GameObjectCreationParameters GameObjectCreationParameters { get { return _subInstantiator.GameObjectCreationParameters; } diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabResourceSingletonProviderCreator.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabResourceSingletonProviderCreator.cs index 2c4a32586..1f9648f70 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabResourceSingletonProviderCreator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabResourceSingletonProviderCreator.cs @@ -47,6 +47,7 @@ public IProvider CreateProvider( creator = new PrefabInstantiatorCached( new PrefabInstantiator( _container, gameObjectBindInfo, + resultType, extraArguments, new PrefabProviderResource(resourcePath))); diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabSingletonProviderCreator.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabSingletonProviderCreator.cs index 0d2fa22f4..7af62fe8e 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabSingletonProviderCreator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/Prefab/PrefabSingletonProviderCreator.cs @@ -47,7 +47,7 @@ public IProvider CreateProvider( { creator = new PrefabInstantiatorCached( new PrefabInstantiator( - _container, gameObjectBindInfo, extraArguments, new PrefabProvider(prefab))); + _container, gameObjectBindInfo, resultType, extraArguments, new PrefabProvider(prefab))); _prefabCreators.Add(prefabId, creator); } diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonProviderCreator.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonProviderCreator.cs index d5a18bcc0..23f322e98 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonProviderCreator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonProviderCreator.cs @@ -70,8 +70,7 @@ public IProvider CreateProviderForPrefabResource( List extraArguments, object concreteIdentifier) { return _prefabResourceProviderCreator.CreateProvider( - resourcePath, resultType, gameObjectBindInfo, - extraArguments, concreteIdentifier); + resourcePath, resultType, gameObjectBindInfo, extraArguments, concreteIdentifier); } public IProvider CreateProviderForSubContainerPrefab( diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs index 32db64804..99be2ec0f 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs @@ -25,8 +25,7 @@ public DiContainer CreateSubContainer(List args) Assert.That(args.IsEmpty()); var prefab = _prefabProvider.GetPrefab(); - var gameObject = _container.InstantiatePrefab( - prefab, new object[0], _gameObjectBindInfo); + var gameObject = _container.InstantiatePrefab(prefab, _gameObjectBindInfo); var context = gameObject.GetComponent(); diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs index b46931e06..45c4cc402 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs @@ -46,8 +46,7 @@ public DiContainer CreateSubContainer(List args) Assert.That(!args.IsEmpty()); var prefab = _prefabProvider.GetPrefab(); - var gameObject = CreateTempContainer(args).InstantiatePrefab( - prefab, new object[0], _gameObjectBindInfo); + var gameObject = CreateTempContainer(args).InstantiatePrefab(prefab, _gameObjectBindInfo); var context = gameObject.GetComponent(); diff --git a/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs b/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs index c7033667f..347a3d2bf 100644 --- a/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs +++ b/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs @@ -49,7 +49,7 @@ public static IEnumerable GetAllSceneContexts() } // NOTE: This method will not return components that are within a GameObjectContext - public static List GetInjectableComponents(GameObject gameObject) + public static List GetInjectableMonoBehaviours(GameObject gameObject) { var childMonoBehaviours = gameObject.GetComponentsInChildren(); @@ -68,10 +68,10 @@ public static List GetInjectableComponents(GameObject gameObject) .ToList(); } - public static IEnumerable GetInjectableComponents(Scene scene) + public static IEnumerable GetInjectableMonoBehaviours(Scene scene) { return GetRootGameObjects(scene) - .SelectMany(ZenUtilInternal.GetInjectableComponents); + .SelectMany(ZenUtilInternal.GetInjectableMonoBehaviours); } public static IEnumerable GetRootGameObjects(Scene scene) diff --git a/UnityProject/Assets/Zenject/Source/Zenject.csproj b/UnityProject/Assets/Zenject/Source/Zenject.csproj index ca17995b4..2e34a6606 100644 --- a/UnityProject/Assets/Zenject/Source/Zenject.csproj +++ b/UnityProject/Assets/Zenject/Source/Zenject.csproj @@ -77,9 +77,7 @@ - - @@ -135,7 +133,6 @@ - From 472bf78ffe768e09fabf4251b11fdb3b35b3c4e1 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Thu, 9 Feb 2017 00:12:24 -0400 Subject: [PATCH 35/62] Removed UnityEventManager since it isn't core to keep things lightweight --- .../Source/Runtime/UnityEventManager.cs | 150 ------------------ 1 file changed, 150 deletions(-) delete mode 100644 UnityProject/Assets/Zenject/Source/Runtime/UnityEventManager.cs diff --git a/UnityProject/Assets/Zenject/Source/Runtime/UnityEventManager.cs b/UnityProject/Assets/Zenject/Source/Runtime/UnityEventManager.cs deleted file mode 100644 index 0db7b2435..000000000 --- a/UnityProject/Assets/Zenject/Source/Runtime/UnityEventManager.cs +++ /dev/null @@ -1,150 +0,0 @@ -#if !NOT_UNITY3D - -using System; -using UnityEngine; - -namespace Zenject -{ - // Note: this corresponds to the values expected in - // Input.GetMouseButtonDown() and similar methods - public enum MouseButtons - { - None, - Left, - Right, - Middle, - } - - [System.Diagnostics.DebuggerStepThrough] - public class UnityEventManager : MonoBehaviour, ITickable - { - public event Action ApplicationGainedFocus = delegate { }; - public event Action ApplicationLostFocus = delegate { }; - public event Action ApplicationFocusChanged = delegate { }; - public event Action ApplicationQuit = delegate { }; - public event Action ChangingScenes = delegate { }; - public event Action DrawGizmos = delegate { }; - public event Action MouseButtonDown = delegate { }; - public event Action MouseButtonUp = delegate { }; - public event Action LeftMouseButtonDown = delegate { }; - public event Action LeftMouseButtonUp = delegate { }; - public event Action MiddleMouseButtonDown = delegate { }; - public event Action MiddleMouseButtonUp = delegate { }; - public event Action RightMouseButtonDown = delegate { }; - public event Action RightMouseButtonUp = delegate { }; - public event Action MouseMoved = delegate { }; - public event Action ScreenSizeChanged = delegate { }; - public event Action Started = delegate { }; - public event Action MouseWheelMoved = delegate { }; - - Vector3 _lastMousePosition; - - int _lastWidth; - int _lastHeight; - - public bool IsFocused - { - get; - private set; - } - - void Start() - { - _lastWidth = Screen.width; - _lastHeight = Screen.height; - Started(); - } - - public void Tick() - { - if (Input.GetMouseButtonDown((int)MouseButtons.Left)) - { - LeftMouseButtonDown(); - MouseButtonDown(MouseButtons.Left); - } - else if (Input.GetMouseButtonUp((int)MouseButtons.Left)) - { - LeftMouseButtonUp(); - MouseButtonUp(MouseButtons.Left); - } - - if (Input.GetMouseButtonDown((int)MouseButtons.Right)) - { - RightMouseButtonDown(); - MouseButtonDown(MouseButtons.Right); - } - else if (Input.GetMouseButtonUp((int)MouseButtons.Right)) - { - RightMouseButtonUp(); - MouseButtonUp(MouseButtons.Right); - } - - if (Input.GetMouseButtonDown((int)MouseButtons.Middle)) - { - MiddleMouseButtonDown(); - MouseButtonDown(MouseButtons.Middle); - } - else if (Input.GetMouseButtonUp((int)MouseButtons.Middle)) - { - MiddleMouseButtonUp(); - MouseButtonUp(MouseButtons.Middle); - } - - if (_lastMousePosition != Input.mousePosition) - { - _lastMousePosition = Input.mousePosition; - MouseMoved(); - } - - // By default this event returns 1/10 for each discrete rotation - // so correct that - var mouseWheelDelta = 10.0f * Input.GetAxis("Mouse ScrollWheel"); - - if (!Mathf.Approximately(mouseWheelDelta, 0)) - { - MouseWheelMoved(mouseWheelDelta); - } - - if (_lastWidth != Screen.width || _lastHeight != Screen.height) - { - _lastWidth = Screen.width; - _lastHeight = Screen.height; - ScreenSizeChanged(); - } - } - - void OnDestroy() - { - ChangingScenes(); - } - - void OnApplicationQuit() - { - ApplicationQuit(); - } - - void OnDrawGizmos() - { - DrawGizmos(); - } - - void OnApplicationFocus(bool newIsFocused) - { - if (newIsFocused && !IsFocused) - { - IsFocused = true; - ApplicationGainedFocus(); - ApplicationFocusChanged(true); - } - - if (!newIsFocused && IsFocused) - { - IsFocused = false; - ApplicationLostFocus(); - ApplicationFocusChanged(false); - } - } - } -} - -#endif From 36d2bf7de2fd029025c4cd3d995245141c195d8b Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Thu, 9 Feb 2017 22:34:30 -0400 Subject: [PATCH 36/62] - Renamed DynamicFactory to PlaceholderFactory - Added InstantiateScriptableObjectResource methods to create a scriptable object derived class from the resources folder re issue #127 - Added FromScriptableObject bind method. Changed FromResource to use Resolves.Load - Renamed FromNewSiblingComponent to FromNewComponentSibling - Added ability to require that the scope be explicitly set for some bind methods. Currently this is only used on - Fixed FromResource to return a set rather than always just one --- .../Bindings/Editor/TestDiContainerMethods.cs | 125 +++++- .../TestFromScriptableObjectResource.cs | 95 +++++ .../TestFromScriptableObjectResource.cs.meta} | 6 +- .../Editor/TestFromSiblingComponent.cs | 6 +- .../TestDiContainerMethods/Foo2.asset | 13 + .../TestDiContainerMethods/Foo2.asset.meta | 8 + .../TestDiContainerMethods/Gorp2.asset | 13 + .../TestDiContainerMethods/Gorp2.asset.meta | 8 + .../TestFromScriptableObjectResource.meta | 9 + .../Bob.asset | 13 + .../Bob.asset.meta | 8 + .../Foo.asset | 13 + .../Foo.asset.meta | 8 + .../Bindings/TestDiContainerMethods/Foo2.cs | 20 + .../TestDiContainerMethods/Foo2.cs.meta | 12 + .../Bindings/TestDiContainerMethods/Gorp2.cs | 26 ++ .../TestDiContainerMethods/Gorp2.cs.meta | 12 + .../TestFromScriptableObjectResource.meta | 9 + .../TestFromScriptableObjectResource/Bob.cs | 21 + .../Bob.cs.meta | 12 + .../TestFromScriptableObjectResource/Foo.cs | 31 ++ .../Foo.cs.meta | 12 + .../TestMultipleContractTypes2.cs | 18 + .../Source/Binding/BindInfo/BindInfo.cs | 9 +- .../Factory/DynamicFactoryBindingFinalizer.cs | 8 +- .../Binding/Binders/FromBinders/FromBinder.cs | 17 +- .../Zenject/Source/Binding/BindingUtil.cs | 19 + .../Finalizers/PrefabBindingFinalizer.cs | 4 +- .../PrefabResourceBindingFinalizer.cs | 4 +- .../Finalizers/ProviderBindingFinalizer.cs | 12 + .../Finalizers/ScopableBindingFinalizer.cs | 4 +- .../SubContainerInstallerBindingFinalizer.cs | 4 +- .../SubContainerMethodBindingFinalizer.cs | 4 +- .../SubContainerPrefabBindingFinalizer.cs | 4 +- ...ContainerPrefabResourceBindingFinalizer.cs | 4 +- .../Source/Factories/DynamicFactory.cs | 6 +- .../Zenject/Source/Factories/Factory.cs | 12 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 397 ++++++++++-------- .../Zenject/Source/Main/IInstantiator.cs | 56 +-- ...AddToCurrentGameObjectComponentProvider.cs | 3 +- .../AddToGameObjectComponentProviderBase.cs | 1 - .../PrefabCreators/PrefabInstantiator.cs | 1 - .../Source/Providers/ResourceProvider.cs | 8 +- .../ScriptableObjectResourceProvider.cs | 68 +++ .../ScriptableObjectResourceProvider.cs.meta | 12 + .../Providers/Singleton/SingletonTypes.cs | 1 + .../Source/Providers/TransientProvider.cs | 3 - 47 files changed, 902 insertions(+), 257 deletions(-) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromScriptableObjectResource.cs rename UnityProject/Assets/Zenject/{Source/Runtime/UnityEventManager.cs.meta => OptionalExtras/IntegrationTests/Bindings/Editor/TestFromScriptableObjectResource.cs.meta} (69%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo2.asset create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo2.asset.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp2.asset create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp2.asset.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Bob.asset create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Bob.asset.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Foo.asset create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Foo.asset.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo2.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo2.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp2.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp2.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Bob.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Bob.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Foo.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Foo.cs.meta create mode 100644 UnityProject/Assets/Zenject/Source/Providers/ScriptableObjectResourceProvider.cs create mode 100644 UnityProject/Assets/Zenject/Source/Providers/ScriptableObjectResourceProvider.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs index cc0f642ca..603b1c2e6 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs @@ -12,6 +12,8 @@ namespace Zenject.Tests.Bindings [TestFixture] public class TestDiContainerMethods : ZenjectIntegrationTestFixture { + const string ResourcePrefix = "TestDiContainerMethods/"; + GameObject FooPrefab { get { return GetPrefab("Foo"); } @@ -28,55 +30,55 @@ GameObject CameraPrefab } [Test] - public void InjectGameObject() + public void TestInstantiateComponent() { Initialize(); - var go = GameObject.Instantiate(FooPrefab); + var gameObject = new GameObject(); - var foo = go.GetComponentInChildren(); + var foo = Container.InstantiateComponent(gameObject); - Assert.That(!foo.WasInjected); - Container.InjectGameObject(go); Assert.That(foo.WasInjected); } [Test] - public void InjectGameObjectForMonoBehaviour() + public void TestInstantiateComponentArgs() { Initialize(); - var go = GameObject.Instantiate(GorpPrefab); + var gameObject = new GameObject(); - Assert.Throws(() => Container.InjectGameObject(go)); + Assert.Throws(() => Container.InstantiateComponent(gameObject)); - var gorp = Container.InjectGameObjectForComponent(go, new object[] { "asdf" }); + var gorp = Container.InstantiateComponent(gameObject, new object[] { "zxcv" }); - Assert.IsEqual(gorp.Arg, "asdf"); + Assert.IsEqual(gorp.Arg, "zxcv"); } [Test] - public void InjectGameObjectForComponent() + public void TestInstantiateComponentOnNewGameObject() { Initialize(); - var go = GameObject.Instantiate(CameraPrefab); + var foo = Container.InstantiateComponentOnNewGameObject(); - Container.InjectGameObjectForComponent(go, new object[0]); + Assert.That(foo.WasInjected); } [Test] - public void InjectGameObjectForComponentMistake() + public void TestInstantiateComponentOnNewGameObjectArgs() { Initialize(); - var go = GameObject.Instantiate(CameraPrefab); + Assert.Throws(() => Container.InstantiateComponentOnNewGameObject()); - Assert.Throws(() => Container.InjectGameObjectForComponent(go, new object[] { "sdf" })); + var gorp = Container.InstantiateComponentOnNewGameObject("sdf", new object[] { "zxcv" }); + + Assert.IsEqual(gorp.Arg, "zxcv"); } [Test] - public void InstantiatePrefab() + public void TestInstantiatePrefab() { Initialize(); @@ -88,7 +90,7 @@ public void InstantiatePrefab() } [Test] - public void InstantiatePrefabForMonoBehaviour() + public void TestInstantiatePrefabForMonoBehaviour() { Initialize(); @@ -100,7 +102,19 @@ public void InstantiatePrefabForMonoBehaviour() } [Test] - public void InstantiatePrefabForComponent() + public void TestInstantiatePrefabResource() + { + Initialize(); + + Assert.Throws(() => Container.InstantiatePrefabResource(ResourcePrefix + "Gorp")); + + var gorp = Container.InstantiatePrefabResourceForComponent(ResourcePrefix + "Gorp", new object[] { "asdf" }); + + Assert.IsEqual(gorp.Arg, "asdf"); + } + + [Test] + public void TestInstantiatePrefabForComponent() { Initialize(); @@ -109,16 +123,85 @@ public void InstantiatePrefabForComponent() } [Test] - public void InstantiatePrefabForComponentMistake() + public void TestInstantiatePrefabForComponentMistake() { Initialize(); Assert.Throws(() => Container.InstantiatePrefabForComponent(CameraPrefab, new object[] { "sdf" })); } + [Test] + public void TestInstantiateScriptableObjectResource() + { + Initialize(); + + var foo = Container.InstantiateScriptableObjectResource(ResourcePrefix + "Foo2"); + Assert.That(foo.WasInjected); + } + + [Test] + public void TestInstantiateScriptableObjectResourceArgs() + { + Initialize(); + + Assert.Throws(() => Container.InstantiateScriptableObjectResource(ResourcePrefix + "Gorp2")); + + var gorp = Container.InstantiateScriptableObjectResource(ResourcePrefix + "Gorp2", new object[] { "asdf" }); + + Assert.IsEqual(gorp.Arg, "asdf"); + } + + [Test] + public void TestInjectGameObject() + { + Initialize(); + + var go = GameObject.Instantiate(FooPrefab); + + var foo = go.GetComponentInChildren(); + + Assert.That(!foo.WasInjected); + Container.InjectGameObject(go); + Assert.That(foo.WasInjected); + } + + [Test] + public void TestInjectGameObjectForMonoBehaviour() + { + Initialize(); + + var go = GameObject.Instantiate(GorpPrefab); + + Assert.Throws(() => Container.InjectGameObject(go)); + + var gorp = Container.InjectGameObjectForComponent(go, new object[] { "asdf" }); + + Assert.IsEqual(gorp.Arg, "asdf"); + } + + [Test] + public void TestInjectGameObjectForComponent() + { + Initialize(); + + var go = GameObject.Instantiate(CameraPrefab); + + Container.InjectGameObjectForComponent(go, new object[0]); + } + + [Test] + public void TestInjectGameObjectForComponentMistake() + { + Initialize(); + + var go = GameObject.Instantiate(CameraPrefab); + + Assert.Throws(() => Container.InjectGameObjectForComponent(go, new object[] { "sdf" })); + } + GameObject GetPrefab(string name) { - return FixtureUtil.GetPrefab("TestDiContainerMethods/{0}".Fmt(name)); + return FixtureUtil.GetPrefab(ResourcePrefix + name); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromScriptableObjectResource.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromScriptableObjectResource.cs new file mode 100644 index 000000000..852be6ac7 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromScriptableObjectResource.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject.Tests.Bindings.FromScriptableObjectResource; + +namespace Zenject.Tests.Bindings +{ + [TestFixture] + public class TestFromScriptableObjectResource : ZenjectIntegrationTestFixture + { + const string PathPrefix = "TestFromScriptableObjectResource/"; + + [Test] + [ExpectedException] + public void TestTransientError() + { + // Validation should detect that it doesn't exist + Container.Bind().FromScriptableObjectResource(PathPrefix + "asdfasdfas").AsTransient().NonLazy(); + + Initialize(); + } + + [Test] + public void TestTransient() + { + Foo.InstanceCount = 0; + Container.Bind().FromScriptableObjectResource(PathPrefix + "Foo").AsTransient(); + + Initialize(); + + var foo = Container.Resolve(); + Assert.That(foo.WasInjected); + + Assert.IsEqual(Foo.InstanceCount, 1); + + var foo2 = Container.Resolve(); + Assert.IsNotEqual(foo, foo2); + Assert.IsEqual(Foo.InstanceCount, 2); + } + + [Test] + public void TestSingle() + { + Foo.InstanceCount = 0; + + Container.Bind().To().FromScriptableObjectResource(PathPrefix + "Foo").AsSingle(); + Container.Bind().FromScriptableObjectResource(PathPrefix + "Foo").AsSingle(); + + Initialize(); + + var ifoo = Container.Resolve(); + Assert.IsEqual(Foo.InstanceCount, 1); + } + + [Test] + public void TestAbstractBinding() + { + Foo.InstanceCount = 0; + + Container.Bind().To() + .FromScriptableObjectResource(PathPrefix + "Foo").AsSingle().NonLazy(); + + Initialize(); + + var foo = Container.Resolve(); + Assert.IsEqual(Foo.InstanceCount, 1); + } + + [Test] + [ExpectedException] + public void TestWithArgumentsFail() + { + Container.Bind() + .FromScriptableObjectResource(PathPrefix + "Bob").AsCached().NonLazy(); + + Initialize(); + } + + [Test] + public void TestWithArguments() + { + Container.Bind() + .FromScriptableObjectResource(PathPrefix + "Bob").AsCached() + .WithArguments("test1").NonLazy(); + + Initialize(); + + Assert.IsEqual(Container.Resolve().Arg, "test1"); + } + } +} diff --git a/UnityProject/Assets/Zenject/Source/Runtime/UnityEventManager.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromScriptableObjectResource.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Runtime/UnityEventManager.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromScriptableObjectResource.cs.meta index 9d60af0cb..958347101 100644 --- a/UnityProject/Assets/Zenject/Source/Runtime/UnityEventManager.cs.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromScriptableObjectResource.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 57c53ca56dbd4ea4daba605f70d72516 -timeCreated: 1461708050 -licenseType: Pro +guid: b760c07c630a59e4099fd50681d354c4 +timeCreated: 1486615351 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSiblingComponent.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSiblingComponent.cs index 4aea13734..30a56d825 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSiblingComponent.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSiblingComponent.cs @@ -15,7 +15,7 @@ public class TestFromSiblingComponent : ZenjectIntegrationTestFixture public void TestBasic() { Container.Bind().FromNewComponentOnNewGameObject().AsSingle().NonLazy(); - Container.Bind().FromNewSiblingComponent(); + Container.Bind().FromNewComponentSibling(); Initialize(); @@ -27,7 +27,7 @@ public void TestBasic() public void TestInvalidUse() { Container.Bind().NonLazy(); - Container.Bind().FromNewSiblingComponent(); + Container.Bind().FromNewComponentSibling(); Initialize(); } @@ -40,7 +40,7 @@ public void TestBasic2() Container.Bind().FromNewComponentOn(gameObject).AsSingle().NonLazy(); Container.Bind().FromNewComponentOn(gameObject).AsSingle().NonLazy(); - Container.Bind().FromNewSiblingComponent(); + Container.Bind().FromNewComponentSibling(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo2.asset b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo2.asset new file mode 100644 index 000000000..eeddf230a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo2.asset @@ -0,0 +1,13 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2fb66836df088014081bc2f5740ecea1, type: 3} + m_Name: Foo2 + m_EditorClassIdentifier: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo2.asset.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo2.asset.meta new file mode 100644 index 000000000..6e8398207 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Foo2.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0b8ab53bbd8332e429a6f0ed1dd3fe16 +timeCreated: 1486678058 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp2.asset b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp2.asset new file mode 100644 index 000000000..d00f5b92a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp2.asset @@ -0,0 +1,13 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 952b7cab572c9c24cb1e7ca240e67c84, type: 3} + m_Name: Gorp2 + m_EditorClassIdentifier: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp2.asset.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp2.asset.meta new file mode 100644 index 000000000..44bfba9c2 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestDiContainerMethods/Gorp2.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: de8d2dce06221cc4cb9fa957aebc8f15 +timeCreated: 1486678064 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource.meta new file mode 100644 index 000000000..80c818fe3 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 100ccadd1fc02a94da96013a3d7caea9 +folderAsset: yes +timeCreated: 1486616185 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Bob.asset b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Bob.asset new file mode 100644 index 000000000..8f49fc02b --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Bob.asset @@ -0,0 +1,13 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9e40755b32ffa6f4fb5f67e0612fc480, type: 3} + m_Name: Bob + m_EditorClassIdentifier: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Bob.asset.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Bob.asset.meta new file mode 100644 index 000000000..cd52f6eae --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Bob.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d45f0a8bee35032448f068189a46e207 +timeCreated: 1486670371 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Foo.asset b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Foo.asset new file mode 100644 index 000000000..0ab1870b6 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Foo.asset @@ -0,0 +1,13 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 70da936d4db31fa4a9f79f7af7604209, type: 3} + m_Name: Foo + m_EditorClassIdentifier: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Foo.asset.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Foo.asset.meta new file mode 100644 index 000000000..3655fae5d --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Resources/TestFromScriptableObjectResource/Foo.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dff7f713b1f7d8041a8e5a3943ef38b3 +timeCreated: 1486616271 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo2.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo2.cs new file mode 100644 index 000000000..714483896 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo2.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +namespace Zenject.Tests.Bindings.DiContainerMethods +{ + [CreateAssetMenu(fileName = "Foo2", menuName = "Test/Foo2")] + public class Foo2 : ScriptableObject + { + public bool WasInjected + { + get; + private set; + } + + [Inject] + public void Construct() + { + WasInjected = true; + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo2.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo2.cs.meta new file mode 100644 index 000000000..31bb58276 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Foo2.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2fb66836df088014081bc2f5740ecea1 +timeCreated: 1486677525 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp2.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp2.cs new file mode 100644 index 000000000..979658b7f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp2.cs @@ -0,0 +1,26 @@ +using ModestTree; +using UnityEngine; +using Zenject; + +#pragma warning disable 649 + +namespace Zenject.Tests.Bindings.DiContainerMethods +{ + [CreateAssetMenu(fileName = "Gorp2", menuName = "Test/Gorp2")] + public class Gorp2 : ScriptableObject + { + [Inject] + string _arg; + + public string Arg + { + get { return _arg; } + } + + [Inject] + public void Initialize() + { + Log.Trace("Received arg '{0}' in Gorp", _arg); + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp2.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp2.cs.meta new file mode 100644 index 000000000..133603380 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestDiContainerMethods/Gorp2.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 952b7cab572c9c24cb1e7ca240e67c84 +timeCreated: 1486677525 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource.meta new file mode 100644 index 000000000..ad6856c1f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 134a0699360dfc048a5e501f7893b6ce +folderAsset: yes +timeCreated: 1486615350 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Bob.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Bob.cs new file mode 100644 index 000000000..ab8d71594 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Bob.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +namespace Zenject.Tests.Bindings.FromScriptableObjectResource +{ + //[CreateAssetMenu(fileName = "Bob", menuName = "Test/Bob")] + public class Bob : ScriptableObject + { + public string Arg + { + get; + private set; + } + + [Inject] + public void Construct(string arg) + { + Arg = arg; + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Bob.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Bob.cs.meta new file mode 100644 index 000000000..9ac74235f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Bob.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9e40755b32ffa6f4fb5f67e0612fc480 +timeCreated: 1486670038 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Foo.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Foo.cs new file mode 100644 index 000000000..d1f55b9a5 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Foo.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +namespace Zenject.Tests.Bindings.FromScriptableObjectResource +{ + public interface IFoo + { + } + + //[CreateAssetMenu(fileName = "Foo", menuName = "Test/Foo")] + public class Foo : ScriptableObject, IFoo + { + public static int InstanceCount + { + get; + set; + } + + public bool WasInjected + { + get; + private set; + } + + [Inject] + public void Construct() + { + WasInjected = true; + InstanceCount++; + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Foo.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Foo.cs.meta new file mode 100644 index 000000000..892084020 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/TestFromScriptableObjectResource/Foo.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 70da936d4db31fa4a9f79f7af7604209 +timeCreated: 1486615350 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs index 975456d4f..1bf14ca18 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs @@ -50,6 +50,15 @@ public void TestInterfaces() Container.Resolve(); } + [Test] + public void TestAllInterfacesMistake() + { + Container.BindInterfacesTo(); + + // Should require setting scope + Assert.Throws(() => Container.FlushBindings()); + } + [Test] public void TestAllInterfaces() { @@ -69,6 +78,15 @@ public void TestAllInterfacesAndSelf() Assert.IsNotNull(Container.Resolve()); Assert.IsNotNull(Container.Resolve()); } + + [Test] + public void TestAllInterfacesAndSelfMistake() + { + Container.BindInterfacesToSelf(); + + // Should require setting scope + Assert.Throws(() => Container.FlushBindings()); + } } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/BindInfo.cs b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/BindInfo.cs index ec36b8ecd..8072d63a3 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/BindInfo.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/BindInfo.cs @@ -5,6 +5,7 @@ namespace Zenject { public enum ScopeTypes { + Unset, Transient, Singleton, Cached, @@ -34,7 +35,7 @@ public BindInfo(List contractTypes, string contextInfo) ToChoice = ToChoices.Self; CopyIntoAllSubContainers = false; NonLazy = false; - Scope = ScopeTypes.Transient; + Scope = ScopeTypes.Unset; InvalidBindResponse = InvalidBindResponses.Assert; } @@ -59,6 +60,12 @@ public string ContextInfo private set; } + public bool RequireExplicitScope + { + get; + set; + } + public object Identifier { get; diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs index 30a414506..439f6f11e 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs @@ -3,17 +3,17 @@ namespace Zenject { - public class DynamicFactoryBindingFinalizer : ProviderBindingFinalizer + public class PlaceholderFactoryBindingFinalizer : ProviderBindingFinalizer { readonly FactoryBindInfo _factoryBindInfo; - public DynamicFactoryBindingFinalizer( + public PlaceholderFactoryBindingFinalizer( BindInfo bindInfo, FactoryBindInfo factoryBindInfo) : base(bindInfo) { // Note that it doesn't derive from Factory - // when used with To<>, so we can only check IDynamicFactory - Assert.That(factoryBindInfo.FactoryType.DerivesFrom()); + // when used with To<>, so we can only check IPlaceholderFactory + Assert.That(factoryBindInfo.FactoryType.DerivesFrom()); _factoryBindInfo = factoryBindInfo; } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index 60b619783..37b54e441 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -115,7 +115,7 @@ public ScopeArgConditionCopyNonLazyBinder FromNewComponentOn(GameObject gameObje return new ScopeArgConditionCopyNonLazyBinder(BindInfo); } - public ArgConditionCopyNonLazyBinder FromNewSiblingComponent() + public ArgConditionCopyNonLazyBinder FromNewComponentSibling() { BindingUtil.AssertIsComponent(ConcreteTypes); BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); @@ -185,6 +185,21 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefabReso return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } + public ScopeArgConditionCopyNonLazyBinder FromScriptableObjectResource(string resourcePath) + { + BindingUtil.AssertIsValidResourcePath(resourcePath); + BindingUtil.AssertIsInterfaceOrScriptableObject(AllParentTypes); + + SubFinalizer = new ScopableBindingFinalizer( + BindInfo, + SingletonTypes.FromScriptableObjectResource, + resourcePath.ToLower(), + (container, type) => new ScriptableObjectResourceProvider( + resourcePath, type, container, BindInfo.ConcreteIdentifier, BindInfo.Arguments)); + + return new ScopeArgConditionCopyNonLazyBinder(BindInfo); + } + public ScopeConditionCopyNonLazyBinder FromResource(string resourcePath) { BindingUtil.AssertDerivesFromUnityObject(ConcreteTypes); diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs b/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs index da50a37d2..acff1d162 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/BindingUtil.cs @@ -94,6 +94,25 @@ public static void AssertIsValidResourcePath(string resourcePath) // a way to do this besides loading it } + public static void AssertIsInterfaceOrScriptableObject(IEnumerable types) + { + foreach (var type in types) + { + AssertIsInterfaceOrScriptableObject(type); + } + } + + public static void AssertIsInterfaceOrScriptableObject() + { + AssertIsInterfaceOrScriptableObject(typeof(T)); + } + + public static void AssertIsInterfaceOrScriptableObject(Type type) + { + Assert.That(type.DerivesFrom(typeof(ScriptableObject)) || type.IsInterface(), + "Invalid type given during bind command. Expected type '{0}' to either derive from UnityEngine.ScriptableObject or be an interface", type); + } + public static void AssertIsInterfaceOrComponent(IEnumerable types) { foreach (var type in types) diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs index 18eaa2d79..f166e3a05 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabBindingFinalizer.cs @@ -46,7 +46,7 @@ IProvider CreateProviderForType( void FinalizeBindingConcrete(DiContainer container, List concreteTypes) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { @@ -111,7 +111,7 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) void FinalizeBindingSelf(DiContainer container) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs index f848ed116..078b8a098 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/PrefabResourceBindingFinalizer.cs @@ -46,7 +46,7 @@ IProvider CreateProviderForType( void FinalizeBindingConcrete(DiContainer container, List concreteTypes) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { @@ -111,7 +111,7 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) void FinalizeBindingSelf(DiContainer container) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs index 0c38187ea..101c4d8ea 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs @@ -23,6 +23,18 @@ protected BindInfo BindInfo private set; } + protected ScopeTypes GetScope() + { + if (BindInfo.Scope == ScopeTypes.Unset) + { + Assert.That(!BindInfo.RequireExplicitScope, + "Scope must be set for the given binding {0}! Please either specify AsTransient, AsCached, or AsSingle.", BindInfo.ContextInfo ?? ""); + return ScopeTypes.Transient; + } + + return BindInfo.Scope; + } + public void FinalizeBinding(DiContainer container) { if (BindInfo.ContractTypes.IsEmpty()) diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ScopableBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ScopableBindingFinalizer.cs index 0d40cf942..5e8bda388 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ScopableBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ScopableBindingFinalizer.cs @@ -42,7 +42,7 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) return; } - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { @@ -84,7 +84,7 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) void FinalizeBindingSelf(DiContainer container) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerInstallerBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerInstallerBindingFinalizer.cs index 91fc1fc32..3a62661a2 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerInstallerBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerInstallerBindingFinalizer.cs @@ -38,7 +38,7 @@ ISubContainerCreator CreateContainerCreator(DiContainer container) void FinalizeBindingConcrete(DiContainer container, List concreteTypes) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { @@ -81,7 +81,7 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) void FinalizeBindingSelf(DiContainer container) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerMethodBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerMethodBindingFinalizer.cs index a453de4bc..b7f1d6d03 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerMethodBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerMethodBindingFinalizer.cs @@ -32,7 +32,7 @@ protected override void OnFinalizeBinding(DiContainer container) void FinalizeBindingConcrete(DiContainer container, List concreteTypes) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { @@ -80,7 +80,7 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) void FinalizeBindingSelf(DiContainer container) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabBindingFinalizer.cs index ecd19b4b7..041149d3a 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabBindingFinalizer.cs @@ -39,7 +39,7 @@ protected override void OnFinalizeBinding(DiContainer container) void FinalizeBindingConcrete(DiContainer container, List concreteTypes) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { @@ -88,7 +88,7 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) void FinalizeBindingSelf(DiContainer container) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabResourceBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabResourceBindingFinalizer.cs index a207c8d30..f6371060b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabResourceBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabResourceBindingFinalizer.cs @@ -39,7 +39,7 @@ protected override void OnFinalizeBinding(DiContainer container) void FinalizeBindingConcrete(DiContainer container, List concreteTypes) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { @@ -87,7 +87,7 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) void FinalizeBindingSelf(DiContainer container) { - switch (BindInfo.Scope) + switch (GetScope()) { case ScopeTypes.Singleton: { diff --git a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs index 8438a6c17..e7e04df3d 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs @@ -5,12 +5,12 @@ namespace Zenject { - public interface IDynamicFactory : IValidatable + public interface IPlaceholderFactory : IValidatable { } - // Dynamic factories can be used to choose a creation method in an installer, using FactoryBinder - public abstract class DynamicFactory : IDynamicFactory + // Placeholder factories can be used to choose a creation method in an installer, using FactoryBinder + public abstract class PlaceholderFactory : IPlaceholderFactory { IProvider _provider; InjectContext _injectContext; diff --git a/UnityProject/Assets/Zenject/Source/Factories/Factory.cs b/UnityProject/Assets/Zenject/Source/Factories/Factory.cs index ce716be7d..5fa042e2d 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Factory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Factory.cs @@ -4,7 +4,7 @@ namespace Zenject { // Zero parameters - public class Factory : DynamicFactory, IFactory + public class Factory : PlaceholderFactory, IFactory { // If you were hoping to override this method, use BindFactory<>.ToFactory instead public TValue Create() @@ -20,7 +20,7 @@ protected sealed override IEnumerable ParamTypes // One parameter public class Factory - : DynamicFactory, IFactory + : PlaceholderFactory, IFactory { // If you were hoping to override this method, use BindFactory<>.ToFactory instead public TValue Create(TParam1 param) @@ -40,7 +40,7 @@ protected sealed override IEnumerable ParamTypes // Two parameters public class Factory - : DynamicFactory, IFactory + : PlaceholderFactory, IFactory { // If you were hoping to override this method, use BindFactory<>.ToFactory instead public TValue Create(TParam1 param1, TParam2 param2) @@ -65,7 +65,7 @@ protected sealed override IEnumerable ParamTypes // Three parameters public class Factory - : DynamicFactory, IFactory + : PlaceholderFactory, IFactory { // If you were hoping to override this method, use BindFactory<>.ToFactory instead public TValue Create(TParam1 param1, TParam2 param2, TParam3 param3) @@ -92,7 +92,7 @@ protected sealed override IEnumerable ParamTypes // Four parameters public class Factory - : DynamicFactory, IFactory + : PlaceholderFactory, IFactory { // If you were hoping to override this method, use BindFactory<>.ToFactory instead public TValue Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) @@ -121,7 +121,7 @@ protected sealed override IEnumerable ParamTypes // Five parameters public class Factory - : DynamicFactory, IFactory + : PlaceholderFactory, IFactory { // If you were hoping to override this method, use BindFactory<>.ToFactory instead public TValue Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5) diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index a18b98ea0..ef3c57adb 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -17,7 +17,6 @@ namespace Zenject public class InjectArgs { public List ExtraArgs; - public bool UseAllArgs; public InjectContext Context; public object ConcreteIdentifier; } @@ -808,12 +807,13 @@ object InstantiateInternal(Type concreteType, bool autoInject, InjectArgs args) if (autoInject) { InjectExplicit(newObj, concreteType, args); - } - else if (args.UseAllArgs && !args.ExtraArgs.IsEmpty()) - { - throw Assert.CreateException( - "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}", - newObj.GetType(), String.Join(",", args.ExtraArgs.Select(x => x.Type.Name()).ToArray()), args.Context.GetObjectGraphString()); + + if (!args.ExtraArgs.IsEmpty()) + { + throw Assert.CreateException( + "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}", + newObj.GetType(), String.Join(",", args.ExtraArgs.Select(x => x.Type.Name()).ToArray()), args.Context.GetObjectGraphString()); + } } return newObj; @@ -841,7 +841,6 @@ public void InjectExplicit(object injectable, List extraArgs) new InjectArgs() { ExtraArgs = extraArgs, - UseAllArgs = true, Context = new InjectContext(this, injectableType, null), ConcreteIdentifier = null, }); @@ -952,7 +951,7 @@ public void InjectExplicit( } } - if (args.UseAllArgs && !args.ExtraArgs.IsEmpty()) + if (!args.ExtraArgs.IsEmpty()) { throw Assert.CreateException( "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}", @@ -1116,37 +1115,6 @@ public object Instantiate( concreteType, InjectUtil.CreateArgList(extraArgs)); } - public T InstantiateExplicit(List extraArgs) - { - return (T)InstantiateExplicit(typeof(T), extraArgs); - } - - public object InstantiateExplicit(Type concreteType, List extraArgs) - { - bool autoInject = true; - - return InstantiateExplicit( - concreteType, - autoInject, - new InjectArgs() - { - ExtraArgs = extraArgs, - Context = new InjectContext(this, concreteType, null), - ConcreteIdentifier = null, - UseAllArgs = true, - }); - } - - public object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs args) - { -#if UNITY_EDITOR - using (ProfileBlock.Start("Zenject.Instantiate({0})", concreteType)) -#endif - { - return InstantiateInternal(concreteType, autoInject, args); - } - } - #if !NOT_UNITY3D // Add new component to existing game object and fill in its dependencies // This is the same as AddComponent except the [Inject] fields will be filled in @@ -1192,23 +1160,25 @@ public T InstantiateComponentOnNewGameObject() return InstantiateComponentOnNewGameObject(typeof(T).Name); } - public T InstantiateComponentOnNewGameObject(string gameObjectName) + public T InstantiateComponentOnNewGameObject(IEnumerable extraArgs) where T : Component { - return InstantiateComponent( - CreateEmptyGameObject(new GameObjectCreationParameters() { Name = gameObjectName })); + return InstantiateComponentOnNewGameObject(typeof(T).Name, extraArgs); } - public Component InstantiateComponentExplicit( - Type componentType, GameObject gameObject, List extraArgs) + public T InstantiateComponentOnNewGameObject(string gameObjectName) + where T : Component { - Assert.That(componentType.DerivesFrom()); - - FlushBindings(); + return InstantiateComponentOnNewGameObject(gameObjectName, new object[0]); + } - var monoBehaviour = (Component)gameObject.AddComponent(componentType); - InjectExplicit(monoBehaviour, extraArgs); - return monoBehaviour; + public T InstantiateComponentOnNewGameObject( + string gameObjectName, IEnumerable extraArgs) + where T : Component + { + return InstantiateComponent( + CreateEmptyGameObject(new GameObjectCreationParameters() { Name = gameObjectName }), + extraArgs); } // Create a new game object from a prefab and fill in dependencies for all children @@ -1309,112 +1279,33 @@ public object InstantiatePrefabResourceForComponent( concreteType, resourcePath, InjectUtil.CreateArgList(extraArgs)); } - // Same as InstantiatePrefabResourceForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public T InstantiatePrefabResourceForComponentExplicit( - string resourcePath, List extraArgs) - { - return (T)InstantiatePrefabResourceForComponentExplicit( - typeof(T), resourcePath, extraArgs); - } - - // Same as InstantiatePrefabResourceForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public object InstantiatePrefabResourceForComponentExplicit( - Type componentType, string resourcePath, List extraArgs) - { - return InstantiatePrefabResourceForComponentExplicit( - componentType, resourcePath, null, - new InjectArgs() - { - ExtraArgs = extraArgs, - Context = new InjectContext(this, componentType, null), - ConcreteIdentifier = null, - UseAllArgs = true, - }); - } - - - // Same as InstantiatePrefabResourceForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public object InstantiatePrefabResourceForComponentExplicit( - Type componentType, string resourcePath, string groupName, InjectArgs args) - { - var prefab = (GameObject)Resources.Load(resourcePath); - Assert.IsNotNull(prefab, - "Could not find prefab at resource location '{0}'".Fmt(resourcePath)); - return InstantiatePrefabForComponentExplicit( - componentType, prefab, groupName, args); - } - - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public T InstantiatePrefabForComponentExplicit( - UnityEngine.Object prefab, List extraArgs) + public T InstantiateScriptableObjectResource(string resourcePath) + where T : ScriptableObject { - return (T)InstantiatePrefabForComponentExplicit( - typeof(T), prefab, extraArgs); + return InstantiateScriptableObjectResource(resourcePath, new object[0]); } - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, List extraArgs) - { - return InstantiatePrefabForComponentExplicit( - componentType, prefab, extraArgs, null); - } - - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, List extraArgs, - string groupName) + public T InstantiateScriptableObjectResource( + string resourcePath, IEnumerable extraArgs) + where T : ScriptableObject { - return InstantiatePrefabForComponentExplicit( - componentType, prefab, groupName, - new InjectArgs() - { - ExtraArgs = extraArgs, - Context = new InjectContext(this, componentType, null), - ConcreteIdentifier = null, - UseAllArgs = true, - }); + return (T)InstantiateScriptableObjectResource( + typeof(T), resourcePath, extraArgs); } - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, string groupName, InjectArgs args) + public object InstantiateScriptableObjectResource( + Type scriptableObjectType, string resourcePath) { - return InstantiatePrefabForComponentExplicit( - componentType, prefab, new GameObjectCreationParameters() { GroupName = groupName }, args); + return InstantiateScriptableObjectResource( + scriptableObjectType, resourcePath, new object[0]); } - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, - GameObjectCreationParameters gameObjectBindInfo, InjectArgs args) + public object InstantiateScriptableObjectResource( + Type scriptableObjectType, string resourcePath, IEnumerable extraArgs) { - Assert.That(!AssertOnNewGameObjects, - "Given DiContainer does not support creating new game objects"); - - FlushBindings(); - - Assert.That(prefab != null, "Null prefab found when instantiating game object"); - - Assert.That(componentType.IsInterface() || componentType.DerivesFrom(), - "Expected type '{0}' to derive from UnityEngine.Component", componentType); - - GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); - - var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); - - gameObj.transform.SetParent(GetTransformGroup(gameObjectBindInfo), false); - - return InjectGameObjectForComponentExplicit( - gameObj, componentType, args); + Assert.DerivesFromOrEqual(scriptableObjectType); + return InstantiateScriptableObjectResourceExplicit( + scriptableObjectType, resourcePath, InjectUtil.CreateArgList(extraArgs)); } // Inject dependencies into any and all child components on the given game object @@ -1460,7 +1351,6 @@ public object InjectGameObjectForComponent( ExtraArgs = InjectUtil.CreateArgList(extraArgs), Context = new InjectContext(this, componentType, null), ConcreteIdentifier = null, - UseAllArgs = true, }); } @@ -1727,7 +1617,7 @@ public ConcreteIdBinderGeneric Bind() public ConcreteIdBinderGeneric Bind(BindInfo bindInfo) { - Assert.That(!typeof(TContract).DerivesFrom(), + Assert.That(!typeof(TContract).DerivesFrom(), "You should not use Container.Bind for factory classes. Use Container.BindFactory instead."); Assert.That(bindInfo.ContractTypes.Contains(typeof(TContract))); @@ -1750,11 +1640,15 @@ public ConcreteIdBinderNonGeneric Bind(IEnumerable contractTypes) ConcreteIdBinderNonGeneric BindInternal( IEnumerable contractTypes, string contextInfo) { - var contractTypesList = contractTypes.ToList(); - Assert.That(contractTypesList.All(x => !x.DerivesFrom()), + return BindInternal( + new BindInfo(contractTypes.ToList(), contextInfo)); + } + + ConcreteIdBinderNonGeneric BindInternal(BindInfo bindInfo) + { + Assert.That(bindInfo.ContractTypes.All(x => !x.DerivesFrom()), "You should not use Container.Bind for factory classes. Use Container.BindFactory instead."); - var bindInfo = new BindInfo(contractTypesList, contextInfo); return new ConcreteIdBinderNonGeneric(bindInfo, StartBinding()); } @@ -1767,7 +1661,7 @@ public ConcreteIdBinderNonGeneric Bind( var contractTypesList = conventionBindInfo.ResolveTypes(); - Assert.That(contractTypesList.All(x => !x.DerivesFrom()), + Assert.That(contractTypesList.All(x => !x.DerivesFrom()), "You should not use Container.Bind for factory classes. Use Container.BindFactory instead."); var bindInfo = new BindInfo(contractTypesList); @@ -1825,9 +1719,12 @@ public FromBinderNonGeneric BindInterfacesTo() public FromBinderNonGeneric BindInterfacesTo(Type type) { - // We must only have one dependency root per container - // We need this when calling this with a GameObjectContext - return BindInternal(type.Interfaces().ToArray(), "BindInterfacesTo({0})".Fmt(type)).To(type); + var bindInfo = new BindInfo( + type.Interfaces().ToList(), "BindInterfacesTo({0})".Fmt(type)); + + // Almost always, you don't want to use the default AsTransient so make them type it + bindInfo.RequireExplicitScope = true; + return BindInternal(bindInfo).To(type); } // Same as BindInterfaces except also binds to self @@ -1838,10 +1735,12 @@ public FromBinderNonGeneric BindInterfacesAndSelfTo() public FromBinderNonGeneric BindInterfacesAndSelfTo(Type type) { - // We must only have one dependency root per container - // We need this when calling this with a GameObjectContext - return Bind( - type.Interfaces().Append(type).ToArray()).To(type); + var bindInfo = new BindInfo( + type.Interfaces().Append(type).ToList(), "BindInterfacesAndSelfTo({0})".Fmt(type)); + + // Almost always, you don't want to use the default AsTransient so make them type it + bindInfo.RequireExplicitScope = true; + return BindInternal(bindInfo).To(type); } // This is simply a shortcut to using the FromInstance method. @@ -1883,7 +1782,7 @@ FactoryToChoiceIdBinder BindFactoryInternal( + StartBinding().SubFinalizer = new PlaceholderFactoryBindingFinalizer( bindInfo, factoryBindInfo); return new FactoryToChoiceIdBinder( @@ -1935,7 +1834,7 @@ FactoryToChoiceIdBinder BindFactoryInternal( + StartBinding().SubFinalizer = new PlaceholderFactoryBindingFinalizer( bindInfo, factoryBindInfo); return new FactoryToChoiceIdBinder( @@ -1962,7 +1861,7 @@ FactoryToChoiceIdBinder BindFactoryInternal( + StartBinding().SubFinalizer = new PlaceholderFactoryBindingFinalizer( bindInfo, factoryBindInfo); return new FactoryToChoiceIdBinder( @@ -1989,7 +1888,7 @@ FactoryToChoiceIdBinder BindFactoryInterna var bindInfo = new BindInfo(typeof(TFactoryContract)); var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); - StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + StartBinding().SubFinalizer = new PlaceholderFactoryBindingFinalizer( bindInfo, factoryBindInfo); return new FactoryToChoiceIdBinder( @@ -2016,7 +1915,7 @@ FactoryToChoiceIdBinder BindFacto var bindInfo = new BindInfo(typeof(TFactoryContract)); var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); - StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + StartBinding().SubFinalizer = new PlaceholderFactoryBindingFinalizer( bindInfo, factoryBindInfo); return new FactoryToChoiceIdBinder( @@ -2043,7 +1942,7 @@ FactoryToChoiceIdBinder var bindInfo = new BindInfo(typeof(TFactoryContract)); var factoryBindInfo = new FactoryBindInfo(typeof(TFactoryConcrete)); - StartBinding().SubFinalizer = new DynamicFactoryBindingFinalizer( + StartBinding().SubFinalizer = new PlaceholderFactoryBindingFinalizer( bindInfo, factoryBindInfo); return new FactoryToChoiceIdBinder( @@ -2063,6 +1962,172 @@ public FactoryToChoiceIdBinder(); } + public T InstantiateExplicit(List extraArgs) + { + return (T)InstantiateExplicit(typeof(T), extraArgs); + } + + public object InstantiateExplicit(Type concreteType, List extraArgs) + { + bool autoInject = true; + + return InstantiateExplicit( + concreteType, + autoInject, + new InjectArgs() + { + ExtraArgs = extraArgs, + Context = new InjectContext(this, concreteType, null), + ConcreteIdentifier = null, + }); + } + + public object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs args) + { +#if UNITY_EDITOR + using (ProfileBlock.Start("Zenject.Instantiate({0})", concreteType)) +#endif + { + return InstantiateInternal(concreteType, autoInject, args); + } + } + + public Component InstantiateComponentExplicit( + Type componentType, GameObject gameObject, List extraArgs) + { + Assert.That(componentType.DerivesFrom()); + + FlushBindings(); + + var monoBehaviour = (Component)gameObject.AddComponent(componentType); + InjectExplicit(monoBehaviour, extraArgs); + return monoBehaviour; + } + + public object InstantiateScriptableObjectResourceExplicit( + Type scriptableObjectType, string resourcePath, List extraArgs) + { + var objects = Resources.LoadAll(resourcePath, scriptableObjectType); + + Assert.That(!objects.IsEmpty(), + "Could not find resource at path '{0}' with type '{1}'", resourcePath, scriptableObjectType); + + Assert.That(objects.Length == 1, + "Found multiple scriptable objects at path '{0}' when only 1 was expected with type '{1}'", resourcePath, scriptableObjectType); + + var newObj = ScriptableObject.Instantiate(objects.Single()); + + InjectExplicit(newObj, extraArgs); + + return newObj; + } + + // Same as InstantiatePrefabResourceForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public T InstantiatePrefabResourceForComponentExplicit( + string resourcePath, List extraArgs) + { + return (T)InstantiatePrefabResourceForComponentExplicit( + typeof(T), resourcePath, extraArgs); + } + + // Same as InstantiatePrefabResourceForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabResourceForComponentExplicit( + Type componentType, string resourcePath, List extraArgs) + { + return InstantiatePrefabResourceForComponentExplicit( + componentType, resourcePath, null, + new InjectArgs() + { + ExtraArgs = extraArgs, + Context = new InjectContext(this, componentType, null), + ConcreteIdentifier = null, + }); + } + + + // Same as InstantiatePrefabResourceForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabResourceForComponentExplicit( + Type componentType, string resourcePath, string groupName, InjectArgs args) + { + var prefab = (GameObject)Resources.Load(resourcePath); + Assert.IsNotNull(prefab, + "Could not find prefab at resource location '{0}'".Fmt(resourcePath)); + return InstantiatePrefabForComponentExplicit( + componentType, prefab, groupName, args); + } + + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public T InstantiatePrefabForComponentExplicit( + UnityEngine.Object prefab, List extraArgs) + { + return (T)InstantiatePrefabForComponentExplicit( + typeof(T), prefab, extraArgs); + } + + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, List extraArgs) + { + return InstantiatePrefabForComponentExplicit( + componentType, prefab, extraArgs, null); + } + + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, List extraArgs, + string groupName) + { + return InstantiatePrefabForComponentExplicit( + componentType, prefab, groupName, + new InjectArgs() + { + ExtraArgs = extraArgs, + Context = new InjectContext(this, componentType, null), + ConcreteIdentifier = null, + }); + } + + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, string groupName, InjectArgs args) + { + return InstantiatePrefabForComponentExplicit( + componentType, prefab, new GameObjectCreationParameters() { GroupName = groupName }, args); + } + + // Same as InstantiatePrefabForComponent except allows null values + // to be included in the argument list. Also see InjectUtil.CreateArgList + public object InstantiatePrefabForComponentExplicit( + Type componentType, UnityEngine.Object prefab, + GameObjectCreationParameters gameObjectBindInfo, InjectArgs args) + { + Assert.That(!AssertOnNewGameObjects, + "Given DiContainer does not support creating new game objects"); + + FlushBindings(); + + Assert.That(prefab != null, "Null prefab found when instantiating game object"); + + Assert.That(componentType.IsInterface() || componentType.DerivesFrom(), + "Expected type '{0}' to derive from UnityEngine.Component", componentType); + + GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); + + var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); + + gameObj.transform.SetParent(GetTransformGroup(gameObjectBindInfo), false); + + return InjectGameObjectForComponentExplicit( + gameObj, componentType, args); + } + ////////////// Types //////////////// class ProviderPair diff --git a/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs b/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs index b95c6ff43..72438e9b1 100644 --- a/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs @@ -21,35 +21,28 @@ public interface IInstantiator object Instantiate(Type concreteType); object Instantiate(Type concreteType, IEnumerable extraArgs); - T InstantiateExplicit(List extraArgs); - object InstantiateExplicit(Type concreteType, List extraArgs); - object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs args); - #if !NOT_UNITY3D // Add new component to existing game object and fill in its dependencies // NOTE: Gameobject here is not a prefab prototype, it is an instance TContract InstantiateComponent(GameObject gameObject) where TContract : Component; - TContract InstantiateComponent( GameObject gameObject, IEnumerable extraArgs) where TContract : Component; - Component InstantiateComponent( Type componentType, GameObject gameObject); - Component InstantiateComponent( Type componentType, GameObject gameObject, IEnumerable extraArgs); T InstantiateComponentOnNewGameObject() where T : Component; - T InstantiateComponentOnNewGameObject(string gameObjectName) where T : Component; - - Component InstantiateComponentExplicit( - Type componentType, GameObject gameObject, List extraArgs); + T InstantiateComponentOnNewGameObject(IEnumerable extraArgs) + where T : Component; + T InstantiateComponentOnNewGameObject(string gameObjectName, IEnumerable extraArgs) + where T : Component; // Create a new game object from a prefab and fill in dependencies for all children GameObject InstantiatePrefab(UnityEngine.Object prefab); @@ -60,38 +53,58 @@ GameObject InstantiatePrefab( // Create a new game object from a resource path and fill in dependencies for all children GameObject InstantiatePrefabResource(string resourcePath); - GameObject InstantiatePrefabResource( string resourcePath, string groupName); // Same as InstantiatePrefab but returns a component after it's initialized // and optionally allows extra arguments for the given component type T InstantiatePrefabForComponent(UnityEngine.Object prefab); - T InstantiatePrefabForComponent( UnityEngine.Object prefab, IEnumerable extraArgs); - object InstantiatePrefabForComponent( Type concreteType, UnityEngine.Object prefab, IEnumerable extraArgs); // Same as InstantiatePrefabResource but returns a component after it's initialized // and optionally allows extra arguments for the given component type T InstantiatePrefabResourceForComponent(string resourcePath); - T InstantiatePrefabResourceForComponent( string resourcePath, IEnumerable extraArgs); - object InstantiatePrefabResourceForComponent( Type concreteType, string resourcePath, IEnumerable extraArgs); + T InstantiateScriptableObjectResource(string resourcePath) + where T : ScriptableObject; + T InstantiateScriptableObjectResource( + string resourcePath, IEnumerable extraArgs) + where T : ScriptableObject; + object InstantiateScriptableObjectResource( + Type scriptableObjectType, string resourcePath); + object InstantiateScriptableObjectResource( + Type scriptableObjectType, string resourcePath, IEnumerable extraArgs); + + GameObject CreateEmptyGameObject(string name); +#endif + + // The below explicit methods are mostly meant for internal use + // but may be useful to you too if you need to pass in null value arguments + + T InstantiateExplicit(List extraArgs); + object InstantiateExplicit(Type concreteType, List extraArgs); + object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs args); + +#if !NOT_UNITY3D + Component InstantiateComponentExplicit( + Type componentType, GameObject gameObject, List extraArgs); + + object InstantiateScriptableObjectResourceExplicit( + Type scriptableObjectType, string resourcePath, List extraArgs); + // Same as InstantiatePrefabResourceForComponent except allows null values // to be included in the argument list. Also see InjectUtil.CreateArgList T InstantiatePrefabResourceForComponentExplicit( string resourcePath, List extraArgs); - object InstantiatePrefabResourceForComponentExplicit( Type concreteType, string resourcePath, List extraArgs); - object InstantiatePrefabResourceForComponentExplicit( Type concreteType, string resourcePath, string groupName, InjectArgs args); @@ -99,23 +112,18 @@ object InstantiatePrefabResourceForComponentExplicit( // to be included in the argument list. Also see InjectUtil.CreateArgList T InstantiatePrefabForComponentExplicit( UnityEngine.Object prefab, List extraArgs); - object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, List extraArgs); - object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, List extraArgs, string groupName); - object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, string groupName, InjectArgs args); - object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, GameObjectCreationParameters gameObjectBindInfo, InjectArgs args); - - GameObject CreateEmptyGameObject(string name); #endif + } } diff --git a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs index 1c69f1608..60b64bf09 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToCurrentGameObjectComponentProvider.cs @@ -53,7 +53,7 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co Assert.IsNotNull(context); Assert.That(context.ObjectType.DerivesFrom(), - "Object '{0}' can only be injected into MonoBehaviour's since it was bound with 'FromNewSiblingComponent'. Attempted to inject into non-MonoBehaviour '{1}'", + "Object '{0}' can only be injected into MonoBehaviour's since it was bound with 'FromNewComponentSibling'. Attempted to inject into non-MonoBehaviour '{1}'", context.MemberType, context.ObjectType); object instance; @@ -84,7 +84,6 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co var injectArgs = new InjectArgs() { ExtraArgs = _extraArguments.Concat(args).ToList(), - UseAllArgs = true, Context = context, ConcreteIdentifier = _concreteIdentifier, }; diff --git a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToGameObjectComponentProviderBase.cs b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToGameObjectComponentProviderBase.cs index e905619d2..0f712d5a6 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToGameObjectComponentProviderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/ComponentProviders/AddToGameObjectComponentProviders/AddToGameObjectComponentProviderBase.cs @@ -72,7 +72,6 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co var injectArgs = new InjectArgs() { ExtraArgs = _extraArguments.Concat(args).ToList(), - UseAllArgs = true, Context = context, ConcreteIdentifier = _concreteIdentifier, }; diff --git a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs index f40d163b3..96cc5ecff 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/PrefabCreators/PrefabInstantiator.cs @@ -75,7 +75,6 @@ public IEnumerator Instantiate(List args) var injectArgs = new InjectArgs() { ExtraArgs = allArgs, - UseAllArgs = true, Context = new InjectContext(_container, _argumentTarget, null), ConcreteIdentifier = null, }; diff --git a/UnityProject/Assets/Zenject/Source/Providers/ResourceProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/ResourceProvider.cs index 94e8bd81b..4062a9f46 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/ResourceProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/ResourceProvider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Linq; using ModestTree; using UnityEngine; @@ -30,12 +31,12 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co Assert.IsNotNull(context); - var obj = Resources.Load(_resourcePath, _resourceType); + var objects = Resources.LoadAll(_resourcePath, _resourceType).Cast().ToList(); - Assert.IsNotNull(obj, + Assert.That(!objects.IsEmpty(), "Could not find resource at path '{0}' with type '{1}'", _resourcePath, _resourceType); - yield return new List() { obj }; + yield return objects; // Are there any resource types which can be injected? } @@ -45,4 +46,3 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co #endif - diff --git a/UnityProject/Assets/Zenject/Source/Providers/ScriptableObjectResourceProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/ScriptableObjectResourceProvider.cs new file mode 100644 index 000000000..d84bb1101 --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Providers/ScriptableObjectResourceProvider.cs @@ -0,0 +1,68 @@ +#if !NOT_UNITY3D + +using System; +using System.Collections.Generic; +using System.Linq; +using ModestTree; +using UnityEngine; + +namespace Zenject +{ + public class ScriptableObjectResourceProvider : IProvider + { + readonly DiContainer _container; + readonly Type _resourceType; + readonly string _resourcePath; + readonly List _extraArguments; + readonly object _concreteIdentifier; + + public ScriptableObjectResourceProvider( + string resourcePath, Type resourceType, + DiContainer container, object concreteIdentifier, List extraArguments) + { + _container = container; + Assert.DerivesFromOrEqual(resourceType); + + _concreteIdentifier = concreteIdentifier; + _extraArguments = extraArguments; + _resourceType = resourceType; + _resourcePath = resourcePath; + } + + public Type GetInstanceType(InjectContext context) + { + return _resourceType; + } + + public IEnumerator> GetAllInstancesWithInjectSplit( + InjectContext context, List args) + { + Assert.IsEmpty(args); + + Assert.IsNotNull(context); + + var objects = Resources.LoadAll(_resourcePath, _resourceType) + .Select(x => ScriptableObject.Instantiate(x)).Cast().ToList(); + + Assert.That(!objects.IsEmpty(), + "Could not find resource at path '{0}' with type '{1}'", _resourcePath, _resourceType); + + yield return objects; + + var injectArgs = new InjectArgs() + { + ExtraArgs = _extraArguments.Concat(args).ToList(), + Context = context, + ConcreteIdentifier = _concreteIdentifier, + }; + + foreach (var obj in objects) + { + _container.InjectExplicit( + obj, _resourceType, injectArgs); + } + } + } +} + +#endif diff --git a/UnityProject/Assets/Zenject/Source/Providers/ScriptableObjectResourceProvider.cs.meta b/UnityProject/Assets/Zenject/Source/Providers/ScriptableObjectResourceProvider.cs.meta new file mode 100644 index 000000000..7399c11be --- /dev/null +++ b/UnityProject/Assets/Zenject/Source/Providers/ScriptableObjectResourceProvider.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5753f1f4d468e7649b017dee98c6301d +timeCreated: 1486668547 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonTypes.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonTypes.cs index 4a9cbf78e..916008715 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonTypes.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonTypes.cs @@ -16,6 +16,7 @@ public enum SingletonTypes FromGetter, FromResolve, FromResource, + FromScriptableObjectResource, FromSubContainerPrefab, FromSubContainerPrefabResource, } diff --git a/UnityProject/Assets/Zenject/Source/Providers/TransientProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/TransientProvider.cs index 1b2e9ab19..193b001c9 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/TransientProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/TransientProvider.cs @@ -57,7 +57,6 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co ExtraArgs = _extraArguments.Concat(args).ToList(), Context = context, ConcreteIdentifier = _concreteIdentifier, - UseAllArgs = false, }; var instance = _container.InstantiateExplicit( @@ -66,8 +65,6 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co // Return before property/field/method injection to allow circular dependencies yield return new List() { instance }; - injectArgs.UseAllArgs = true; - _container.InjectExplicit(instance, instanceType, injectArgs); } From b2c990f34de71aa80985db1184cf8730b4e258d8 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Thu, 9 Feb 2017 22:42:21 -0400 Subject: [PATCH 37/62] Changed to require explicitly setting AsTransient for all bind methods except the for the "search" ones like FromMethod or FromComponentInParents, etc. to avoid the otherwise common error of mistakenly using transient when meaning single --- .../Bindings/Editor/TestFromGameObject.cs | 2 +- .../Bindings/Editor/TestFromPrefab.cs | 4 ++-- .../Bindings/Editor/TestFromPrefabResource.cs | 4 ++-- .../Factories/Editor/TestBindFactoryOne.cs | 9 ++++++--- .../TestBindFactoryFive/FooInstaller.cs | 2 +- .../TestBindFactoryOne/FooInstaller.cs | 2 +- .../Editor/Tests/TestAsteroidManager.cs | 2 +- .../TestMultipleContractTypes2.cs | 2 +- .../UnitTests/Editor/Bindings/TestFrom.cs | 2 +- .../Editor/Bindings/TestFromResolve.cs | 20 +++++++++---------- .../Bindings/TestFromSubContainerInstaller.cs | 4 ++-- .../Bindings/TestFromSubContainerMethod.cs | 5 +++-- .../Editor/Conventions/TestConvention.cs | 14 ++++++------- .../Editor/Conventions/TestConvention2.cs | 4 ++-- .../Editor/Conventions/TestConventionNames.cs | 6 +++--- .../TestFactoryFromSubContainerInstaller1.cs | 2 +- .../ConcreteBinders/ConcreteBinderGeneric.cs | 1 + .../ConcreteBinderNonGeneric.cs | 1 + ... => PlaceholderFactoryBindingFinalizer.cs} | 0 ...laceholderFactoryBindingFinalizer.cs.meta} | 6 +++--- .../Binding/Binders/FromBinders/FromBinder.cs | 20 +++++++++++++++++++ ...ynamicFactory.cs => PlaceholderFactory.cs} | 0 ...ory.cs.meta => PlaceholderFactory.cs.meta} | 6 +++--- 23 files changed, 72 insertions(+), 46 deletions(-) rename UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/{DynamicFactoryBindingFinalizer.cs => PlaceholderFactoryBindingFinalizer.cs} (100%) rename UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/{DynamicFactoryBindingFinalizer.cs.meta => PlaceholderFactoryBindingFinalizer.cs.meta} (69%) rename UnityProject/Assets/Zenject/Source/Factories/{DynamicFactory.cs => PlaceholderFactory.cs} (100%) rename UnityProject/Assets/Zenject/Source/Factories/{DynamicFactory.cs.meta => PlaceholderFactory.cs.meta} (69%) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs index 9c6185b9c..a60e629d3 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromGameObject.cs @@ -88,7 +88,7 @@ public void TestCached2() public void TestMultipleConcreteTransient1() { Container.Bind().To(typeof(Foo), typeof(Bar)).FromNewComponentOnNewGameObject() - .WithGameObjectName(GameObjName); + .WithGameObjectName(GameObjName).AsTransient(); Container.BindRootResolve(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs index 7cbef575b..414e0c06e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs @@ -150,7 +150,7 @@ public void TestWithAbstractSearch() { // There are three components that implement INorf on this prefab // and so this should result in a list of 3 INorf's - Container.Bind().FromComponentInPrefab(NorfPrefab).NonLazy(); + Container.Bind().FromComponentInPrefab(NorfPrefab).AsTransient().NonLazy(); Initialize(); @@ -163,7 +163,7 @@ public void TestWithAbstractSearch() public void TestAbstractBindingConcreteSearch() { // Should ignore the Norf2 component on it - Container.Bind().To().FromComponentInPrefab(NorfPrefab).NonLazy(); + Container.Bind().To().FromComponentInPrefab(NorfPrefab).AsTransient().NonLazy(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs index 56e2d15f1..49b1d3e33 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs @@ -122,7 +122,7 @@ public void TestWithAbstractSearch() { // There are three components that implement INorf on this prefab // and so this should result in a list of 3 INorf's - Container.Bind().FromComponentInPrefabResource(PathPrefix + "Norf").NonLazy(); + Container.Bind().FromComponentInPrefabResource(PathPrefix + "Norf").AsTransient().NonLazy(); Initialize(); @@ -135,7 +135,7 @@ public void TestWithAbstractSearch() public void TestAbstractBindingConcreteSearch() { // Should ignore the Norf2 component on it - Container.Bind().To().FromComponentInPrefabResource(PathPrefix + "Norf").NonLazy(); + Container.Bind().To().FromComponentInPrefabResource(PathPrefix + "Norf").AsTransient().NonLazy(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs index 56ce3bc52..4585f9ce4 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs @@ -101,7 +101,8 @@ public void TestToPrefabSelf() [Test] public void TestToPrefabConcrete() { - Container.BindFactory().To().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().To() + .FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -129,7 +130,8 @@ public void TestToPrefabResourceSelf() [Test] public void TestToPrefabResourceConcrete() { - Container.BindFactory().To().FromComponentInPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); + Container.BindFactory().To() + .FromComponentInPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); AddFactoryUser(); @@ -143,7 +145,8 @@ public void TestToPrefabResourceConcrete() [Test] public void TestToSubContainerPrefabSelf() { - Container.BindFactory().FromSubContainerResolve().ByPrefab(FooSubContainerPrefab); + Container.BindFactory() + .FromSubContainerResolve().ByPrefab(FooSubContainerPrefab); AddFactoryUser(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryFive/FooInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryFive/FooInstaller.cs index 86c6e8b7a..3ab0967fe 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryFive/FooInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryFive/FooInstaller.cs @@ -29,7 +29,7 @@ public override void InstallBindings() Container.BindInstance(_param4, true).WhenInjectedInto(); Container.BindInstance(_param5, true).WhenInjectedInto(); - Container.Bind().FromNewComponentOnNewGameObject(); + Container.Bind().FromNewComponentOnNewGameObject().AsTransient(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryOne/FooInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryOne/FooInstaller.cs index ac36b0f3e..e687881f5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryOne/FooInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/TestBindFactoryOne/FooInstaller.cs @@ -16,7 +16,7 @@ public void Init(string param1) public override void InstallBindings() { Container.BindInstance(_param1, true).WhenInjectedInto(); - Container.Bind().FromNewComponentOnNewGameObject(); + Container.Bind().FromNewComponentOnNewGameObject().AsTransient(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs index 80339b5f1..da5fcea60 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs @@ -21,7 +21,7 @@ public void CommonInstall() var gameSettings = Container.Resolve(); Container.Bind().AsSingle(); Container.BindFactory().FromComponentInPrefab(gameSettings.AsteroidPrefab); - Container.Bind().WithId("Main").FromNewComponentOnNewGameObject(); + Container.Bind().WithId("Main").FromNewComponentOnNewGameObject().AsTransient(); Container.Bind().AsSingle(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs index 1bf14ca18..81256845d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/BindFeatures/TestMultipleContractTypes2.cs @@ -82,7 +82,7 @@ public void TestAllInterfacesAndSelf() [Test] public void TestAllInterfacesAndSelfMistake() { - Container.BindInterfacesToSelf(); + Container.BindInterfacesAndSelfTo(); // Should require setting scope Assert.Throws(() => Container.FlushBindings()); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs index f842e05db..1389a00e1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFrom.cs @@ -73,7 +73,7 @@ public void TestConcreteTransient() [Test] public void TestConcreteTransient2() { - Container.Bind().To().NonLazy(); + Container.Bind().To().AsTransient().NonLazy(); Assert.IsNotNull(Container.Resolve()); Assert.IsNotEqual(Container.Resolve(), Container.Resolve()); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs index 1819e105c..4e2ff0b0d 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs @@ -78,7 +78,7 @@ public void TestInfiniteLoop() [Test] public void TestResolveManyTransient() { - Container.Bind().NonLazy(); + Container.Bind().AsTransient().NonLazy(); Container.Bind().FromInstance(new Foo()).NonLazy(); Container.Bind().To().FromResolve().NonLazy(); @@ -89,7 +89,7 @@ public void TestResolveManyTransient() [Test] public void TestResolveManyTransient2() { - Container.Bind().NonLazy(); + Container.Bind().AsTransient().NonLazy(); Container.Bind().FromInstance(new Foo()).NonLazy(); Container.Bind(typeof(IFoo), typeof(IBar)).To().FromResolve().NonLazy(); @@ -101,8 +101,8 @@ public void TestResolveManyTransient2() [Test] public void TestResolveManyCached() { - Container.Bind().NonLazy(); - Container.Bind().NonLazy(); + Container.Bind().AsTransient().NonLazy(); + Container.Bind().AsTransient().NonLazy(); Container.Bind().To().FromResolve().AsCached().NonLazy(); @@ -113,8 +113,8 @@ public void TestResolveManyCached() [Test] public void TestResolveManyCached2() { - Container.Bind().NonLazy(); - Container.Bind().NonLazy(); + Container.Bind().AsTransient().NonLazy(); + Container.Bind().AsTransient().NonLazy(); Container.Bind(typeof(IFoo), typeof(IBar)).To().FromResolve().AsCached().NonLazy(); @@ -126,8 +126,8 @@ public void TestResolveManyCached2() [Test] public void TestResolveManyCached3() { - Container.Bind().NonLazy(); - Container.Bind().NonLazy(); + Container.Bind().AsTransient().NonLazy(); + Container.Bind().AsTransient().NonLazy(); Container.Bind().To().FromResolve().AsCached().NonLazy(); Container.Bind().To().FromResolve().AsCached().NonLazy(); @@ -140,8 +140,8 @@ public void TestResolveManyCached3() [Test] public void TestResolveManySingle() { - Container.Bind().NonLazy(); - Container.Bind().NonLazy(); + Container.Bind().AsTransient().NonLazy(); + Container.Bind().AsTransient().NonLazy(); // This is a bit weird since it's a singleton but matching multiple... but valid Container.Bind().To().FromResolve().AsSingle().NonLazy(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs index ae05a8aac..d2de4a900 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerInstaller.cs @@ -113,10 +113,10 @@ public override void InstallBindings() Container.Bind().AsSingle(); Container.Bind().AsSingle(); - Container.Bind(); + Container.Bind().AsTransient(); Container.Bind().FromInstance(new Qux()); - Container.Bind().WithId("gorp"); + Container.Bind().WithId("gorp").AsTransient(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs index 870bb9a8d..4174a6dbf 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromSubContainerMethod.cs @@ -79,7 +79,8 @@ public void TestMethodConcreteTransient() [Test] public void TestMethodConcreteCached() { - Container.Bind().To().FromSubContainerResolve().ByMethod(InstallFooFacade).AsCached().NonLazy(); + Container.Bind().To() + .FromSubContainerResolve().ByMethod(InstallFooFacade).AsCached().NonLazy(); Assert.IsNotNull(Container.Resolve().Bar); } @@ -152,7 +153,7 @@ void InstallFooFacade(DiContainer container) container.Bind().AsSingle(); container.Bind().AsSingle(); - container.Bind().WithId("gorp"); + container.Bind().WithId("gorp").AsTransient(); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConvention.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConvention.cs index c487b6ac4..79c4970b5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConvention.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConvention.cs @@ -17,7 +17,7 @@ public class TestConvention : ZenjectUnitTestFixture public void TestDerivingFrom() { Container.Bind() - .To(x => x.AllTypes().DerivingFrom().FromThisAssembly()); + .To(x => x.AllTypes().DerivingFrom().FromThisAssembly()).AsTransient(); Assert.IsEqual(Container.ResolveAll().Count(), 4); } @@ -26,7 +26,7 @@ public void TestDerivingFrom() public void TestDerivingFrom2() { Container.Bind() - .To(x => x.AllTypes().DerivingFrom()); + .To(x => x.AllTypes().DerivingFrom()).AsTransient(); Assert.IsEqual(Container.ResolveAll().Count(), 4); } @@ -35,7 +35,7 @@ public void TestDerivingFrom2() public void TestMatchAll() { // Should automatically filter by contract types - Container.Bind().To(x => x.AllNonAbstractClasses()); + Container.Bind().To(x => x.AllNonAbstractClasses()).AsTransient(); Assert.IsEqual(Container.ResolveAll().Count(), 4); } @@ -45,7 +45,7 @@ public void TestMatchAll() public void TestDerivingFromFail() { Container.Bind() - .To(x => x.AllTypes().DerivingFrom().FromAssemblyContaining()); + .To(x => x.AllTypes().DerivingFrom().FromAssemblyContaining()).AsTransient(); Assert.That(Container.ResolveAll().IsEmpty()); } @@ -55,7 +55,7 @@ public void TestDerivingFromFail() public void TestAttributeFilter() { Container.Bind() - .To(x => x.AllTypes().WithAttribute()); + .To(x => x.AllTypes().WithAttribute()).AsTransient(); Assert.IsEqual(Container.ResolveAll().Count(), 2); } @@ -64,7 +64,7 @@ public void TestAttributeFilter() public void TestAttributeWhereFilter() { Container.Bind() - .To(x => x.AllTypes().WithAttributeWhere(a => a.Num == 1)); + .To(x => x.AllTypes().WithAttributeWhere(a => a.Num == 1)).AsTransient(); Assert.IsEqual(Container.ResolveAll().Count(), 1); } @@ -73,7 +73,7 @@ public void TestAttributeWhereFilter() public void TestInNamespace() { Container.Bind() - .To(x => x.AllTypes().DerivingFrom().InNamespace("Zenject.Tests.Convention.NamespaceTest")); + .To(x => x.AllTypes().DerivingFrom().InNamespace("Zenject.Tests.Convention.NamespaceTest")).AsTransient(); Assert.IsEqual(Container.ResolveAll().Count(), 1); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConvention2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConvention2.cs index 38ac10b82..e31ef8cbb 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConvention2.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConvention2.cs @@ -18,7 +18,7 @@ public void TestBindAllInterfacesSimple() { var container = new DiContainer(); - container.Bind(x => x.AllInterfaces()).To(); + container.Bind(x => x.AllInterfaces()).To().AsTransient(); Assert.That(container.Resolve() is Foo); Assert.That(container.Resolve() is Foo); @@ -30,7 +30,7 @@ public void TestBindAllInterfaces2() var container = new DiContainer(); container.Bind(x => x.AllInterfaces()) - .To(x => x.AllNonAbstractClasses().InNamespace("Zenject.Tests.Convention.Two")); + .To(x => x.AllNonAbstractClasses().InNamespace("Zenject.Tests.Convention.Two")).AsTransient(); Assert.IsEqual(container.ResolveAll().Count, 2); Assert.IsEqual(container.ResolveAll().Count, 2); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConventionNames.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConventionNames.cs index 6694c19c9..c0dfccb27 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConventionNames.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conventions/TestConventionNames.cs @@ -18,7 +18,7 @@ public class TestConventionNames : ZenjectUnitTestFixture public void TestWithSuffix() { Container.Bind() - .To(x => x.AllNonAbstractClasses().InNamespace("Zenject.Tests.Convention.Names").WithSuffix("Controller")); + .To(x => x.AllNonAbstractClasses().InNamespace("Zenject.Tests.Convention.Names").WithSuffix("Controller")).AsTransient(); Assert.That(Container.Resolve() is FooController); } @@ -27,7 +27,7 @@ public void TestWithSuffix() public void TestWithPrefix() { Container.Bind() - .To(x => x.AllTypes().InNamespace("Zenject.Tests.Convention.Names").WithPrefix("Controller")); + .To(x => x.AllTypes().InNamespace("Zenject.Tests.Convention.Names").WithPrefix("Controller")).AsTransient(); Assert.That(Container.Resolve() is ControllerBar); } @@ -36,7 +36,7 @@ public void TestWithPrefix() public void TestMatchingRegex() { Container.Bind() - .To(x => x.AllNonAbstractClasses().InNamespace("Zenject.Tests.Convention.Names").MatchingRegex("Controller$")); + .To(x => x.AllNonAbstractClasses().InNamespace("Zenject.Tests.Convention.Names").MatchingRegex("Controller$")).AsTransient(); Assert.That(Container.Resolve() is FooController); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs index 0ce9f7eca..120e6e4ca 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestFactoryFromSubContainerInstaller1.cs @@ -40,7 +40,7 @@ public FooInstaller(string value) public override void InstallBindings() { - Container.Bind().WithArgumentsExplicit( + Container.Bind().AsTransient().WithArgumentsExplicit( InjectUtil.CreateArgListExplicit(_value)); } } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderGeneric.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderGeneric.cs index 2168c64db..e7f66ddda 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderGeneric.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderGeneric.cs @@ -20,6 +20,7 @@ public FromBinderGeneric ToSelf() { Assert.IsEqual(BindInfo.ToChoice, ToChoices.Self); + BindInfo.RequireExplicitScope = true; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromNew, null, (container, type) => new TransientProvider( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderNonGeneric.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderNonGeneric.cs index d9cd67aac..15121831b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderNonGeneric.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/ConcreteBinders/ConcreteBinderNonGeneric.cs @@ -20,6 +20,7 @@ public FromBinderNonGeneric ToSelf() { Assert.IsEqual(BindInfo.ToChoice, ToChoices.Self); + BindInfo.RequireExplicitScope = true; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromNew, null, (container, type) => new TransientProvider( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/PlaceholderFactoryBindingFinalizer.cs similarity index 100% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/PlaceholderFactoryBindingFinalizer.cs diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs.meta b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/PlaceholderFactoryBindingFinalizer.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs.meta rename to UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/PlaceholderFactoryBindingFinalizer.cs.meta index 3e03344aa..826fecd1f 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/DynamicFactoryBindingFinalizer.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/PlaceholderFactoryBindingFinalizer.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 05c65ab93a383274999ceb788b62c655 -timeCreated: 1461708048 -licenseType: Pro +guid: 2a3880a3063c56747b32995b66a8a1ca +timeCreated: 1486691381 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index 37b54e441..69a39db56 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -67,6 +67,7 @@ public ScopeConditionCopyNonLazyBinder FromResolve() public ScopeConditionCopyNonLazyBinder FromResolve(object subIdentifier) { + BindInfo.RequireExplicitScope = false; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromResolve, subIdentifier, @@ -82,6 +83,10 @@ public SubContainerBinder FromSubContainerResolve() public SubContainerBinder FromSubContainerResolve(object subIdentifier) { + // It's unlikely they will want to create the whole subcontainer with each binding + // (aka transient) which is the default so require that they specify it + BindInfo.RequireExplicitScope = true; + return new SubContainerBinder( BindInfo, FinalizerWrapper, subIdentifier); } @@ -90,6 +95,7 @@ public ScopeArgConditionCopyNonLazyBinder FromFactory(Type factoryType) { Assert.That(factoryType.DerivesFrom()); + BindInfo.RequireExplicitScope = true; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromFactory, factoryType, @@ -107,6 +113,7 @@ public ScopeArgConditionCopyNonLazyBinder FromNewComponentOn(GameObject gameObje BindingUtil.AssertIsComponent(ConcreteTypes); BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); + BindInfo.RequireExplicitScope = true; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromComponentGameObject, gameObject, (container, type) => new AddToExistingGameObjectComponentProvider( @@ -120,6 +127,7 @@ public ArgConditionCopyNonLazyBinder FromNewComponentSibling() BindingUtil.AssertIsComponent(ConcreteTypes); BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); + BindInfo.RequireExplicitScope = true; SubFinalizer = new SingleProviderBindingFinalizer( BindInfo, (container, type) => new AddToCurrentGameObjectComponentProvider( container, type, BindInfo.ConcreteIdentifier, BindInfo.Arguments)); @@ -138,6 +146,7 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromNewComponentOnNewGame BindingUtil.AssertIsComponent(ConcreteTypes); BindingUtil.AssertTypesAreNotAbstract(ConcreteTypes); + BindInfo.RequireExplicitScope = true; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromGameObject, gameObjectInfo, (container, type) => new AddToNewGameObjectComponentProvider( @@ -162,6 +171,7 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefab( BindingUtil.AssertIsValidPrefab(prefab); BindingUtil.AssertIsInterfaceOrComponent(AllParentTypes); + BindInfo.RequireExplicitScope = true; SubFinalizer = new PrefabBindingFinalizer( BindInfo, gameObjectInfo, prefab); @@ -179,6 +189,7 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefabReso BindingUtil.AssertIsValidResourcePath(resourcePath); BindingUtil.AssertIsInterfaceOrComponent(AllParentTypes); + BindInfo.RequireExplicitScope = true; SubFinalizer = new PrefabResourceBindingFinalizer( BindInfo, gameObjectInfo, resourcePath); @@ -190,6 +201,7 @@ public ScopeArgConditionCopyNonLazyBinder FromScriptableObjectResource(string re BindingUtil.AssertIsValidResourcePath(resourcePath); BindingUtil.AssertIsInterfaceOrScriptableObject(AllParentTypes); + BindInfo.RequireExplicitScope = true; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromScriptableObjectResource, @@ -204,6 +216,7 @@ public ScopeConditionCopyNonLazyBinder FromResource(string resourcePath) { BindingUtil.AssertDerivesFromUnityObject(ConcreteTypes); + BindInfo.RequireExplicitScope = false; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromResource, @@ -217,6 +230,7 @@ public ScopeConditionCopyNonLazyBinder FromResource(string resourcePath) public ScopeArgConditionCopyNonLazyBinder FromMethodUntyped(Func method) { + BindInfo.RequireExplicitScope = false; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromMethod, new SingletonImplIds.ToMethod(method), @@ -229,6 +243,7 @@ protected ScopeArgConditionCopyNonLazyBinder FromMethodBase(Func(F { BindingUtil.AssertIsDerivedFromTypes(typeof(TConcrete), AllParentTypes); + BindInfo.RequireExplicitScope = false; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromMethod, new SingletonImplIds.ToMethod(method), @@ -254,6 +270,8 @@ protected ScopeArgConditionCopyNonLazyBinder FromFactoryBase( { BindingUtil.AssertIsDerivedFromTypes(typeof(TResult), AllParentTypes); + BindInfo.RequireExplicitScope = false; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromGetter, @@ -287,6 +306,7 @@ protected ScopeConditionCopyNonLazyBinder FromInstanceBase(object instance, bool BindingUtil.AssertInstanceDerivesFromOrEqual(instance, AllParentTypes); + BindInfo.RequireExplicitScope = false; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromInstance, instance, (container, type) => new InstanceProvider(container, type, instance)); diff --git a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/PlaceholderFactory.cs similarity index 100% rename from UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs rename to UnityProject/Assets/Zenject/Source/Factories/PlaceholderFactory.cs diff --git a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs.meta b/UnityProject/Assets/Zenject/Source/Factories/PlaceholderFactory.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs.meta rename to UnityProject/Assets/Zenject/Source/Factories/PlaceholderFactory.cs.meta index cd00b7039..46ad9e550 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/DynamicFactory.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Factories/PlaceholderFactory.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: ea8a4084079a1ab4eac1ae9c79a5753a -timeCreated: 1461708054 -licenseType: Pro +guid: 665a56f53857092408155478e576cfd0 +timeCreated: 1486691381 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] From 5a4579ef1c447c5e65b959dbc5b0c09eb92e9a63 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 10 Feb 2017 13:09:00 -0400 Subject: [PATCH 38/62] Fixed to avoid the extra performance costs of calling SetParent by directly passing the parent to the GameObject.Instantiate method issue #188 --- .../Assets/Zenject/Source/Main/DiContainer.cs | 53 +++++++++---------- .../Zenject/Source/Main/IInstantiator.cs | 13 ++--- .../Zenject/Source/Util/TypeAnalyzer.cs | 25 +++++---- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index ef3c57adb..ed11c343d 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -998,10 +998,8 @@ public GameObject CreateAndParentPrefab( var prefabAsGameObject = GetPrefabAsGameObject(prefab); - var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); - - gameObj.transform.SetParent( - GetTransformGroup(gameObjectBindInfo), false); + var gameObj = (GameObject)GameObject.Instantiate( + prefabAsGameObject, GetTransformGroup(gameObjectBindInfo)); if (gameObjectBindInfo.Name != null) { @@ -1184,15 +1182,15 @@ public T InstantiateComponentOnNewGameObject( // Create a new game object from a prefab and fill in dependencies for all children public GameObject InstantiatePrefab(UnityEngine.Object prefab) { - return InstantiatePrefab(prefab, (string)null); + return InstantiatePrefab( + prefab, new GameObjectCreationParameters()); } // Create a new game object from a prefab and fill in dependencies for all children - public GameObject InstantiatePrefab( - UnityEngine.Object prefab, string groupName) + public GameObject InstantiatePrefab(UnityEngine.Object prefab, Transform parentTransform) { return InstantiatePrefab( - prefab, new GameObjectCreationParameters() { GroupName = groupName }); + prefab, new GameObjectCreationParameters() { ParentTransform = parentTransform }); } // Create a new game object from a prefab and fill in dependencies for all children @@ -1211,19 +1209,25 @@ public GameObject InstantiatePrefab( // Create a new game object from a resource path and fill in dependencies for all children public GameObject InstantiatePrefabResource(string resourcePath) { - return InstantiatePrefabResource(resourcePath, null); + return InstantiatePrefabResource(resourcePath, new GameObjectCreationParameters()); + } + + // Create a new game object from a resource path and fill in dependencies for all children + public GameObject InstantiatePrefabResource(string resourcePath, Transform parentTransform) + { + return InstantiatePrefabResource(resourcePath, new GameObjectCreationParameters() { ParentTransform = parentTransform }); } // Create a new game object from a resource path and fill in dependencies for all children public GameObject InstantiatePrefabResource( - string resourcePath, string groupName) + string resourcePath, GameObjectCreationParameters creationInfo) { var prefab = (GameObject)Resources.Load(resourcePath); Assert.IsNotNull(prefab, "Could not find prefab at resource location '{0}'".Fmt(resourcePath)); - return InstantiatePrefab(prefab, groupName); + return InstantiatePrefab(prefab, creationInfo); } // Same as InstantiatePrefab but returns a component after it's initialized @@ -2037,7 +2041,7 @@ public object InstantiatePrefabResourceForComponentExplicit( Type componentType, string resourcePath, List extraArgs) { return InstantiatePrefabResourceForComponentExplicit( - componentType, resourcePath, null, + componentType, resourcePath, new GameObjectCreationParameters(), new InjectArgs() { ExtraArgs = extraArgs, @@ -2050,13 +2054,14 @@ public object InstantiatePrefabResourceForComponentExplicit( // Same as InstantiatePrefabResourceForComponent except allows null values // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabResourceForComponentExplicit( - Type componentType, string resourcePath, string groupName, InjectArgs args) + Type componentType, string resourcePath, + GameObjectCreationParameters creationInfo, InjectArgs args) { var prefab = (GameObject)Resources.Load(resourcePath); Assert.IsNotNull(prefab, "Could not find prefab at resource location '{0}'".Fmt(resourcePath)); return InstantiatePrefabForComponentExplicit( - componentType, prefab, groupName, args); + componentType, prefab, creationInfo, args); } // Same as InstantiatePrefabForComponent except allows null values @@ -2074,17 +2079,17 @@ public object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, List extraArgs) { return InstantiatePrefabForComponentExplicit( - componentType, prefab, extraArgs, null); + componentType, prefab, extraArgs, new GameObjectCreationParameters()); } // Same as InstantiatePrefabForComponent except allows null values // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, List extraArgs, - string groupName) + GameObjectCreationParameters creationInfo) { return InstantiatePrefabForComponentExplicit( - componentType, prefab, groupName, + componentType, prefab, creationInfo, new InjectArgs() { ExtraArgs = extraArgs, @@ -2093,15 +2098,6 @@ public object InstantiatePrefabForComponentExplicit( }); } - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, string groupName, InjectArgs args) - { - return InstantiatePrefabForComponentExplicit( - componentType, prefab, new GameObjectCreationParameters() { GroupName = groupName }, args); - } - // Same as InstantiatePrefabForComponent except allows null values // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabForComponentExplicit( @@ -2120,9 +2116,8 @@ public object InstantiatePrefabForComponentExplicit( GameObject prefabAsGameObject = GetPrefabAsGameObject(prefab); - var gameObj = (GameObject)GameObject.Instantiate(prefabAsGameObject); - - gameObj.transform.SetParent(GetTransformGroup(gameObjectBindInfo), false); + var gameObj = (GameObject)GameObject.Instantiate( + prefabAsGameObject, GetTransformGroup(gameObjectBindInfo)); return InjectGameObjectForComponentExplicit( gameObj, componentType, args); diff --git a/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs b/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs index 72438e9b1..f4b3add42 100644 --- a/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs @@ -47,14 +47,16 @@ T InstantiateComponentOnNewGameObject(string gameObjectName, IEnumerable( object InstantiatePrefabResourceForComponentExplicit( Type concreteType, string resourcePath, List extraArgs); object InstantiatePrefabResourceForComponentExplicit( - Type concreteType, string resourcePath, string groupName, InjectArgs args); + Type concreteType, string resourcePath, + GameObjectCreationParameters creationInfo, InjectArgs args); // Same as InstantiatePrefabForComponent except allows null values // to be included in the argument list. Also see InjectUtil.CreateArgList @@ -116,9 +119,7 @@ object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, List extraArgs); object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, List extraArgs, - string groupName); - object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, string groupName, InjectArgs args); + GameObjectCreationParameters creationInfo); object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, GameObjectCreationParameters gameObjectBindInfo, InjectArgs args); diff --git a/UnityProject/Assets/Zenject/Source/Util/TypeAnalyzer.cs b/UnityProject/Assets/Zenject/Source/Util/TypeAnalyzer.cs index 5a061c7a1..5defc6d85 100644 --- a/UnityProject/Assets/Zenject/Source/Util/TypeAnalyzer.cs +++ b/UnityProject/Assets/Zenject/Source/Util/TypeAnalyzer.cs @@ -17,23 +17,28 @@ public static ZenjectTypeInfo GetInfo() public static ZenjectTypeInfo GetInfo(Type type) { - Assert.That(!type.IsAbstract(), - "Tried to analyze abstract type '{0}'. This is not currently allowed.", type); +#if UNITY_EDITOR + using (ProfileBlock.Start("Zenject Reflection")) +#endif + { + Assert.That(!type.IsAbstract(), + "Tried to analyze abstract type '{0}'. This is not currently allowed.", type); - ZenjectTypeInfo info; + ZenjectTypeInfo info; #if ZEN_MULTITHREADING - lock (_typeInfo) + lock (_typeInfo) #endif - { - if (!_typeInfo.TryGetValue(type, out info)) { - info = CreateTypeInfo(type); - _typeInfo.Add(type, info); + if (!_typeInfo.TryGetValue(type, out info)) + { + info = CreateTypeInfo(type); + _typeInfo.Add(type, info); + } } - } - return info; + return info; + } } static ZenjectTypeInfo CreateTypeInfo(Type type) From bc74992c798962d18d76f362b93888441b53b625 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 10 Feb 2017 21:38:47 -0400 Subject: [PATCH 39/62] Minor fix to integration tests --- .../Source/Editor/Testing/ZenjectIntegrationTestFixture.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs index a15f1c28c..9a47e8625 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs @@ -30,6 +30,11 @@ protected DiContainer Container [SetUp] public virtual void SetUp() { + // Don't clear the scene to allow tests to initialize the scene how they + // want to set it up manually in their own [Setup] method (eg. TestFromComponentInChildren) + // Also, I think unity might already clear the scene anyway? + // ClearScene(); + _hasStarted = false; _isValidating = CurrentTestHasAttribute(); @@ -95,7 +100,7 @@ bool CurrentTestHasAttribute() .Cast().OfType().Any(); } - void ClearScene() + protected void ClearScene() { var scene = EditorSceneManager.GetActiveScene(); From c3eb3edc57ea3c626dbeeb4fb0bd4999bf250ae0 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 10 Feb 2017 23:22:28 -0400 Subject: [PATCH 40/62] Updated project to 5.5.1 --- .../ProjectSettings/EditorBuildSettings.asset | 4 +- .../ProjectSettings/ProjectSettings.asset | 314 +++++++++--------- .../ProjectSettings/ProjectVersion.txt | 2 +- 3 files changed, 161 insertions(+), 159 deletions(-) diff --git a/UnityProject/ProjectSettings/EditorBuildSettings.asset b/UnityProject/ProjectSettings/EditorBuildSettings.asset index a846663a4..b522bb60f 100644 --- a/UnityProject/ProjectSettings/EditorBuildSettings.asset +++ b/UnityProject/ProjectSettings/EditorBuildSettings.asset @@ -5,5 +5,7 @@ EditorBuildSettings: m_ObjectHideFlags: 0 serializedVersion: 2 m_Scenes: - - enabled: 1 + - enabled: 0 path: Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Asteroids.unity + - enabled: 1 + path: Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/SpaceFighter.unity diff --git a/UnityProject/ProjectSettings/ProjectSettings.asset b/UnityProject/ProjectSettings/ProjectSettings.asset index 61e3236b5..be84e671f 100644 --- a/UnityProject/ProjectSettings/ProjectSettings.asset +++ b/UnityProject/ProjectSettings/ProjectSettings.asset @@ -3,7 +3,7 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 8 + serializedVersion: 10 productGUID: 5ed61df0b8965e44b81c9baf7e91dc14 AndroidProfiler: 0 defaultScreenOrientation: 0 @@ -14,21 +14,46 @@ PlayerSettings: productName: Asteroids defaultCursor: {fileID: 0} cursorHotspot: {x: 0, y: 0} - m_SplashScreenStyle: 0 + m_SplashScreenBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21176471, a: 1} m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_SplashScreenBackgroundLandscape: {fileID: 0} + m_SplashScreenBackgroundPortrait: {fileID: 0} m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} defaultScreenWidth: 1024 defaultScreenHeight: 768 defaultScreenWidthWeb: 960 defaultScreenHeightWeb: 600 - m_RenderingPath: 1 - m_MobileRenderingPath: 1 + m_StereoRenderingPath: 0 m_ActiveColorSpace: 0 m_MTRendering: 1 m_MobileMTRendering: 0 m_StackTraceTypes: 010000000100000001000000010000000100000001000000 iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 + tizenShowActivityIndicatorOnLoading: -1 iosAppInBackgroundBehavior: 0 displayResolutionDialog: 1 iosAllowHTTPDownload: 1 @@ -43,7 +68,7 @@ PlayerSettings: defaultIsNativeResolution: 1 runInBackground: 1 captureSingleScreen: 0 - Override IPod Music: 0 + muteOtherAudioSources: 0 Prepare IOS For Recording: 0 submitAnalytics: 1 usePlayerLog: 1 @@ -75,7 +100,6 @@ PlayerSettings: xboxOneResolution: 0 xboxOneMonoLoggingLevel: 0 xboxOneLoggingLevel: 1 - ps3SplashScreen: {fileID: 0} videoMemoryForVertexBuffers: 0 psp2PowerMode: 0 psp2AcquireBGM: 1 @@ -97,9 +121,9 @@ PlayerSettings: bundleIdentifier: com.Asteroids bundleVersion: 1.0 preloadedAssets: [] - metroEnableIndependentInputSource: 0 + metroInputSource: 0 + m_HolographicPauseOnTrackingLoss: 1 xboxOneDisableKinectGpuReservation: 0 - singlePassStereoRendering: 0 protectGraphicsMemory: 0 AndroidBundleVersionCode: 1 AndroidMinSdkVersion: 9 @@ -120,9 +144,10 @@ PlayerSettings: serializedVersion: 2 m_Bits: 238 iPhoneSdkVersion: 988 - iPhoneTargetOSVersion: 22 + iOSTargetOSVersionString: 6.0 tvOSSdkVersion: 0 - tvOSTargetOSVersion: 900 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 0 uIRequiresFullScreen: 1 @@ -143,6 +168,7 @@ PlayerSettings: tvOSSmallIconLayers: [] tvOSLargeIconLayers: [] tvOSTopShelfImageLayers: [] + tvOSTopShelfImageWideLayers: [] iOSLaunchScreenType: 0 iOSLaunchScreenPortrait: {fileID: 0} iOSLaunchScreenLandscape: {fileID: 0} @@ -162,6 +188,12 @@ PlayerSettings: iOSLaunchScreeniPadCustomXibPath: iOSDeviceRequirements: [] iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + appleEnableAutomaticSigning: 0 AndroidTargetDevice: 0 AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} @@ -191,6 +223,63 @@ PlayerSettings: - m_BuildTarget: AndroidPlayer m_APIs: 08000000 m_Automatic: 0 + m_BuildTargetVRSettings: + - m_BuildTarget: Android + m_Enabled: 0 + m_Devices: + - Oculus + - m_BuildTarget: Metro + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: N3DS + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: PS3 + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: PS4 + m_Enabled: 0 + m_Devices: + - PlayStationVR + - m_BuildTarget: PSM + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: PSP2 + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: SamsungTV + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: Standalone + m_Enabled: 0 + m_Devices: + - Oculus + - m_BuildTarget: Tizen + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: WebGL + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: WebPlayer + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: WiiU + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: Xbox360 + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: XboxOne + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: iOS + m_Enabled: 0 + m_Devices: [] + - m_BuildTarget: tvOS + m_Enabled: 0 + m_Devices: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 webPlayerTemplate: APPLICATION:Default m_TemplateCustomTags: {} wiiUTitleID: 0005000011000000 @@ -209,12 +298,15 @@ PlayerSettings: wiiUSystemHeapSize: 128 wiiUTVStartupScreen: {fileID: 0} wiiUGamePadStartupScreen: {fileID: 0} + wiiUDrcBufferDisabled: 0 wiiUProfilerLibPath: actionOnDotNetUnhandledException: 1 enableInternalProfiler: 0 logObjCUncaughtExceptions: 1 enableCrashReportAPI: 0 + cameraUsageDescription: locationUsageDescription: + microphoneUsageDescription: XboxTitleId: XboxImageXexPath: XboxSpaPath: @@ -225,24 +317,6 @@ PlayerSettings: xboxAdditionalTitleMemorySize: 0 xboxDeployKinectHeadOrientation: 0 xboxDeployKinectHeadPosition: 0 - ps3TitleConfigPath: - ps3DLCConfigPath: - ps3ThumbnailPath: - ps3BackgroundPath: - ps3SoundPath: - ps3NPAgeRating: 12 - ps3TrophyCommId: - ps3NpCommunicationPassphrase: - ps3TrophyPackagePath: - ps3BootCheckMaxSaveGameSizeKB: 128 - ps3TrophyCommSig: - ps3SaveGameSlots: 1 - ps3TrialMode: 0 - ps3VideoMemoryForAudio: 0 - ps3EnableVerboseMemoryStats: 0 - ps3UseSPUForUmbra: 0 - ps3EnableMoveSupport: 1 - ps3DisableDolbyEncoding: 0 ps4NPAgeRating: 12 ps4NPTitleSecret: ps4NPTrophyPackPath: @@ -254,7 +328,9 @@ PlayerSettings: ps4AppType: 0 ps4ParamSfxPath: ps4VideoOutPixelFormat: 0 - ps4VideoOutResolution: 4 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 120 ps4PronunciationXMLPath: ps4PronunciationSIGPath: ps4BackgroundImagePath: @@ -276,6 +352,7 @@ PlayerSettings: ps4ApplicationParam4: 0 ps4DownloadDataSize: 0 ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ ps4UseDebugIl2cppLibs: 0 ps4pnSessions: 1 @@ -283,9 +360,12 @@ PlayerSettings: ps4pnFriends: 1 ps4pnGameCustomData: 1 playerPrefsSupport: 0 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 ps4ReprojectionSupport: 0 ps4UseAudio3dBackend: 0 ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 3 ps4Audio3dVirtualSpeakerCount: 14 ps4attribCpuUsage: 0 ps4PatchPkgPath: @@ -298,6 +378,9 @@ PlayerSettings: ps4attribShareSupport: 0 ps4attribExclusiveVR: 0 ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 ps4IncludedModules: [] monoEnv: psp2Splashimage: {fileID: 0} @@ -348,11 +431,38 @@ PlayerSettings: psp2InfoBarColor: 0 psp2UseDebugIl2cppLibs: 0 psmSplashimage: {fileID: 0} + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} spritePackerPolicy: + webGLMemorySize: 256 + webGLExceptionSupport: 0 + webGLDataCaching: 0 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLUseWasm: 0 + webGLCompressionFormat: 1 scriptingDefineSymbols: {} + platformArchitecture: + iOS: 2 + scriptingBackend: + Android: 0 + Metro: 1 + Standalone: 0 + WP8: 2 + WebGL: 1 + iOS: 0 + incrementalIl2cppBuild: + iOS: 0 + additionalIl2CppArgs: + m_RenderingPath: 1 + m_MobileRenderingPath: 1 metroPackageName: Game1 metroPackageVersion: - metroCertificatePath: C:\Projects\zenject\UnityProject\Assets\WSATestCertificate.pfx + metroCertificatePath: Assets/WSATestCertificate.pfx metroCertificatePassword: metroCertificateSubject: ModestTree metroCertificateIssuer: ModestTree @@ -380,6 +490,8 @@ PlayerSettings: tizenSigningProfileName: tizenGPSPermissions: 0 tizenMicrophonePermissions: 0 + tizenDeploymentTarget: + tizenDeploymentTargetType: -252843268 tizenMinOSVersion: 0 n3dsUseExtSaveData: 0 n3dsCompressStaticMem: 1 @@ -410,139 +522,27 @@ PlayerSettings: XboxOnePackageEncryption: 0 XboxOnePackageUpdateGranularity: 2 XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} XboxOneIsContentPackage: 0 XboxOneEnableGPUVariability: 0 XboxOneSockets: {} XboxOneSplashScreen: {fileID: 0} XboxOneAllowedProductIds: [] XboxOnePersistentLocalStorageSize: 0 - intPropertyNames: - - Android::ScriptingBackend - - Metro::ScriptingBackend - - Standalone::ScriptingBackend - - WP8::ScriptingBackend - - WebGL::ScriptingBackend - - WebGL::audioCompressionFormat - - WebGL::exceptionSupport - - WebGL::memorySize - - iOS::Architecture - - iOS::EnableIncrementalBuildSupportForIl2cpp - - iOS::ScriptingBackend - Android::ScriptingBackend: 0 - Metro::ScriptingBackend: 1 - Standalone::ScriptingBackend: 0 - WP8::ScriptingBackend: 2 - WebGL::ScriptingBackend: 1 - WebGL::audioCompressionFormat: 4 - WebGL::exceptionSupport: 0 - WebGL::memorySize: 256 - iOS::Architecture: 2 - iOS::EnableIncrementalBuildSupportForIl2cpp: 0 - iOS::ScriptingBackend: 0 - boolPropertyNames: - - Android::VR::enable - - Metro::VR::enable - - N3DS::VR::enable - - PS3::VR::enable - - PS4::VR::enable - - PSM::VR::enable - - PSP2::VR::enable - - SamsungTV::VR::enable - - Standalone::VR::enable - - Tizen::VR::enable - - WebGL::VR::enable - - WebGL::analyzeBuildSize - - WebGL::dataCaching - - WebGL::useEmbeddedResources - - WebPlayer::VR::enable - - WiiU::VR::enable - - Xbox360::VR::enable - - XboxOne::VR::enable - - iOS::VR::enable - - tvOS::VR::enable - Android::VR::enable: 0 - Metro::VR::enable: 0 - N3DS::VR::enable: 0 - PS3::VR::enable: 0 - PS4::VR::enable: 0 - PSM::VR::enable: 0 - PSP2::VR::enable: 0 - SamsungTV::VR::enable: 0 - Standalone::VR::enable: 0 - Tizen::VR::enable: 0 - WebGL::VR::enable: 0 - WebGL::analyzeBuildSize: 0 - WebGL::dataCaching: 0 - WebGL::useEmbeddedResources: 0 - WebPlayer::VR::enable: 0 - WiiU::VR::enable: 0 - Xbox360::VR::enable: 0 - XboxOne::VR::enable: 0 - iOS::VR::enable: 0 - tvOS::VR::enable: 0 - stringPropertyNames: - - Analytics_ServiceEnabled::Analytics_ServiceEnabled - - Build_ServiceEnabled::Build_ServiceEnabled - - Collab_ServiceEnabled::Collab_ServiceEnabled - - ErrorHub_ServiceEnabled::ErrorHub_ServiceEnabled - - Game_Performance_ServiceEnabled::Game_Performance_ServiceEnabled - - Hub_ServiceEnabled::Hub_ServiceEnabled - - Purchasing_ServiceEnabled::Purchasing_ServiceEnabled - - UNet_ServiceEnabled::UNet_ServiceEnabled - - Unity_Ads_ServiceEnabled::Unity_Ads_ServiceEnabled - - WebGL::emscriptenArgs - - WebGL::template - - additionalIl2CppArgs::additionalIl2CppArgs - Analytics_ServiceEnabled::Analytics_ServiceEnabled: False - Build_ServiceEnabled::Build_ServiceEnabled: False - Collab_ServiceEnabled::Collab_ServiceEnabled: False - ErrorHub_ServiceEnabled::ErrorHub_ServiceEnabled: False - Game_Performance_ServiceEnabled::Game_Performance_ServiceEnabled: False - Hub_ServiceEnabled::Hub_ServiceEnabled: False - Purchasing_ServiceEnabled::Purchasing_ServiceEnabled: False - UNet_ServiceEnabled::UNet_ServiceEnabled: False - Unity_Ads_ServiceEnabled::Unity_Ads_ServiceEnabled: False - WebGL::emscriptenArgs: - WebGL::template: APPLICATION:Default - additionalIl2CppArgs::additionalIl2CppArgs: - vectorPropertyNames: - - Android::VR::enabledDevices - - Metro::VR::enabledDevices - - N3DS::VR::enabledDevices - - PS3::VR::enabledDevices - - PS4::VR::enabledDevices - - PSM::VR::enabledDevices - - PSP2::VR::enabledDevices - - SamsungTV::VR::enabledDevices - - Standalone::VR::enabledDevices - - Tizen::VR::enabledDevices - - WebGL::VR::enabledDevices - - WebPlayer::VR::enabledDevices - - WiiU::VR::enabledDevices - - Xbox360::VR::enabledDevices - - XboxOne::VR::enabledDevices - - iOS::VR::enabledDevices - - tvOS::VR::enabledDevices - Android::VR::enabledDevices: - - Oculus - Metro::VR::enabledDevices: [] - N3DS::VR::enabledDevices: [] - PS3::VR::enabledDevices: [] - PS4::VR::enabledDevices: - - PlayStationVR - PSM::VR::enabledDevices: [] - PSP2::VR::enabledDevices: [] - SamsungTV::VR::enabledDevices: [] - Standalone::VR::enabledDevices: - - Oculus - Tizen::VR::enabledDevices: [] - WebGL::VR::enabledDevices: [] - WebPlayer::VR::enabledDevices: [] - WiiU::VR::enabledDevices: [] - Xbox360::VR::enabledDevices: [] - XboxOne::VR::enabledDevices: [] - iOS::VR::enabledDevices: [] - tvOS::VR::enabledDevices: [] + vrEditorSettings: {} + cloudServicesEnabled: + Analytics: 0 + Build: 0 + Collab: 0 + ErrorHub: 0 + Game_Performance: 0 + Hub: 0 + Purchasing: 0 + UNet: 0 + Unity_Ads: 0 cloudProjectId: projectName: organizationId: diff --git a/UnityProject/ProjectSettings/ProjectVersion.txt b/UnityProject/ProjectSettings/ProjectVersion.txt index 66e05aa78..86d1b1eba 100644 --- a/UnityProject/ProjectSettings/ProjectVersion.txt +++ b/UnityProject/ProjectSettings/ProjectVersion.txt @@ -1 +1 @@ -m_EditorVersion: 5.5.0f3 +m_EditorVersion: 5.5.1f1 From 9182261f75166b159ea1418e9c02cfcb9a5a281f Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Fri, 10 Feb 2017 23:23:52 -0400 Subject: [PATCH 41/62] Bug fix - NonLazy was fixed to only resolve local bindings so that it can be used inside sub containers. Also fixed commands to not use non lazy since they already use IInitializable --- .../Binding/Binders/Factory/FactoryFromBinderBase.cs | 3 ++- .../Source/Binding/Binders/FromBinders/FromBinder.cs | 3 ++- .../Source/Binding/Finalizers/ProviderBindingFinalizer.cs | 5 ++++- .../Source/Editor/Testing/ZenjectIntegrationTestFixture.cs | 2 +- .../Assets/Zenject/Source/Providers/ResolveProvider.cs | 7 +++++-- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs index 29727f078..bb4fb1661 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs @@ -67,7 +67,8 @@ public ConditionCopyNonLazyBinder FromResolve(object subIdentifier) { ProviderFunc = (container) => new ResolveProvider( - ContractType, container, subIdentifier, false); + ContractType, container, + subIdentifier, false, InjectSources.Any); return this; } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index 69a39db56..f9b09042b 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -71,7 +71,8 @@ public ScopeConditionCopyNonLazyBinder FromResolve(object subIdentifier) SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromResolve, subIdentifier, - (container, type) => new ResolveProvider(type, container, subIdentifier, false)); + (container, type) => new ResolveProvider( + type, container, subIdentifier, false, InjectSources.Any)); return new ScopeConditionCopyNonLazyBinder(BindInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs index 101c4d8ea..0c6ba7a4d 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs @@ -59,7 +59,10 @@ public void FinalizeBinding(DiContainer container) { container.RegisterProvider( bindingId, null, new ResolveProvider( - contractType, container, BindInfo.Identifier, false)); + contractType, container, BindInfo.Identifier, false, + // We always want to only use local here so that we can use + // NonLazy() inside subcontainers + InjectSources.Local)); } } } diff --git a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs index 9a47e8625..8b55e90f8 100644 --- a/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs +++ b/UnityProject/Assets/Zenject/Source/Editor/Testing/ZenjectIntegrationTestFixture.cs @@ -33,7 +33,7 @@ public virtual void SetUp() // Don't clear the scene to allow tests to initialize the scene how they // want to set it up manually in their own [Setup] method (eg. TestFromComponentInChildren) // Also, I think unity might already clear the scene anyway? - // ClearScene(); + //ClearScene(); _hasStarted = false; _isValidating = CurrentTestHasAttribute(); diff --git a/UnityProject/Assets/Zenject/Source/Providers/ResolveProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/ResolveProvider.cs index 65a776aa4..a961893dc 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/ResolveProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/ResolveProvider.cs @@ -11,14 +11,17 @@ public class ResolveProvider : IProvider readonly DiContainer _container; readonly Type _contractType; readonly bool _isOptional; + readonly InjectSources _source; public ResolveProvider( - Type contractType, DiContainer container, object identifier, bool isOptional) + Type contractType, DiContainer container, object identifier, + bool isOptional, InjectSources source) { _contractType = contractType; _identifier = identifier; _container = container; _isOptional = isOptional; + _source = source; } public Type GetInstanceType(InjectContext context) @@ -40,7 +43,7 @@ InjectContext GetSubContext(InjectContext parent) { var subContext = parent.CreateSubContext(_contractType, _identifier); - subContext.SourceType = InjectSources.Any; + subContext.SourceType = _source; subContext.Optional = _isOptional; return subContext; From fcb18bb17e388c0848cd1f9754b97ab977a0fbd7 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 11 Feb 2017 16:36:54 -0400 Subject: [PATCH 42/62] Added section on the various DiContainer methods to the readme as well as other tweaks to the docs --- README.md | 399 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 354 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 4fc71724b..734df19c6 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,6 @@ The tests may also be helpful to show usage for each specific feature (which you * Identifiers * Non Generic bindings * Convention Based Binding - * Unbind / Rebind * Singleton Identifiers * Scriptable Object Installer * Runtime Parameters For Installers @@ -129,6 +128,14 @@ The tests may also be helpful to show usage for each specific feature (which you * Zenject Order Of Operations * Injecting data across scenes * Scene Parenting Using Contract Names + * DiContainer Methods + * DiContainer.Instantiate + * DiContainer.Bind + * DiContainer.Resolve + * DiContainer.Inject + * DiContainer.QueueForInject + * DiContainer Unbind / Rebind + * Other DiContainer methods * Scene Decorators * Sub-Containers And Facades * Writing Automated Unit Tests / Integration Tests @@ -274,13 +281,13 @@ public class TestInstaller : MonoInstaller public override void InstallBindings() { Container.Bind().FromInstance("Hello World!"); - Container.Bind().NonLazy(); + Container.Bind().NonLazy(); } } -public class TestRunner +public class Greeter { - public TestRunner(string message) + public Greeter(string message) { Debug.Log(message); } @@ -291,7 +298,7 @@ You can run this example by doing the following: * Create a new scene in Unity * Right Click inside the Hierarchy tab and select `Zenject -> Scene Context` -* Right Click in a folder within the Scene Heirarchy and Choose `Create -> Zenject -> MonoInstaller`. Name it TestInstaller.cs. (Note that you can also just directly create this file too without using this template). +* Right Click in a folder within the Project Tab and Choose `Create -> Zenject -> MonoInstaller`. Name it TestInstaller.cs. (Note that you can also just directly create this file too without using this template). * Add your TestInstaller script to the scene (as its own GameObject or on the same GameObject as the SceneContext, it doesn't matter) * Add a reference to your TestInstaller to the properties of the SceneContext by adding a new row in the inspector of the "Installers" property (press the + button) and then dragging the TestInstaller GameObject to it * Open up TestInstaller and paste the above code into it @@ -300,11 +307,11 @@ You can run this example by doing the following: * Note also, that you can use the shortcut CTRL+SHIFT+R to "validate then run". Validation is usually fast enough that this does not add a noticeable overhead to running your game, and when it does detect errors it is much faster to iterate on since you avoid the startup time. * Observe unity console for output -The SceneContext MonoBehaviour is the entry point of the application, where Zenject sets up all the various dependencies before kicking off your scene. To add content to your Zenject scene, you need to write what is referred to in Zenject as an 'Installer', which declares all the dependencies used in your scene and their relationships with each other. All dependencies that are marked as "NonLazy" are automatically created at this point, as well as any dependencies that implement the standard Zenject interfaces such as `IInitializable`, `ITickable`, etc. If the above doesn't make sense to you yet, keep reading! +The SceneContext MonoBehaviour is the entry point of the application, where Zenject sets up all the various dependencies before kicking off your scene. To add content to your Zenject scene, you need to write what is referred to in Zenject as an 'Installer', which declares all the dependencies used in your scene and their relationships with each other. All dependencies that are marked as "NonLazy" are automatically created at this point, which is why the Greeter class that we added above gets created on startup. If the above doesn't make sense to you yet, keep reading! ## Injection -There are many different ways of binding types on the container, which are documented in the next section. There are also several ways of having these dependencies injected into your classes. These are: +There are many different ways of declaring dependencies on the container, which are documented in the next section. There are also several ways of having these dependencies injected into your classes. These are: 1 - **Constructor Injection** @@ -367,11 +374,11 @@ public class Foo Method Inject injection works very similarly to constructor injection. -Note that these methods are called after all other injection types. It is designed this way so that these methods can be used to execute initialization logic which might make use of one of these dependencies. Note also that you can leave the parameter list empty if you just want to do some initialization logic only. +Note that inject methods are called after all other injection types. It is designed this way so that these methods can be used to execute initialization logic which might make use of one of these dependencies. Note also that you can leave the parameter list empty if you just want to do some initialization logic only. Note that there can be any number of inject methods. In this case, they are called in the order of Base class to Derived class. This can be useful to avoid the need to forward many dependencies from derived classes to the base class via constructor parameters, while also guaranteeing that the base class inject methods complete first, just like how constructors work. -Note that the dependencies that you receive via inject methods should themselves have already been injected. This can be important if you use inject methods to perform some basic initialization, since you may need the given dependencies to themselves be initialized via their Inject methods. +Note that the dependencies that you receive via inject methods should themselves have already been injected (the only exception to this is in the case where you have circular dependencies). This can be important if you use inject methods to perform some basic initialization, since you may need the given dependencies to themselves be initialized via their Inject methods. Using [Inject] methods to inject dependencies is the recommended approach for MonoBehaviours, since MonoBehaviours cannot have constructors. @@ -381,7 +388,7 @@ Using [Inject] methods to inject dependencies is the recommended approach for Mo * Constructor injection forces the dependency to only be resolved once, at class creation, which is usually what you want. In most cases you don't want to expose a public property for your initial dependencies because this suggests that it's open to changing. * Constructor injection guarantees no circular dependencies between classes, which is generally a bad thing to do. You can do this however using method injection or field injection if necessary. * Constructor/Method injection is more portable for cases where you decide to re-use the code without a DI framework such as Zenject. You can do the same with public properties but it's more error prone (it's easier to forget to initialize one field and leave the object in an invalid state) - * Finally, Constructor/Method injection makes it clear what all the dependencies of a class are when another programmer is reading the code. They can simply look at the parameter list of the method. This is also good because it will be more obvious when a class has too many dependencies and should therefore be split up (since it's constructor parameter list will be too long) + * Finally, Constructor/Method injection makes it clear what all the dependencies of a class are when another programmer is reading the code. They can simply look at the parameter list of the method. This is also good because it will be more obvious when a class has too many dependencies and should therefore be split up (since it's constructor parameter list will start to seem long) ## Binding @@ -424,7 +431,7 @@ Container.Bind<ContractType>() .AsScope() .WithArguments(Arguments) .When(Condition) - .InheritInSubContainers() + .CopyIntoAllSubContainers() .NonLazy(); @@ -452,7 +459,7 @@ Where: * It can be one of the following: 1. **AsTransient** - Will not re-use the instance at all. Every time **ContractType** is requested, the DiContainer will return a brand new instance of type **ResultType** 2. **AsCached** - Will re-use the same instance of **ResultType** every time **ContractType** is requested, which it will lazily generate upon first use - 3. **AsSingle** - Will re-use the same instance of **ResultType** across the entire DiContainer, which it will lazily generate upon first use. It can be thought of as a stronger version of AsCached, because it allows you to bind to the same instance across multiple bind commands. It will also ensure that there is only ever exactly one instance of **ResultType** in the DiContainer (ie. it will enforce **ResultType** to be a 'Singleton' hence the name). + 3. **AsSingle** - Will re-use the same instance of **ResultType** across the entire DiContainer, which it will lazily generate upon first use. It can be thought of as a stronger version of AsCached, because it allows you to bind to the same instance across multiple bind commands. It will also ensure that there is only ever exactly one instance of **ResultType** in the DiContainer (ie. it will enforce **ResultType** to be a 'Singleton' hence the name). Note however that it will only guarantee that there is only one instance across the given container, which means that using AsSingle with the same binding in a sub-container could generate a second instance. * In most cases, you will likely want to just use AsSingle, however AsTransient and AsCached have their uses too. * To illustrate the difference between the different scope types, see the following example: @@ -506,9 +513,9 @@ Where: Container.Bind().To().AsSingle(); ``` -* **Arguments** = A list of objects to use when constructing the new instance of type **ResultType**. This can be useful as an alternative to `Container.BindInstance(arg).WhenInjectedInto()` +* **Arguments** = A list of objects to use when constructing the new instance of type **ResultType**. This can be useful as an alternative to adding other bindings for the arguments in the form `Container.BindInstance(arg).WhenInjectedInto()` * **Condition** = The condition that must be true for this binding to be chosen. See here for more details. -* **InheritInSubContainers** = If supplied, then this binding will automatically be inherited from any subcontainers that are created from it. In other words, the result will be equivalent to copying and pasting the `Container.Bind` statement into the installer for every sub-container. +* **CopyIntoAllSubContainers** = If supplied, then this binding will automatically be inherited from any subcontainers that are created from it. In other words, the result will be equivalent to copying and pasting the `Container.Bind` statement into the installer for every sub-container. * **NonLazy** = Normally, the **ResultType** is only ever instantiated when the binding is first used (aka "lazily"). However, when NonLazy is used, **ResultType** will immediately by created on startup. ## Construction Methods @@ -521,7 +528,7 @@ Where: Container.Bind().FromNew(); ``` -1. **FromInstance** - Use a given instance +1. **FromInstance** - Add a given instance to the container. Note that the given instance will not be injected in this case. If you also want your instance to be injected at startup, see QueueForInject ```csharp Container.Bind().FromInstance(new Foo()); @@ -1507,17 +1514,20 @@ Any ITickables, IInitializables, or `IDisposable`'s that are not assigned a prio ## Zenject Order Of Operations -A Zenject driven application is executed by the following steps: +What follows below is a more detailed view of what happens when running a scene that uses Zenject. This can be useful to know to fully understand exactly how Zenject works. * Unity Awake() phase begins * SceneContext.Awake() method is called. This should always be the first thing executed in your scene. It should work this way by default (see here if you are noticing otherwise). - * If this is the first scene to be loaded during this play session, SceneContext will create the ProjectContext prefab. If ProjectContext has already been created by a previous scene, we skip this step and directly initialize the SceneContext - * ProjectContext iterates through all the Installers that have been added to its prefab via the Unity Inspector, updates them to point to its DiContainer, then calls InstallBindings() on each. Each Installer calls some number of Bind<> methods on the DiContainer. - * ProjectContext then injects all MonoBehaviours attached to its game object as well as its children - * ProjectContext then constructs all the non-lazy root objects, which includes any classes that derive from ITickable / IInitializable or IDisposable, as well as those classes that are added with a `NonLazy()` binding. - * SceneContext iterates through all the Installers that have been added to it via the Unity Inspector, updates them to point to its DiContainer, then calls InstallBindings() on each. Each Installer calls some number of Bind<> methods on the DiContainer. - * SceneContext then injects all objects in the scene (except those objects that are parented to the ProjectContext) - * SceneContext then constructs all the non-lazy root objects, which includes any classes that derive from ITickable / IInitializable or IDisposable, as well as those classes that are added with a `NonLazy()` binding. + * Project Context is initialized. Note that this only happens once per play session. If a previous scene already initialized the ProjectContext, then this step is skipped + * All injectable MonoBehaviour's on the ProjectContext prefab are passed to the container via DiContainer.QueueForInject + * ProjectContext iterates through all the Installers that have been added to its prefab via the Unity Inspector, updates them to point to its DiContainer, then calls InstallBindings() on each. Each Installer calls some number of Bind methods on the DiContainer. + * All instances that were added via DiContainer.QueueForInject are injected + * ProjectContext then constructs all the non-lazy root objects, which includes any classes that derive from ITickable / IInitializable or IDisposable, as well as those classes that are added with a `NonLazy()` binding. + * Scene Context is initialized. + * All injectable MonoBehaviour's in the entire scene are passed to the SceneContext container via DiContainer.QueueForInject + * SceneContext iterates through all the Installers that have been added to it via the Unity Inspector, updates them to point to its DiContainer, then calls InstallBindings() on each. Each Installer calls some number of Bind<> methods on the DiContainer. + * All instances that were added via DiContainer.QueueForInject are injected + * SceneContext then constructs all the non-lazy root objects, which includes any classes that derive from ITickable / IInitializable or IDisposable, as well as those classes that are added with a `NonLazy()` binding. * If any required dependencies cannot be resolved, a ZenjectResolveException is thrown * All other MonoBehaviour's in the scene have their Awake() method called * Unity Start() phase begins @@ -1734,6 +1744,327 @@ See here. See here. +## DiContainer Methods + +In addition to the bind methods documented above, there are also some other methods you might want to occasionally use on DiContainer. For example, if you are writing a custom factory, you might want to directly call one of the `DiContainer.Instantaite` methods. Or you might have a situation where another library is creating instances of your classes (for example, a networking library) and you need to manually call DiContainer.Inject. + +DiContainer is always added to itself, so you can always get it injected into any class. However, note that this is usually a sign of bad practice, since there is almost always a better way to design your code such that you don't need to reference DiContainer directly. Once again, best practice with dependency injection is to only reference the DiContainer in the "composition root layer" which includes any custom factories you might have as well as the installers. However there are exceptions to this rule. + +### DiContainer.Instantiate + +These instantiate methods might be useful for example when creating a custom factory. Note however that in most cases, you can probably get away with using a normal Factory instead without needing to directly reference DiContainer. + +When instantiating objects directly, you can either use DiContainer or you can use IInstantiator, which DiContainer inherits from. IInstantiator exists because often, in custom factories, you are only interested in the instantiate operation so you don't need the Bind, Resolve, etc. methods + +1. **Instantiate<T>** - Create the given class using the new operator and then inject it. Note that this method should not be used for Components/MonoBehaviours. However, it can be used for ScriptableObject derived classes (in which case Zenject will automatically call ScriptableObject.CreateInstance). + + ```csharp + Foo foo = Container.Instantiate(); + ``` + + You can also pass extra arguments to it like this: + + ```csharp + Foo foo = Container.Instantiate(new object[] { "foo", 5 }); + ``` + + There is also non-generic versions: + + ```csharp + Foo foo = (Foo)Container.Instantiate(typeof(Foo)); + Foo foo = (Foo)Container.Instantiate(typeof(Foo), new object[] { "foo", 5 }); + ``` + +1. **InstantiatePrefab** - Instantiate the given prefab and then inject into any MonoBehaviour's that are on it. + + ```csharp + GameObject gameObject = Container.InstantiatePrefab(MyPrefab); + ``` + + This method is equivalent to calling `var gameObject = GameObject.Instantiate(MyPrefab)` yourself and then calling `DiContainer.Inject(gameObject)`. Note that MyPrefab above can either be a GameObject or it can be a direct reference to a component on the prefab. + + Similar to `GameObject.Instantiate`, you can also pass an initial parent transform to use: + + ```csharp + GameObject gameObject = Container.InstantiatePrefab(MyPrefab, MyParentTransform); + ``` + +1. **InstantiatePrefabResource** - Same as InstantiatePrefab except instead of passing a prefab, you pass a path within the unity Resources folder where the prefab exists. + + ```csharp + GameObject gameObject = Container.InstantiatePrefabResource("path/to/myprefab"); + ``` + + This method is simply a shortcut to calling `Container.InstantiatePrefab(Resources.Load("path/to/myprefab"));` + +1. **InstantiatePrefabForComponent<T>** - Instantiates the given prefab, injects on the prefab, and then returns the given component which is assumed to exist somewhere in the heirarchy of the prefab. + + ```csharp + var foo = Container.InstantiatePrefabForComponent(FooPrefab) + ``` + + Unlike the InstantiatePrefab methods above, this method also allows passing parameters to the given component: + + ```csharp + var foo = Container.InstantiatePrefabForComponent(FooPrefab, new object[] { "asdf", 6.0f }) + ``` + +1. **InstantiatePrefabResourceForComponent<T>** - Same as InstantiatePrefabForComponent, except the prefab is provided as a resource path instead of as a direct reference + + ```csharp + var foo = Container.InstantiatePrefabResourceForComponent("path/to/fooprefab") + var foo = Container.InstantiatePrefabResourceForComponent("path/to/fooprefab", new object[] { "asdf", 6.0f }) + ``` + +1. **InstantiateComponent<T>** - Add the given component to a given game object. + + ```csharp + var foo = Container.InstantiateComponent(gameObject); + var foo = Container.InstantiateComponent(gameObject, new object[] { "asdf", 6.0f }); + ``` + + Note that this is equivalent to calling GameObject.AddComponent yourself then immediatly calling DiContainer.Inject on the new component instance. + +1. **InstantiateComponentOnNewGameObject<T>** - Create a new empty game object then instantiate a new component of the given type on it + + ```csharp + var foo = Container.InstantiateComponentOnNewGameObject(); + var foo = Container.InstantiateComponentOnNewGameObject(new object[] { "zxcv" }); + ``` + + This is similar to calling `new GameObject()`, then call DiContainer.InstantiateComponent on the result. + +1. **InstantiateScriptableObjectResource<T>** - Instantiate the given ScriptableObject type which is assumed to exist at the given resource path. Note that if you want to create an entirely new ScriptableObject, you can just use DiContainer.Instantiate. + + ```csharp + var foo = Container.InstantiateScriptableObjectResource("path/to/fooscriptableobject") + var foo = Container.InstantiateScriptableObjectResource("path/to/fooscriptableobject", new object[] { "asdf", 6.0f }) + ``` + +### DiContainer.Bind + +See here + +### DiContainer.Resolve + +1. **DiContainer.Resolve** - Get instance to match the given type. This may involve creating a new instance or it might return an existing instance, depending on how the given type was bound. + + ```csharp + Container.Bind().AsSingle(); + ... + var foo = Container.Resolve(); + ``` + + You can also pass an identifier as a parameter: + + ```csharp + Container.Bind().WithId("foo1").AsSingle(); + ... + var foo = Container.Resolve("foo1"); + ``` + + An exception will be thrown if no bindings were found for the given type/identifier, or if multiple bindings were found. See TryResolve / ResolveAll for those cases. + +1. **DiContainer.TryResolve** - Same as DiContainer.Resolve except instead of throwing an exception when a match is not found, a null value is returned. + + ```csharp + var foo = Container.TryResolve(); + + if (foo != null) + { + ... + } + ``` + +1. **DiContainer.ResolveAll** - Same as DiContainer.Resolve except it will return all matches instead of assuming just one. + + ```csharp + List foos = Container.ResolveAll(); + List foos = Container.ResolveAll("foo1"); + ``` + +1. **DiContainer.ResolveType** - Returns the type that would be retrieved/instantiated if Resolve is called with the same type/identifier. + + ```csharp + if (Container.ResolveType() == typeof(Foo)) + { + ... + } + ``` + + This is safe to call during install phase since nothing will be instantiated by calling this. Note also that if there are multiple matches found or zero matches then an exception will be thrown. + +1. **DiContainer.ResolveTypeAll** - Same as ResolveType except returns all matches instead of assuming a single match. + +### DiContainer.Inject + +1. **DiContainer.Inject** - Inject on the given instance. + + ```csharp + Container.Inject(foo); + ``` + + Note that you can also pass extra arguments to inject: + + ```csharp + Container.Inject(foo, new object[] { "asdf", 6 }); + ``` + + This will inject in the following order: + + 1. Fields + 1. Properties + 1. Inject methods + +1. **DiContainer.InjectGameObject** - Inject into all MonoBehaviour's attached to the given game object as well as any children. + + ```csharp + Container.InjectGameObject(gameObject); + ``` + + Note that it will inject in a bottom-up fashion. So the root transforms in the given game object will always be injected last. + +1. **DiContainer.InjectGameObjectForComponent** - Same as InjectGameObject except it will return the given component after injection completes. + + ```csharp + var foo = Container.InjectGameObjectForComponent(gameObject); + ``` + + Also, unlike InjectGameObject, this method supports passing extra arguments to the given component: + + ```csharp + var foo = Container.InjectGameObjectForComponent(gameObject, new object[] { "asdf", 5.1f }); + ``` + + Note however that it is assumed here that there is only one match for the given component. Multiple matches (or zero matches) will generate an exception. + +### DiContainer.QueueForInject + +**DiContainer.QueueForInject** will queue the given instance for injection once the initial object graph is constructed. + +Sometimes, there are instances that are not created by Zenject and which exist at startup, and which you want to be injected. In these cases you will often add them to the container like this: + +```csharp +var foo = new Foo(); +... +Container.Bind().FromInstance(foo); +``` + +Or, equivalently, using this shortcut: + +```csharp +Container.BindInstance(foo); +``` + +However, using FromInstance will not cause the given instance to be injected. + +One approach would be to inject on the instance immediately like this: + +```csharp +Container.BindInstance(foo); +Container.Inject(foo); +``` + +However, this is bad practice. You do not ever want to instantiate or inject during the install phase, because the objects that you are injecting could require bindings that have not yet been added. + +Therefore the correct way to handle these cases is to use QueueForInject: + +```csharp +Container.BindInstance(foo); +Container.QueueForInject(foo); +``` + +This way, our `foo` object will be injected at the same time the initial object graph is constructed, immediately after the install phase. + +Another important advantage of using QueueForInject is that Zenject will guarantee that your instances are injected in the correct order. In other words, if you have the following classes: + +```csharp +class A +{ + [Inject] + public void Init() + { + ... + } +} + +class B +{ + [Inject] + public void Init(A a) + { + ... + } +} +``` + +And they are added to the container this way: + +```csharp +var a = new A(); +var b = new B(); + +Container.BindInstance(a); +Container.BindInstance(b); + +Container.QueueForInject(a); +Container.QueueForInject(b); +``` + +Then, you can assume that A will have its inject method called before B, regardless of the order that they were added to the container. This is nice in the case where you have some initialization logic that occurs in the [Inject] method for B, and which requires that A has been initialized. + +This is also precisely how the initial MonoBehaviour's in the scene are injected. They are all simply added to the container with the QueueForInject method. + +### DiContainer Unbind / Rebind + +It is possible to remove or replace bindings that were added in a previous bind statement. + +1. Unbind - Remove all bindings matching the given type/id from container. + + ```csharp + Container.Bind().To(); + + // This will nullify the above statement + Container.Unbind(); + ``` + +1. Rebind - Override existing bindings with a new one. This is equivalent to calling unbind with the given type and then immediately calling bind afterwards. + + ```csharp + Container.Bind().To(); + + Container.Rebind().To(); + ``` + +### Other DiContainer methods + +1. **DiContainer.ParentContainer** - The parent container for the given DiContainer. For example, for the DiContainer associated with SceneContext, this will usually be the DiContainer associated with the ProjectContext (unless you're using Scene Parenting in which case it will be another SceneContext) +1. **DiContainer.IsValidating** - Returns true if the container is being run for validation. This can be useful in some edge cases where special logic needs to be added during the validation step only. +1. **DiContainer.CreateSubContainer** - Creates a new container as a child of the current container. This might be useful for custom factories that involve creating objects with complex inter-dependencies. For example: + + ```csharp + var subContainer = Container.CreateSubContainer(); + + subContainer.Bind(); + subContainer.Bind(); + subContainer.Bind(); + + var foo = subContainer.Resolve(); + ``` + + Although in most cases you should probably use the FromSubContainerResolve methods rather than doing it this way. + +1. **DiContainer.HasBinding** - Returns true if a binding that matches the given type/id has already been added. This can be useful if you want to avoid adding a duplicate binding that may have been added in a previous installer + + ```csharp + if (!Container.HasBinding()) + { + Container.Bind().To().AsSingle(); + } + ``` + +1. **DiContainer.GetDependencyContracts** - Returns a list of all the types that the given type depends on. This might be useful, for exmaple, if you wanted to do some static analysis of your project, or if you wanted to automatically generate a dependency diagram, etc. + ## Non Generic bindings In some cases you may not know the exact type you want to bind at compile time. In these cases you can use the overload of the `Bind` method which takes a `System.Type` value instead of a generic parameter. @@ -1898,28 +2229,6 @@ Note that you can chain together any combination of the below conditionals in th This is equivalent to calling `Container.BindAllInterfaces().To()` for every type in the namespace "MyGame.Things". This works because, as touched on above, Zenject will skip any bindings in which the concrete type does not actually derive from the base type. So even though we are using `AllInterfaces` which matches every single interface in every single loaded assembly, this is ok because it will not try and bind an interface to a type that doesn't implement this interface. -## Unbind / Rebind - -It is also possible to remove or replace bindings that were added in another bind statement. - -1. Unbind - Remove binding from container. - - ```csharp - Container.Bind().To(); - - // This will nullify the above statement - Container.Unbind(); - ``` - -1. Rebind - Override an existing binding with a new one. This is equivalent to calling unbind with the given type and then immediately calling bind afterwards. - - ```csharp - Container.Bind().To(); - - // - Container.Rebind().To(); - ``` - ## Singleton Identifiers In addition to normal identifiers, you can also assign an identifer to a given singleton. From 2686831c3e124666c5e7ba162d34bdb9dcfc6a2b Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 11 Feb 2017 18:19:43 -0400 Subject: [PATCH 43/62] - Removed some ambiguous overloads of the Resolve and ResolveAll methods - Fixed subcontainers to work with QueueForInject - Minor tweaks to the parameter list of the InstantiatePrefab methods - Changed back to order the result of GetInjectableMonoBehaviours since that still does kinda matter even when using the lazy injector stuff - Changed to hide LazyInstanceInjector and use DiContainer directly instead --- .../Bindings/Editor/TestDiContainerMethods.cs | 42 ++++ .../Editor/TestFromComponentInSiblings.cs | 11 +- .../Util/Editor/FixtureUtil.cs | 2 +- .../BindInfo/GameObjectCreationParameters.cs | 2 + .../FactoryFromBinder/FactoryFromBinder0.cs | 2 +- .../Binding/Binders/FromBinders/FromBinder.cs | 2 +- .../Finalizers/ProviderBindingFinalizer.cs | 7 +- .../Zenject/Source/Factories/PrefabFactory.cs | 16 +- .../Assets/Zenject/Source/Injection/Lazy.cs | 2 +- .../Install/Contexts/GameObjectContext.cs | 9 +- .../Source/Install/Contexts/ProjectContext.cs | 10 +- .../Source/Install/Contexts/SceneContext.cs | 8 +- .../Install/Contexts/SceneDecoratorContext.cs | 6 +- .../Zenject/Source/Install/MonoInstaller.cs | 2 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 200 ++++++++---------- .../Zenject/Source/Main/IInstantiator.cs | 55 +---- .../Source/Main/LazyInstanceInjector.cs | 5 + .../Source/Providers/GetterProvider.cs | 2 +- .../Source/Providers/InstanceProvider.cs | 8 +- .../SubContainerCreatorByInstaller.cs | 1 + .../SubContainerCreatorByMethod.cs | 6 + .../Zenject/Source/Util/ZenUtilInternal.cs | 14 ++ 22 files changed, 226 insertions(+), 186 deletions(-) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs index 603b1c2e6..dc8ed875e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestDiContainerMethods.cs @@ -199,6 +199,48 @@ public void TestInjectGameObjectForComponentMistake() Assert.Throws(() => Container.InjectGameObjectForComponent(go, new object[] { "sdf" })); } + [Test] + public void TestLazyInstanceInjectorFail() + { + Qux.WasInjected = false; + + var qux = new Qux(); + Container.BindInstance(qux); + + Assert.That(!Qux.WasInjected); + Initialize(); + Assert.That(!Qux.WasInjected); + } + + [Test] + public void TestLazyInstanceInjectorSuccess() + { + Qux.WasInjected = false; + + var qux = new Qux(); + Container.BindInstance(qux); + Container.QueueForInject(qux); + + Assert.That(!Qux.WasInjected); + Initialize(); + Assert.That(Qux.WasInjected); + } + + public class Qux + { + public static bool WasInjected + { + get; + set; + } + + [Inject] + public void Construct() + { + WasInjected = true; + } + } + GameObject GetPrefab(string name) { return FixtureUtil.GetPrefab(ResourcePrefix + name); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs index a580dff7e..2a54640a5 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInSiblings.cs @@ -37,10 +37,12 @@ public void RunTest() { Container.Bind().FromComponentSibling(); Container.Bind().FromComponentSibling(); + Container.Bind().FromComponentSibling(); Initialize(); Assert.IsEqual(_foo.Bar, _bar); + Assert.IsEqual(_foo.IBar, _bar); Assert.IsEqual(_foo.Qux[0], _qux1); Assert.IsEqual(_foo.Qux[1], _qux2); @@ -55,7 +57,11 @@ public class Qux : MonoBehaviour public Qux OtherQux; } - public class Bar : MonoBehaviour + public interface IBar + { + } + + public class Bar : MonoBehaviour, IBar { } @@ -64,6 +70,9 @@ public class Foo : MonoBehaviour [Inject] public Bar Bar; + [Inject] + public IBar IBar; + [Inject] public List Qux; } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Util/Editor/FixtureUtil.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Util/Editor/FixtureUtil.cs index 9fcd67869..d410fd3f4 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Util/Editor/FixtureUtil.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Util/Editor/FixtureUtil.cs @@ -70,7 +70,7 @@ static IEnumerable GetDescendants(Transform parent) public static void AssertResolveCount( DiContainer container, int expectedNum) { - var actualCount = container.ResolveAll(true).Count; + var actualCount = container.ResolveAll().Count; Assert.That(actualCount == expectedNum, "Expected to find '{0}' instances of type '{1}' but instead found '{2}'", expectedNum, typeof(TContract).Name(), actualCount); diff --git a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/GameObjectCreationParameters.cs b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/GameObjectCreationParameters.cs index 98be48aac..8afb3e764 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/BindInfo/GameObjectCreationParameters.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/BindInfo/GameObjectCreationParameters.cs @@ -31,6 +31,8 @@ public Func ParentTransformGetter set; } + public static readonly GameObjectCreationParameters Default = new GameObjectCreationParameters(); + public override int GetHashCode() { unchecked // Overflow is fine, just wrap diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs index b913de454..e1e0468cc 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/FactoryFromBinder0.cs @@ -38,7 +38,7 @@ public ConditionCopyNonLazyBinder FromInstance(object instance) BindingUtil.AssertInstanceDerivesFromOrEqual(instance, AllParentTypes); ProviderFunc = - (container) => new InstanceProvider(container, ContractType, instance); + (container) => new InstanceProvider(ContractType, instance, container); return this; } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index f9b09042b..bd9da70a5 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -310,7 +310,7 @@ protected ScopeConditionCopyNonLazyBinder FromInstanceBase(object instance, bool BindInfo.RequireExplicitScope = false; SubFinalizer = new ScopableBindingFinalizer( BindInfo, SingletonTypes.FromInstance, instance, - (container, type) => new InstanceProvider(container, type, instance)); + (container, type) => new InstanceProvider(type, instance, container)); return new ScopeConditionCopyNonLazyBinder(BindInfo); } diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs index 0c6ba7a4d..f9493e2e3 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs @@ -27,8 +27,11 @@ protected ScopeTypes GetScope() { if (BindInfo.Scope == ScopeTypes.Unset) { - Assert.That(!BindInfo.RequireExplicitScope, - "Scope must be set for the given binding {0}! Please either specify AsTransient, AsCached, or AsSingle.", BindInfo.ContextInfo ?? ""); + // If condition is set then it's probably fine to allow the default of transient + Assert.That(!BindInfo.RequireExplicitScope || BindInfo.Condition != null, + "Scope must be set for the previous binding! Please either specify AsTransient, AsCached, or AsSingle. Last binding: Contract: {0}, Identifier: {1} {2}", + BindInfo.ContractTypes.Select(x => x.ToString()).Join(", "), BindInfo.Identifier, + BindInfo.ContextInfo != null ? "Context: '{0}'".Fmt(BindInfo.ContextInfo) : ""); return ScopeTypes.Transient; } diff --git a/UnityProject/Assets/Zenject/Source/Factories/PrefabFactory.cs b/UnityProject/Assets/Zenject/Source/Factories/PrefabFactory.cs index ee29818a5..d0fee5130 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/PrefabFactory.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/PrefabFactory.cs @@ -48,8 +48,8 @@ public virtual T Create(UnityEngine.Object prefab, P1 param) Assert.That(prefab != null, "Null prefab given to factory create method when instantiating object with type '{0}'.", typeof(T)); - return _container.InstantiatePrefabForComponentExplicit( - prefab, InjectUtil.CreateArgListExplicit(param)); + return (T)_container.InstantiatePrefabForComponentExplicit( + typeof(T), prefab, InjectUtil.CreateArgListExplicit(param)); } public virtual T Create(string prefabResourceName, P1 param) @@ -73,8 +73,8 @@ public virtual T Create(UnityEngine.Object prefab, P1 param, P2 param2) Assert.That(prefab != null, "Null prefab given to factory create method when instantiating object with type '{0}'.", typeof(T)); - return _container.InstantiatePrefabForComponentExplicit( - prefab, InjectUtil.CreateArgListExplicit(param, param2)); + return (T)_container.InstantiatePrefabForComponentExplicit( + typeof(T), prefab, InjectUtil.CreateArgListExplicit(param, param2)); } public virtual T Create(string prefabResourceName, P1 param, P2 param2) @@ -98,8 +98,8 @@ public virtual T Create(UnityEngine.Object prefab, P1 param, P2 param2, P3 param Assert.That(prefab != null, "Null prefab given to factory create method when instantiating object with type '{0}'.", typeof(T)); - return _container.InstantiatePrefabForComponentExplicit( - prefab, InjectUtil.CreateArgListExplicit(param, param2, param3)); + return (T)_container.InstantiatePrefabForComponentExplicit( + typeof(T), prefab, InjectUtil.CreateArgListExplicit(param, param2, param3)); } public virtual T Create(string prefabResourceName, P1 param, P2 param2, P3 param3) @@ -123,8 +123,8 @@ public virtual T Create(UnityEngine.Object prefab, P1 param, P2 param2, P3 param Assert.That(prefab != null, "Null prefab given to factory create method when instantiating object with type '{0}'.", typeof(T)); - return _container.InstantiatePrefabForComponentExplicit( - prefab, InjectUtil.CreateArgListExplicit(param, param2, param3, param4)); + return (T)_container.InstantiatePrefabForComponentExplicit( + typeof(T), prefab, InjectUtil.CreateArgListExplicit(param, param2, param3, param4)); } public virtual T Create(string prefabResourceName, P1 param, P2 param2, P3 param3, P4 param4) diff --git a/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs b/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs index 48d6e83d7..19e896b50 100644 --- a/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs +++ b/UnityProject/Assets/Zenject/Source/Injection/Lazy.cs @@ -36,7 +36,7 @@ public T Value { if (!_hasValue) { - _value = _container.Resolve(_context); + _value = (T)_container.Resolve(_context); _hasValue = true; } diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs index b4f061319..01c808d3f 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/GameObjectContext.cs @@ -44,16 +44,15 @@ public void Construct( _container = parentContainer.CreateSubContainer(); - _container.LazyInstanceInjector - .AddInstances(GetInjectableMonoBehaviours().Cast()); - - foreach (var instance in _container.LazyInstanceInjector.Instances) + foreach (var instance in GetInjectableMonoBehaviours().Cast()) { if (instance is MonoKernel) { Assert.That(ReferenceEquals(instance, _kernel), "Found MonoKernel derived class that is not hooked up to GameObjectContext. If you use MonoKernel, you must indicate this to GameObjectContext by dragging and dropping it to the Kernel field in the inspector"); } + + _container.QueueForInject(instance); } _container.IsInstalling = true; @@ -69,7 +68,7 @@ public void Construct( Log.Debug("GameObjectContext: Injecting into child components..."); - _container.LazyInstanceInjector.LazyInjectAll(); + _container.FlushInjectQueue(); Assert.That(_dependencyRoots.IsEmpty()); _dependencyRoots.AddRange(_container.ResolveDependencyRoots()); diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs index 5ac74d8b3..d037453e9 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/ProjectContext.cs @@ -134,8 +134,10 @@ void Initialize() _container = new DiContainer( StaticContext.Container, isValidating); - _container.LazyInstanceInjector.AddInstances( - GetInjectableMonoBehaviours().Cast()); + foreach (var instance in GetInjectableMonoBehaviours().Cast()) + { + _container.QueueForInject(instance); + } _container.IsInstalling = true; @@ -148,7 +150,7 @@ void Initialize() _container.IsInstalling = false; } - _container.LazyInstanceInjector.LazyInjectAll(); + _container.FlushInjectQueue(); Assert.That(_dependencyRoots.IsEmpty()); @@ -169,7 +171,7 @@ void InstallBindings() // We could add the contents of GuiRenderer into MonoKernel, but this adds // undesirable per-frame allocations. See comment in IGuiRenderable.cs for usage // - // Short answer is if you want to use IGuiRenderable then + // Short answer is if you want to use IGuiRenderable then // you need to include the following in project context installer: // `Container.Bind().FromNewComponentOnNewGameObject().AsSingle().CopyIntoAllSubContainers().NonLazy();` _container.Bind(typeof(TickableManager), typeof(InitializableManager), typeof(DisposableManager), typeof(GuiRenderableManager)) diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs index feb37a1e6..87efcf58e 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneContext.cs @@ -217,8 +217,10 @@ public void Install() // so that it doesn't inject on the game object twice // InitialComponentsInjecter will also guarantee that any component that is injected into // another component has itself been injected - _container.LazyInstanceInjector - .AddInstances(GetInjectableMonoBehaviours().Cast()); + foreach (var instance in GetInjectableMonoBehaviours().Cast()) + { + _container.QueueForInject(instance); + } foreach (var decoratorContext in _decoratorContexts) { @@ -245,7 +247,7 @@ public void Resolve() Assert.That(!_hasResolved); _hasResolved = true; - _container.LazyInstanceInjector.LazyInjectAll(); + _container.FlushInjectQueue(); Log.Debug("SceneContext: Resolving dependency roots..."); diff --git a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs index fb50ecce4..0a5fadd5e 100644 --- a/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs +++ b/UnityProject/Assets/Zenject/Source/Install/Contexts/SceneDecoratorContext.cs @@ -44,8 +44,10 @@ public void Initialize(DiContainer container) Assert.IsNull(_container); _container = container; - container.LazyInstanceInjector - .AddInstances(GetInjectableMonoBehaviours().Cast()); + foreach (var instance in GetInjectableMonoBehaviours().Cast()) + { + container.QueueForInject(instance); + } } public void InstallDecoratorSceneBindings() diff --git a/UnityProject/Assets/Zenject/Source/Install/MonoInstaller.cs b/UnityProject/Assets/Zenject/Source/Install/MonoInstaller.cs index 8cfe920f6..b67effbf8 100644 --- a/UnityProject/Assets/Zenject/Source/Install/MonoInstaller.cs +++ b/UnityProject/Assets/Zenject/Source/Install/MonoInstaller.cs @@ -140,7 +140,7 @@ public static TInstaller CreateInstaller( string resourcePath, DiContainer container) where TInstaller : MonoInstallerBase { - var gameObj = container.CreateAndParentPrefabResource(resourcePath, new GameObjectCreationParameters()); + var gameObj = container.CreateAndParentPrefabResource(resourcePath, GameObjectCreationParameters.Default); var installers = gameObj.GetComponentsInChildren(); diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index ed11c343d..bc739d881 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -118,11 +118,6 @@ public DiContainer(DiContainer parentContainer) { } - public LazyInstanceInjector LazyInstanceInjector - { - get { return _lazyInjector; } - } - // When true, this will throw exceptions whenever we create new game objects // This is helpful when used in places like EditorWindowKernel where we can't // assume that there is a "scene" to place objects @@ -132,12 +127,12 @@ public bool AssertOnNewGameObjects set; } - public SingletonMarkRegistry SingletonMarkRegistry + internal SingletonMarkRegistry SingletonMarkRegistry { get { return _singletonMarkRegistry; } } - public SingletonProviderCreator SingletonProviderCreator + internal SingletonProviderCreator SingletonProviderCreator { get { return _singletonProviderCreator; } } @@ -260,6 +255,22 @@ public DiContainer CreateSubContainer() return CreateSubContainer(_isValidating); } + public void QueueForInject(object instance) + { + _lazyInjector.AddInstance(instance); + } + + public void FlushInjectQueue() + { + _lazyInjector.LazyInjectAll(); + } + + // Do not use this + internal void OnInstanceResolved(object instance) + { + _lazyInjector.OnInstanceResolved(instance); + } + DiContainer CreateSubContainer(bool isValidating) { return new DiContainer(this, isValidating); @@ -1183,7 +1194,7 @@ public T InstantiateComponentOnNewGameObject( public GameObject InstantiatePrefab(UnityEngine.Object prefab) { return InstantiatePrefab( - prefab, new GameObjectCreationParameters()); + prefab, GameObjectCreationParameters.Default); } // Create a new game object from a prefab and fill in dependencies for all children @@ -1209,7 +1220,7 @@ public GameObject InstantiatePrefab( // Create a new game object from a resource path and fill in dependencies for all children public GameObject InstantiatePrefabResource(string resourcePath) { - return InstantiatePrefabResource(resourcePath, new GameObjectCreationParameters()); + return InstantiatePrefabResource(resourcePath, GameObjectCreationParameters.Default); } // Create a new game object from a resource path and fill in dependencies for all children @@ -1234,7 +1245,8 @@ public GameObject InstantiatePrefabResource( // and optionally allows extra arguments for the given component type public T InstantiatePrefabForComponent(UnityEngine.Object prefab) { - return InstantiatePrefabForComponent(prefab, new object[0]); + return (T)InstantiatePrefabForComponent( + typeof(T), prefab, null, new object[0]); } // Same as InstantiatePrefab but returns a component after it's initialized @@ -1243,24 +1255,49 @@ public T InstantiatePrefabForComponent( UnityEngine.Object prefab, IEnumerable extraArgs) { return (T)InstantiatePrefabForComponent( - typeof(T), prefab, extraArgs); + typeof(T), prefab, null, extraArgs); + } + + public T InstantiatePrefabForComponent( + UnityEngine.Object prefab, Transform parentTransform) + { + return (T)InstantiatePrefabForComponent( + typeof(T), prefab, parentTransform, new object[0]); + } + + public T InstantiatePrefabForComponent( + UnityEngine.Object prefab, Transform parentTransform, IEnumerable extraArgs) + { + return (T)InstantiatePrefabForComponent( + typeof(T), prefab, parentTransform, extraArgs); } // Same as InstantiatePrefab but returns a component after it's initialized // and optionally allows extra arguments for the given component type public object InstantiatePrefabForComponent( - Type concreteType, UnityEngine.Object prefab, IEnumerable extraArgs) + Type concreteType, UnityEngine.Object prefab, + Transform parentTransform, IEnumerable extraArgs) + { + return InstantiatePrefabForComponent( + concreteType, prefab, extraArgs, + new GameObjectCreationParameters() { ParentTransform = parentTransform }); + } + + public object InstantiatePrefabForComponent( + Type concreteType, UnityEngine.Object prefab, + IEnumerable extraArgs, GameObjectCreationParameters creationInfo) { return InstantiatePrefabForComponentExplicit( concreteType, prefab, - InjectUtil.CreateArgList(extraArgs)); + InjectUtil.CreateArgList(extraArgs), creationInfo); } // Same as InstantiatePrefabResource but returns a component after it's initialized // and optionally allows extra arguments for the given component type public T InstantiatePrefabResourceForComponent(string resourcePath) { - return InstantiatePrefabResourceForComponent(resourcePath, new object[0]); + return (T)InstantiatePrefabResourceForComponent( + typeof(T), resourcePath, null, new object[0]); } // Same as InstantiatePrefabResource but returns a component after it's initialized @@ -1268,19 +1305,37 @@ public T InstantiatePrefabResourceForComponent(string resourcePath) public T InstantiatePrefabResourceForComponent( string resourcePath, IEnumerable extraArgs) { - return (T)InstantiatePrefabResourceForComponent(typeof(T), resourcePath, extraArgs); + return (T)InstantiatePrefabResourceForComponent( + typeof(T), resourcePath, null, extraArgs); + } + + public T InstantiatePrefabResourceForComponent( + string resourcePath, Transform parentTransform) + { + return (T)InstantiatePrefabResourceForComponent( + typeof(T), resourcePath, parentTransform, new object[0]); + } + + public T InstantiatePrefabResourceForComponent( + string resourcePath, Transform parentTransform, IEnumerable extraArgs) + { + return (T)InstantiatePrefabResourceForComponent( + typeof(T), resourcePath, parentTransform, extraArgs); } // Same as InstantiatePrefabResource but returns a component after it's initialized // and optionally allows extra arguments for the given component type public object InstantiatePrefabResourceForComponent( - Type concreteType, string resourcePath, IEnumerable extraArgs) + Type concreteType, string resourcePath, Transform parentTransform, + IEnumerable extraArgs) { Assert.That(!extraArgs.ContainsItem(null), - "Null value given to factory constructor arguments when instantiating object with type '{0}'. In order to use null use InstantiatePrefabForComponentExplicit", concreteType); + "Null value given to factory constructor arguments when instantiating object with type '{0}'. In order to use null use InstantiatePrefabForComponentExplicit", concreteType); return InstantiatePrefabResourceForComponentExplicit( - concreteType, resourcePath, InjectUtil.CreateArgList(extraArgs)); + concreteType, resourcePath, + InjectUtil.CreateArgList(extraArgs), + new GameObjectCreationParameters() { ParentTransform = parentTransform }); } public T InstantiateScriptableObjectResource(string resourcePath) @@ -1418,12 +1473,12 @@ public void Inject(object injectable, IEnumerable extraArgs) // public TContract Resolve() { - return Resolve((string)null); + return Resolve(null); } public TContract Resolve(object identifier) { - return Resolve(new InjectContext(this, typeof(TContract), identifier)); + return (TContract)Resolve(new InjectContext(this, typeof(TContract), identifier)); } // Same as Resolve<> except it will return null if a value for the given type cannot @@ -1431,7 +1486,7 @@ public TContract Resolve(object identifier) public TContract TryResolve() where TContract : class { - return TryResolve((string)null); + return TryResolve(null); } public TContract TryResolve(object identifier) @@ -1461,24 +1516,10 @@ public object Resolve(Type contractType, object identifier) return Resolve(new InjectContext(this, contractType, identifier)); } - // InjectContext can be used to add more constraints to the object that you want to retrieve - public TContract Resolve(InjectContext context) - { - Assert.IsNotNull(context); - - Assert.IsEqual(context.MemberType, typeof(TContract)); - return (TContract) Resolve(context); - } - // Same as Resolve<> except it will return all bindings that are associated with the given type public List ResolveAll() { - return ResolveAll((string)null); - } - - public List ResolveAll(bool optional) - { - return ResolveAll(null, optional); + return ResolveAll(null); } public List ResolveAll(object identifier) @@ -1489,35 +1530,7 @@ public List ResolveAll(object identifier) public List ResolveAll(object identifier, bool optional) { var context = new InjectContext(this, typeof(TContract), identifier, optional); - return ResolveAll(context); - } - - public List ResolveAll(InjectContext context) - { - Assert.IsNotNull(context); - Assert.IsEqual(context.MemberType, typeof(TContract)); - return (List) ResolveAll(context); - } - - public IList ResolveAll(Type contractType) - { - return ResolveAll(contractType, null); - } - - public IList ResolveAll(Type contractType, object identifier) - { - return ResolveAll(contractType, identifier, true); - } - - public IList ResolveAll(Type contractType, bool optional) - { - return ResolveAll(contractType, null, optional); - } - - public IList ResolveAll(Type contractType, object identifier, bool optional) - { - var context = new InjectContext(this, contractType, identifier, optional); - return ResolveAll(context); + return (List)ResolveAll(context); } // Removes all bindings @@ -1774,7 +1787,7 @@ public IdScopeConditionCopyNonLazyBinder BindInstance(TContract insta binding.SubFinalizer = new ScopableBindingFinalizer( bindInfo, SingletonTypes.FromInstance, instance, - (container, type) => new InstanceProvider(container, type, instance)); + (container, type) => new InstanceProvider(type, instance, container)); return new IdScopeConditionCopyNonLazyBinder(bindInfo); } @@ -2026,83 +2039,58 @@ public object InstantiateScriptableObjectResourceExplicit( return newObj; } - // Same as InstantiatePrefabResourceForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public T InstantiatePrefabResourceForComponentExplicit( - string resourcePath, List extraArgs) - { - return (T)InstantiatePrefabResourceForComponentExplicit( - typeof(T), resourcePath, extraArgs); - } - // Same as InstantiatePrefabResourceForComponent except allows null values // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabResourceForComponentExplicit( - Type componentType, string resourcePath, List extraArgs) + Type componentType, string resourcePath, List extraArgs, + GameObjectCreationParameters creationInfo) { return InstantiatePrefabResourceForComponentExplicit( - componentType, resourcePath, new GameObjectCreationParameters(), + componentType, resourcePath, new InjectArgs() { ExtraArgs = extraArgs, Context = new InjectContext(this, componentType, null), - ConcreteIdentifier = null, - }); + }, creationInfo); } - - // Same as InstantiatePrefabResourceForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabResourceForComponentExplicit( - Type componentType, string resourcePath, - GameObjectCreationParameters creationInfo, InjectArgs args) + Type componentType, string resourcePath, InjectArgs args, + GameObjectCreationParameters creationInfo) { var prefab = (GameObject)Resources.Load(resourcePath); Assert.IsNotNull(prefab, "Could not find prefab at resource location '{0}'".Fmt(resourcePath)); return InstantiatePrefabForComponentExplicit( - componentType, prefab, creationInfo, args); + componentType, prefab, args, creationInfo); } - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - public T InstantiatePrefabForComponentExplicit( - UnityEngine.Object prefab, List extraArgs) - { - return (T)InstantiatePrefabForComponentExplicit( - typeof(T), prefab, extraArgs); - } - - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, List extraArgs) + Type componentType, UnityEngine.Object prefab, + List extraArgs) { return InstantiatePrefabForComponentExplicit( - componentType, prefab, extraArgs, new GameObjectCreationParameters()); + componentType, prefab, extraArgs, GameObjectCreationParameters.Default); } - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, List extraArgs, - GameObjectCreationParameters creationInfo) + Type componentType, UnityEngine.Object prefab, + List extraArgs, GameObjectCreationParameters gameObjectBindInfo) { return InstantiatePrefabForComponentExplicit( - componentType, prefab, creationInfo, + componentType, prefab, new InjectArgs() { ExtraArgs = extraArgs, Context = new InjectContext(this, componentType, null), - ConcreteIdentifier = null, - }); + }, gameObjectBindInfo); } // Same as InstantiatePrefabForComponent except allows null values // to be included in the argument list. Also see InjectUtil.CreateArgList public object InstantiatePrefabForComponentExplicit( Type componentType, UnityEngine.Object prefab, - GameObjectCreationParameters gameObjectBindInfo, InjectArgs args) + InjectArgs args, GameObjectCreationParameters gameObjectBindInfo) { Assert.That(!AssertOnNewGameObjects, "Given DiContainer does not support creating new game objects"); diff --git a/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs b/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs index f4b3add42..d090e57b1 100644 --- a/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs +++ b/UnityProject/Assets/Zenject/Source/Main/IInstantiator.cs @@ -48,31 +48,35 @@ T InstantiateComponentOnNewGameObject(string gameObjectName, IEnumerable(UnityEngine.Object prefab); T InstantiatePrefabForComponent( UnityEngine.Object prefab, IEnumerable extraArgs); + T InstantiatePrefabForComponent( + UnityEngine.Object prefab, Transform parentTransform); + T InstantiatePrefabForComponent( + UnityEngine.Object prefab, Transform parentTransform, IEnumerable extraArgs); object InstantiatePrefabForComponent( - Type concreteType, UnityEngine.Object prefab, IEnumerable extraArgs); + Type concreteType, UnityEngine.Object prefab, Transform parentTransform, IEnumerable extraArgs); // Same as InstantiatePrefabResource but returns a component after it's initialized // and optionally allows extra arguments for the given component type T InstantiatePrefabResourceForComponent(string resourcePath); T InstantiatePrefabResourceForComponent( string resourcePath, IEnumerable extraArgs); + T InstantiatePrefabResourceForComponent( + string resourcePath, Transform parentTransform); + T InstantiatePrefabResourceForComponent( + string resourcePath, Transform parentTransform, IEnumerable extraArgs); object InstantiatePrefabResourceForComponent( - Type concreteType, string resourcePath, IEnumerable extraArgs); + Type concreteType, string resourcePath, Transform parentTransform, IEnumerable extraArgs); T InstantiateScriptableObjectResource(string resourcePath) where T : ScriptableObject; @@ -86,45 +90,6 @@ object InstantiateScriptableObjectResource( GameObject CreateEmptyGameObject(string name); #endif - - // The below explicit methods are mostly meant for internal use - // but may be useful to you too if you need to pass in null value arguments - - T InstantiateExplicit(List extraArgs); - object InstantiateExplicit(Type concreteType, List extraArgs); - object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs args); - -#if !NOT_UNITY3D - Component InstantiateComponentExplicit( - Type componentType, GameObject gameObject, List extraArgs); - - object InstantiateScriptableObjectResourceExplicit( - Type scriptableObjectType, string resourcePath, List extraArgs); - - // Same as InstantiatePrefabResourceForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - T InstantiatePrefabResourceForComponentExplicit( - string resourcePath, List extraArgs); - object InstantiatePrefabResourceForComponentExplicit( - Type concreteType, string resourcePath, List extraArgs); - object InstantiatePrefabResourceForComponentExplicit( - Type concreteType, string resourcePath, - GameObjectCreationParameters creationInfo, InjectArgs args); - - // Same as InstantiatePrefabForComponent except allows null values - // to be included in the argument list. Also see InjectUtil.CreateArgList - T InstantiatePrefabForComponentExplicit( - UnityEngine.Object prefab, List extraArgs); - object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, List extraArgs); - object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, List extraArgs, - GameObjectCreationParameters creationInfo); - object InstantiatePrefabForComponentExplicit( - Type componentType, UnityEngine.Object prefab, - GameObjectCreationParameters gameObjectBindInfo, InjectArgs args); -#endif - } } diff --git a/UnityProject/Assets/Zenject/Source/Main/LazyInstanceInjector.cs b/UnityProject/Assets/Zenject/Source/Main/LazyInstanceInjector.cs index 20570d665..a101dc827 100644 --- a/UnityProject/Assets/Zenject/Source/Main/LazyInstanceInjector.cs +++ b/UnityProject/Assets/Zenject/Source/Main/LazyInstanceInjector.cs @@ -30,6 +30,11 @@ public IEnumerable Instances get { return _instancesToInject; } } + public void AddInstance(object instance) + { + _instancesToInject.Add(instance); + } + public void AddInstances(IEnumerable instances) { _instancesToInject.UnionWith(instances); diff --git a/UnityProject/Assets/Zenject/Source/Providers/GetterProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/GetterProvider.cs index c5b8007b1..908237cea 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/GetterProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/GetterProvider.cs @@ -52,7 +52,7 @@ public IEnumerator> GetAllInstancesWithInjectSplit( else { yield return new List() { _method( - _container.Resolve(GetSubContext(context))) }; + (TObj)_container.Resolve(GetSubContext(context))) }; } } } diff --git a/UnityProject/Assets/Zenject/Source/Providers/InstanceProvider.cs b/UnityProject/Assets/Zenject/Source/Providers/InstanceProvider.cs index d6c5cb80a..cdba50f38 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/InstanceProvider.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/InstanceProvider.cs @@ -8,14 +8,14 @@ public class InstanceProvider : IProvider { readonly object _instance; readonly Type _instanceType; - readonly LazyInstanceInjector _lazyInjector; + readonly DiContainer _container; public InstanceProvider( - DiContainer container, Type instanceType, object instance) + Type instanceType, object instance, DiContainer container) { _instanceType = instanceType; _instance = instance; - _lazyInjector = container.LazyInstanceInjector; + _container = container; } public Type GetInstanceType(InjectContext context) @@ -30,7 +30,7 @@ public IEnumerator> GetAllInstancesWithInjectSplit(InjectContext co Assert.That(_instanceType.DerivesFromOrEqual(context.MemberType)); - _lazyInjector.OnInstanceResolved(_instance); + _container.OnInstanceResolved(_instance); yield return new List() { _instance }; } diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs index ecde7eb1f..eccaeadcc 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByInstaller.cs @@ -36,6 +36,7 @@ public DiContainer CreateSubContainer(List args) _installerType, args.Concat(_extraArgs).ToList()); installer.InstallBindings(); + subContainer.FlushInjectQueue(); subContainer.ResolveDependencyRoots(); if (subContainer.IsValidating) diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByMethod.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByMethod.cs index 6f552bb08..66c43a4ca 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByMethod.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByMethod.cs @@ -27,6 +27,7 @@ public DiContainer CreateSubContainer(List args) _installMethod(subContainer); + subContainer.FlushInjectQueue(); subContainer.ResolveDependencyRoots(); if (subContainer.IsValidating) @@ -65,6 +66,7 @@ public DiContainer CreateSubContainer(List args) _installMethod(subContainer, (TParam1)args[0].Value); + subContainer.FlushInjectQueue(); subContainer.ResolveDependencyRoots(); if (subContainer.IsValidating) @@ -107,6 +109,7 @@ public DiContainer CreateSubContainer(List args) (TParam1)args[0].Value, (TParam2)args[1].Value); + subContainer.FlushInjectQueue(); subContainer.ResolveDependencyRoots(); if (subContainer.IsValidating) @@ -151,6 +154,7 @@ public DiContainer CreateSubContainer(List args) (TParam2)args[1].Value, (TParam3)args[2].Value); + subContainer.FlushInjectQueue(); subContainer.ResolveDependencyRoots(); if (subContainer.IsValidating) @@ -197,6 +201,7 @@ public DiContainer CreateSubContainer(List args) (TParam3)args[2].Value, (TParam4)args[3].Value); + subContainer.FlushInjectQueue(); subContainer.ResolveDependencyRoots(); if (subContainer.IsValidating) @@ -245,6 +250,7 @@ public DiContainer CreateSubContainer(List args) (TParam4)args[3].Value, (TParam5)args[4].Value); + subContainer.FlushInjectQueue(); subContainer.ResolveDependencyRoots(); if (subContainer.IsValidating) diff --git a/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs b/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs index 347a3d2bf..446a02a24 100644 --- a/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs +++ b/UnityProject/Assets/Zenject/Source/Util/ZenUtilInternal.cs @@ -65,9 +65,23 @@ public static List GetInjectableMonoBehaviours(GameObject gameObj // BUT we do want to inject on the GameObjectContext itself && UnityUtil.GetParents(x.transform).Intersect(subContexts).IsEmpty() && (x.GetComponent() == null || x is GameObjectContext)) + .OrderByDescending(x => GetParentCount(x.transform)) .ToList(); } + static int GetParentCount(Transform transform) + { + int result = 0; + + while (transform.parent != null) + { + transform = transform.parent; + result++; + } + + return result; + } + public static IEnumerable GetInjectableMonoBehaviours(Scene scene) { return GetRootGameObjects(scene) From 612eda6cc28f86399fdaefc5e2746ce4172d2eb7 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 11 Feb 2017 20:58:06 -0400 Subject: [PATCH 44/62] - More updates to read me. Updated the construction methods section - Updated release notes --- Documentation/ReleaseNotes.md | 200 +++++++++++++++++++++++++++------- README.md | 165 +++++++++++++++++++++------- 2 files changed, 281 insertions(+), 84 deletions(-) diff --git a/Documentation/ReleaseNotes.md b/Documentation/ReleaseNotes.md index 6da0bde64..bc587ee05 100644 --- a/Documentation/ReleaseNotes.md +++ b/Documentation/ReleaseNotes.md @@ -1,7 +1,42 @@ ## Release Notes -4.7 (November 6, 2016) +###5.0 (February 11, 2017) + +New Features +- Added Lazy<> construct so that you can have the resolve occur upon first usage +- Added menu option "Validate All Active Scenes" +- Added support for memory pools. This includes a fluent interface similar to how factories work +- Added DiContainer.QueueForInject method to support adding pre-made instances to the initial inject list + +Changes +- Updated sample projects to be easier to understand +- Improved error messages to include full type names +- Changed list bindings to default to optional so that you don't have to do this explicitly constantly + +Optimizations +- Fixed major performance issue for scenes that have a lot of transforms Re issue #188. +- Fixed to avoid the extra performance costs of calling SetParent by directly passing the parent to the GameObject.Instantiate method issue #188 + +Breaking changes +- Changed to require that the scope be explicitly set for some of the bind methods to avoid extremely common errors of accidentally leaving it as transient. Bind methods that are more like "look ups" (eg. FromMethod, FromComponentInParents, etc.) have it as optional, however bind methods that create new instances require that it be set explicitly +- Moved commands and signals packages into a seperate repo +- Renamed BindAllInterfaces to BindInterfacesTo and BindAllInterfacesAndSelf to BindInterfacesAndSelfTo to avoid the extremely common mistake of forgetting the To +- Removed support for passing arguments to InjectGameObject and InstantiatePrefab methods (issue #125) +- Removed UnityEventManager since it isn't core to keep things lightweight + +Bug fixes +- Fixed extremely rare bug that would cause an infinite loop when using complex subcontainer setups +- Fixed to work with nunit test case attributes +- Fixed to instantiate prefabs without always changing them to be active +- Fixed WithArguments bind method to support passing null values +- Fixed context menu to work properly when creating installers etc. issue #200 +- Fixed issue with ZenUtilInternal.InjectGameObjectForComponent method to support looking up non-monobehaviours. +- Fixed NonLazy() bind method to work properly wtihin sub containers + +--------- + +###4.7 (November 6, 2016) - Removed the concept of triggers in favour of just directly acting on the Signal to both subscribe and fire, since using Trigger was too much overhead for not enough gain - Fixed issue for Windows Store platform where zenject was not properly stripping out the WSA generated constructors - Changed to automatically choose the public constructor if faced with a choice between public and private @@ -9,7 +44,9 @@ - Added support for using the WithArguments bind method combined with FromFactory - Improved validation of multi-scene setups using Contract Names to output better error messages -4.6 (October 23, 2016) +--------- + +###4.6 (October 23, 2016) - Changed Validation to run at edit time rather than requiring that we enter play mode. This is significantly faster. Also added a hotkey to "validate then run" since it's fast enough to use as a pre-run check - Added InstantiateComponentOnNewGameObject method - Changed to install ScriptableObjectInstallers before MonoInstallers since it is common to include settings in ScriptableObjectInstallers (including settings for MonoInstallers) @@ -26,13 +63,17 @@ - Added documentation on ZenjectEditorWindow, Unit Testing, and Integration Testing - Misc. bug fixes -4.5 (September 1, 2016) +--------- + +###4.5 (September 1, 2016) - Fixed DiContainer.ResolveTypeAll() method to properly search in parent containers - Fixed exception that was occuring with Factories when using derived parameter types - Fixed FromResolve to properly search in parent containers - Fixed exception that was occuring with FromMethod when using derived parameter types -4.4 (July 23, 2016) +--------- + +###4.4 (July 23, 2016) - Changed the way installers are called from other installers, to allow strongly typed parameter passing - Added untyped version of FromMethod - Added FromSiblingComponent bind method @@ -40,14 +81,18 @@ - Minor bug fix to command binding to work with InheritInSubcontainers() method - Bug fix - NonLazy method was not working properly when used with ByInstaller or ByMethod -4.3 (June 4, 2016) +--------- + +###4.3 (June 4, 2016) - Changed to disallow using null with BindInstance by default, to catch these errors earlier - Changed to use UnityEngine.Object when referring to prefabs to allow people to get some stronger type checking of prefabs at edit time - (bug fix) for Hololens with Unity 5.4 - (bug fix) Scene decorator property was not being serialized correctly - (bug fix) Custom factories were not validating in some cases -4.2 (May 30, 2016) +--------- + +###4.2 (May 30, 2016) - Finally updated the documentation - Renamed FromGetter to FromGetterResolve - Added some optimizations to convention binding @@ -57,7 +102,9 @@ - (bug) Fixed bug with Unity 5.3.5 where the list of installers would not serialize properly - (but) Fixed minor bug with validation -4.1 (May 15, 2016) +--------- + +###4.1 (May 15, 2016) - Changed ResolveAll method to be optional by default, so it can return the empty list - Removed Zenject.Commands namespace in favour of just Zenject - Added convention based binding (eg. Container.Bind().To(x => x.AllTypes().DerivingFrom())) @@ -76,7 +123,9 @@ - Changed to automatically call ScriptableObject.CreateInstance when creating types that derive from ScriptableObject - Fix to non-unity build -4.0 (April 30, 2016) +--------- + +###4.0 (April 30, 2016) - Added another property to CompositionRoot to specify installers as prefabs re #96 - Changed global composition root to be a prefab instead of assembling together a bunch of ScriptableObject assets re #98 - Changed to lookup Zenject Auto Binding components by default, without the need for AutoBindInstaller. Also added new properties such as CompositionRoot, identifier, and made Component a list. Also works now when put underneath GameObjectCompositionRoot's. @@ -105,18 +154,24 @@ - Renamed BindPriority to BindExecutionOrder - Removed support for binary version of Zenject. This was necessary since Zenject now needs to use some unity defines (eg. UNITY_EDITOR) which doesn't work in DLLs -3.11 (May 15, 2016) +--------- + +###3.11 (May 15, 2016) - Bug fix - Calling Resolve<> or Instantiate<> inside an installer was causing the object to be injected twice - Added StaticCompositionRoot as an even higher level container than ProjectCompositionRoot, for cases where you want to add dependencies directly to the Zenject assembly before Unity even starts up - Bug fix - loading the same scene multiple times with LoadSceneAdditive was not working - Fixed compiler errors with Unity 5.4 -3.10 (March 26, 2016) +--------- + +###3.10 (March 26, 2016) - Fixed to actually support Windows Store platform - Added pause/resume methods to TickableManager - Bug fix - OnlyInjectWhenActive flag did not work on root inactive game objects -3.9 (Feb 7, 2016) +--------- + +###3.9 (Feb 7, 2016) - Added a lot more error checking when using the ToSingle bindings. It will no longer allow mixing different ToSingle types - Fixed ToSingleGameObject and ToSingleMonoBehaviour to allow multiple bindings to the same result - Made it easier to construct SceneCompositionRoot objects dynamically @@ -125,10 +180,14 @@ - Added a bunch of integration tests - Reorganized folder structure -3.8 (Feb 4, 2016) +--------- + +###3.8 (Feb 4, 2016) - Changed back to only initializing the ProjectCompositionRoot when starting a scene with a SceneCompositionRoot rather than always starting it in every scene -3.7 (Jan 31, 2016) +--------- + +###3.7 (Jan 31, 2016) - Changed to not bother parenting transforms to the CompositionRoot object by default (This is still optional with a checkbox however) - Added string parameter to BindMonoBehaviourFactory method to allow specifying the name of an empty GameObject to use for organization - Changed FacadeFactory to inherit from IFactory @@ -138,18 +197,26 @@ - Added optional parameter to the [Inject] attribute to specify which container to retrieve from in the case of nested containers - Fixed some unity-specific bind commands to play more nicely with interfaces -3.6 (Jan 24, 2016) +--------- + +###3.6 (Jan 24, 2016) - Another change to signals to not require parameter types to the bind methods -3.5 (Jan 17, 2016) +--------- + +###3.5 (Jan 17, 2016) - Made breaking change to require separate bind commands for signals and triggers, to allow adding different conditionals on each. -3.4 (Jan 7, 2016) +--------- + +###3.4 (Jan 7, 2016) - Cleaned up directory structure - Fixed bug with Global bindings not getting their Tick() called in the correct order - Fixes to the releases automation scripts -3.2 (December 20, 2015) +--------- + +###3.2 (December 20, 2015) - Added the concept of "Commands" and "Signals". See documentation for details. - Fixed validation for decorator scenes that open decorator scenes. - Changed to be more strict when using a combination of differents kinds of ToSingle<>, since there should only be one way to create the singleton. @@ -167,11 +234,15 @@ - Got the optional Moq extension method ToMock() working again - Fixed scene decorators to play more nicely with Unity's own way of handling LoadLevelAdditive. Decorated scenes are now organized in the scene heirarchy under scene headings just like when calling LoadLevelAdditive normally -3.1 +--------- + +###3.1 - Changes related to upgrading to Unity 5.3 - Fixed again to make zero heap allocations per frame -3.0 +--------- + +###3.0 - Added much better support for nested containers. It now works more closely to what you might expect: Any parent dependencies are always inherited in sub-containers, even for optional injectables. Also removed BindScope and FallbackContainer since these were really just workarounds for this feature missing. Also added [InjectLocal] attribute for cases where you want to inject dependencies only from the local container. - Changed the way execution order is specified in the installers. Now the order for Initialize / Tick / Dispose are all given by one property similar to how unity does it, using ExecutionOrderInstaller - Added ability to pass arguments to Container.Install<> @@ -179,14 +250,20 @@ - Changed validation to be executed on DiContainer instead of through BindingValidator for ease of use - Added automatic support for WebGL by marking constructors as [Inject] -2.8 +--------- + +###2.8 * Fixed to properly use explicit default parameter values in Constructor/PostInject methods. For eg: public Foo(int bar = 5) should consider bar to be optional and use 5 if not resolved. -2.7 +--------- + +###2.7 * Bug fix to ensure global composition root always gets initialized before the scene composition root * Changed scene decorators to use LoadLevelAdditive instead of LoadLevel to allow more complex setups involving potentially several decorators within decorators -2.6 +--------- + +###2.6 * Added new bind methods: ToResource, ToTransientPrefabResource, ToSinglePrefabResource * Added ability to have multiple sets of global installers * Fixed support for using zenject with .NET 4.5 @@ -198,25 +275,35 @@ * Changed to assume any parameters with hard coded default values (eg: int x = 5) are InjectOptional * Fixed bug with asteroids project which was causing exceptions to be thrown on the second run due to the use of tags -2.5 +--------- + +###2.5 * Added support for circular dependencies in the PostInject method or as fields (just not constructor parameters) * Fixed issue with identifiers that was occurring when having both [Inject] and [InjectOptional] attributes on a field/constructor parameter. Now requires that only one be set * Removed BindValue in favour of just using Bind for both reference and value types for simplicity * Removed GameObjectInstantiator class since it was pretty awkward and confusing. Moved methods directly into IInstantiator/DiContainer. See IInstantiator class. * Extracted IResolver and IBinder interfaces from DiContainer -2.4 +--------- + +###2.4 * Refactored the way IFactory is used to be a lot cleaner. It now uses a kind of fluent syntax through its own bind method BindIFactory<> -2.3 +--------- + +###2.3 * Added "ParentContexts" property to InjectContext, to allow very complex conditional bindings that involve potentially several identifiers, etc. * Removed InjectionHelper class and moved methods into DiContainer to simplify API and also to be more discoverable * Added ability to build dlls for use in outside unity from the assembly build solution -2.2 +--------- + +###2.2 * Changed the way installers invoke other installers. Previously you would Bind them to IInstaller and now you call Container.Install instead. This is better because it allows you to immediately call Rebind<> afterwards -2.1 +--------- + +###2.1 * Simplified interface a bit more by moving more methods into DiContainer such as Inject and Instantiate. Moved all helper methods into extension methods for readability. Deleted FieldsInjector and Instantiator classes as part of this * Renamed DiContainer.To() method to ToInstance since I had witnessed some confusion with it for new users. Did the same with ToSingleInstance * Added support for using Zenject outside of Unity by building with the ZEN_NOT_UNITY3D define set @@ -225,8 +312,9 @@ * Renamed DiContainer.ResolveMany to DiContainer.ResolveAll * Added 'InjectFullScene' flag to CompositionRoot to allow injecting across the entire unity scene instead of just objects underneath the CompositionRoot -2.0 +--------- +###2.0 * Added ability to inject dependencies via parameters to the [PostInject] method just like it does with constructors. Especially useful for MonoBehaviours. * Fixed the order that [PostInject] methods are called in for prefabs * Changed singletons created via ToSinglePrefab to identify based on identifier and prefab and not component type. This allows things like ToSingle(prefab1) and ToSingle(prefab1) to use the same prefab, so you can map singletons to multiple components on the same prefab. This also works with interfaces. @@ -236,32 +324,44 @@ * Fixed validation to work properly for ToSinglePrefab * Changed to allow using conditions to override a default binding. When multiple providers are found it will now try and use the one with conditions. So for example you can define a default with `Container.Bind().ToSingle()` and then override for specific classes with `Container.Bind().ToSingle().WhenInjectedInto()`, etc. -1.19 +--------- + +###1.19 * Upgraded to Unity 5 * Added an optional identifier to InjectOptional attribute * Changed the way priorities are interpreted for tickables, disposables, etc. Zero is now used as default for any unspecified priorities. This is helpful because it allows you to choose priorities that occur either before or after the unspecified priorities. * Added some helper methods to ZenEditorUtil for use by CI servers to validate all scenes -1.18 +--------- + +###1.18 * Added minor optimizations to reduce per-frame allocation to zero * Fixed unit tests to be compatible with unity test tools * Minor bug fix with scene decorators, GameObjectInstantiator. -1.17 +--------- + +###1.17 * Bug fix. Was not forwarding parameters correctly when instantiating objects from prefabs -1.16 +--------- + +###1.16 * Removed the word 'ModestTree' from namespaces since Zenject is open source and not proprietary to the company ModestTree. -1.15 +--------- + +###1.15 * Fixed bug with ToSinglePrefab which was causing it to create multiple instances when used in different bindings. -1.14 +--------- + +###1.14 * Added flag to CompositionRoot for whether to inject into inactive game objects or ignore them completely * Added BindAllInterfacesToSingle method to DiContainer @@ -269,11 +369,15 @@ * Added ILateTickable interface, which works just like ITickable or IFixedTickable for unity's LateUpdate event * Added support for 'decorators', which can be used to add dependencies to another scene -1.13 +--------- + +###1.13 * Minor bug fix to global composition root. Also fixed a few compiler warnings. -1.12 +--------- + +###1.12 * Added Rebind<> method * Changed Factories to use strongly typed parameters by default. Also added ability to pass in null values as arguments as well as multiple instances of the same type @@ -284,34 +388,46 @@ * Changed TickableManager to not be a monobehaviour and receive its update from the UnityDependencyRoot instead * Added IFixedTickable class to support unity FixedUpdate method -1.11 +--------- + +###1.11 * Removed Fasterflect library to keep Zenject nice and lightweight (it was also causing issues on WP8) * Fixed bug related to singletons + object graph validation. Changed the way IDisposables are handled to be closer to the way IInitializable and ITickable are handled. Added method to BinderUntyped. -1.10 +--------- + +###1.10 * Added custom editor for the Installers property of CompositionRoot to make re-ordering easier -1.09 +--------- + +###1.09 * Added support for nested containers * Added ability to execute bind commands using Type objects rather than a generic type * Changed the way IDisposable bindings work to be similar to how ITickable and IInitializable work * Bug fixes -1.08 +--------- + +###1.08 * Order of magnitude speed improvement by using more caching * Minor change to API to use the As() method to specify identifiers * Bug fixes -1.07 +--------- + +###1.07 * Simplified API by removing the concept of modules in favour of just having installers instead (and add support for installers installing other installers) * Bug fixes -1.06 +--------- + +###1.06 * Introduced concept of scene installer, renamed installers 'modules' * Bug fixes diff --git a/README.md b/README.md index 734df19c6..2e6fb2121 100644 --- a/README.md +++ b/README.md @@ -451,7 +451,7 @@ Where: * **ConstructionMethod** = The method by which an instance of **ResultType** is created/retrieved. See this section for more details on the various construction methods. * Default: FromNew() - * Examples: eg. FromGetter, FromMethod, FromPrefab, FromResolve, FromSubContainerResolve, FromInstance, etc. + * Examples: eg. FromGetter, FromMethod, FromResolve, FromComponentInNewPrefab, FromSubContainerResolve, FromInstance, etc. * **Scope** = This value determines how often (or if at all) the generated instance is re-used across multiple injections. @@ -553,46 +553,142 @@ Where: } ``` -1. **FromComponent** - Create as a new component on an existing game object. **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case +1. **FromMethodMultiple** - Same as FromMethod except allows returning multiple instances at once. + + ```csharp + Container.Bind().FromMethodMultiple(GetFoos); + + IEnumerable GetFoos(InjectContext context) + { + ... + return new Foo[] + { + new Foo(), + new Foo(), + new Foo(), + } + } + ``` + +1. **FromFactory** - Create instance using a custom factory class. This construction method is similar to `FromMethod` except can be cleaner in cases where the logic is more complicated or requires dependencies (the factory itself can have dependencies injected) + + ```csharp + class FooFactory : IFactory + { + public Foo Create() + { + // ... + return new Foo(); + } + } + + Container.Bind().FromFactory() + ``` + +1. **FromComponentInNewPrefab** - Instantiate the given prefab as a new game object, inject any MonoBehaviour's on it, and then search the result for type **ResultType**. + + ```csharp + Container.Bind().FromComponentInNewPrefab(somePrefab); + ``` + + **ResultType** must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + +1. **FromComponentInNewPrefabResource** - Instantiate the given prefab at the given resource path as a new game object, inject any MonoBehaviour's on it, and then search the result for type **ResultType**. + + ```csharp + Container.Bind().FromComponentInNewPrefabResource("Some/Path/Foo"); + ``` + + **ResultType** must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + +1. **FromNewComponentOnNewGameObject** - Create a new empty game object and then instantiate a new component of the given type on it. + + ```csharp + Container.Bind().FromNewComponentOnNewGameObject(); + ``` + + **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + +1. **FromNewComponentOn** - Add a new component of the given type on the given game object then inject on it. ```csharp Container.Bind().FromComponent(someGameObject); ``` -1. **FromSiblingComponent** - Create as a new component on the same game object where the component is being injected into. **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + +1. **FromNewComponentSibling** - Add a new component on the current transform and inject on it. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type. ```csharp - Container.Bind().FromSiblingComponent(someGameObject); + Container.Bind().FromNewComponentSibling(); ``` -1. **FromGameObject** - Create as a new component on a new game object. **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + + Also note that if a non-MonoBehaviour requests the given type, an exception will be thrown, since there is no current transform in that case. + +1. **FromComponentInHierarchy** - Look up the component within the scene hierarchy associated with the current context, as well as the hierarchy associated with any parent contexts. ```csharp - Container.Bind().FromGameObject(); + Container.Bind().FromComponentInHierarchy(); ``` -1. **FromPrefab** - Create by instantiating the given prefab and then searching it for type **ResultType**. **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + **ResultType** must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + + In the most common case where the context is a SceneContext, this will search the entire scene hierarchy (except any sub-contexts such as GameObjectContext). In other words, when the current context is a scene context, it will behave similar to `GameObject.FindObjectsOfType`. Note that since this could be a big search, it should be used with caution, just like `GameObject.FindObjectsOfType` should be used with caution. + + In the case where the context is GameObjectContext, it will only search within and underneath the game object root (and any parent contexts). + + In the case where the context is ProjectContext, it will only search within the project context prefab + +1. **FromComponentSibling** - Look up the given component type by searching over the components that are attached to the current transform. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type. + + ```csharp + Container.Bind().FromComponentSibling(); + ``` + + **ResultType** must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + + Note that if a non-MonoBehaviour requests the given type, an exception will be thrown, since there is no current transform in that case. + +1. **FromComponentInParents** - Look up the component by searching the current transform or any parent for the given component type. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type. + + ```csharp + Container.Bind().FromComponentInParents(); + ``` + + **ResultType** must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + + Note that if a non-MonoBehaviour requests the given type, an exception will be thrown, since there is no current transform in that case. + +1. **FromComponentInChildren** - Look up the component by searching the current transform or any child transform for the given component type. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type. ```csharp - Container.Bind().FromPrefab(somePrefab); + Container.Bind().FromComponentInChildren(); ``` -1. **FromPrefabResource** - Create by instantiating the prefab at the given resource path and then searching it for type **ResultType**. **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + **ResultType** must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case + + Note that if a non-MonoBehaviour requests the given type, an exception will be thrown, since there is no current transform in that case. + +1. **FromResource** - Create by calling the Unity3d function `Resources.Load` for **ResultType**. This can be used to load any type that `Resources.Load` can load, such as textures, sounds, prefabs, etc. ```csharp - Container.Bind().FromPrefabResource("Some/Path/Foo"); + Container.Bind().WithId("Glass").FromResource("Some/Path/Glass"); ``` -1. **FromResource** - Create by calling the Unity3d function `Resources.Load` for **ResultType**. This can be used to load any type that `Resources.Load` can load, such as textures, sounds, prefabs, custom classes deriving from ScriptableObject, etc. +1. **FromScriptableObjectResource** - Create a new ScriptableObject class by cloning a previously created instance saved to the resources folder. ```csharp public class Foo : ScriptableObject { } - Container.Bind().FromResource("Some/Path/Foo"); + Container.Bind().FromScriptableObjectResource("Some/Path/Foo"); ``` + Note that unlike FromResource, the value returned from Resources.Load in this case will be cloned by calling ScriptableObject.Instantiate. This is necessary to allow multiple instances of the same scriptable object resource. + 1. **FromResolve** - Get instance by doing another lookup on the container (in other words, calling `DiContainer.Resolve()`). Note that for this to work, **ResultType** must be bound in a separate bind statement. This construction method can be especially useful when you want to bind an interface to another interface, as shown in the below example ```csharp @@ -612,22 +708,7 @@ Where: Container.Bind().To(); ``` -1. **FromFactory** - Create instance using a custom factory class. This construction method is similar to `FromMethod` except can be cleaner in cases where the logic is more complicated or requires dependencies (the factory itself can have dependencies injected) - - ```csharp - class FooFactory : IFactory - { - public Foo Create() - { - // ... - return new Foo(); - } - } - - Container.Bind().FromFactory() - ``` - -1. **FromResolveGetter** - Get instance from the property of another dependency which is obtained by doing another lookup on the container (in other words, calling `DiContainer.Resolve()` and then accessing a value on the returned instance of type **ResultType**). Note that for this to work, **ObjectType** must be bound in a separate bind statement. +1. **FromResolveGetter<ObjectType>** - Get instance from the property of another dependency which is obtained by doing another lookup on the container (in other words, calling `DiContainer.Resolve()` and then accessing a value on the returned instance of type **ResultType**). Note that for this to work, **ObjectType** must be bound in a separate bind statement. ```csharp public class Bar @@ -659,7 +740,7 @@ Where: } ``` - 1. **ByInstaller** - Initialize the subcontainer by using a class derived from `Installer`. This can be a cleaner and less error-prone alternative than using `ByMethod`, especially if you need to inject data into the installer itself. Less error prone because when using ByMethod it is common to accidentally use Container instead of subContainer in your method. + 1. **ByInstaller** - Initialize the subcontainer by using a class derived from `Installer`. This can be a cleaner and less error-prone alternative than `ByMethod`, especially if you need to inject data into the installer itself. Less error prone because when using ByMethod it is common to accidentally use Container instead of subContainer in your method. ```csharp Container.Bind().FromSubContainerResolve().ByInstaller(); @@ -673,10 +754,10 @@ Where: } ``` - 1. **ByPrefab** - Initialize subcontainer using a prefab. Note that the prefab must contain a `GameObjectContext` component attached to the root game object. For details on `GameObjectContext` see this section. + 1. **ByNewPrefab** - Initialize subcontainer by instantiating a new prefab. Note that the prefab must contain a `GameObjectContext` component attached to the root game object. For details on `GameObjectContext` see this section. ```csharp - Container.Bind().FromSubContainerResolve().ByPrefab(MyPrefab); + Container.Bind().FromSubContainerResolve().ByNewPrefab(MyPrefab); // Assuming here that this installer is added to the GameObjectContext at the root // of the prefab. You could also use a ZenjectBinding in the case where Foo is a MonoBehaviour @@ -689,10 +770,10 @@ Where: } ``` - 1. **ByPrefabResource** - Initialize subcontainer using a prefab obtained via `Resources.Load`. Note that the prefab must contain a `GameObjectContext` component attached to the root game object. + 1. **ByNewPrefabResource** - Initialize subcontainer instantiating a new prefab obtained via `Resources.Load`. Note that the prefab must contain a `GameObjectContext` component attached to the root game object. ```csharp - Container.Bind().FromSubContainerResolve().ByPrefabResource("Path/To/MyPrefab"); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource("Path/To/MyPrefab"); ``` ## Installers @@ -1064,12 +1145,12 @@ Please feel free to submit any other sources of confusion to sfvermeulen@gmail.c ## Game Object Bind Methods -For bindings that create new game objects (eg. FromPrefab or FromGameObject) there are also two extra bind methods +For bindings that create new game objects (eg. FromComponentInNewPrefab or FromGameObject) there are also two extra bind methods * **WithGameObjectName** = The name to give the new Game Object associated with this binding. ```csharp - Container.Bind().FromPrefabResource("Some/Path/Foo").WithGameObjectName("Foo1"); + Container.Bind().FromComponentInNewPrefabResource("Some/Path/Foo").WithGameObjectName("Foo1"); Container.Bind().FromGameObject().WithGameObjectName("Foo2"); ``` @@ -1077,7 +1158,7 @@ For bindings that create new game objects (eg. FromPrefab or FromGameObject) the ```csharp Container.BindFactory() - .FromPrefab(BulletPrefab) + .FromComponentInNewPrefab(BulletPrefab) .UnderTransformGroup("Bullets"); ``` @@ -1085,7 +1166,7 @@ For bindings that create new game objects (eg. FromPrefab or FromGameObject) the ```csharp Container.BindFactory() - .FromPrefab(BulletPrefab) + .FromComponentInNewPrefab(BulletPrefab) .UnderTransform(BulletTransform); ``` @@ -2253,15 +2334,15 @@ In this case however, two instances will be created. Another use case for this is to allow creating multiple singletons from the same prefab. For example, Given the following: ```csharp -Container.Bind().FromPrefab(MyPrefab).AsSingle(); -Container.Bind().FromPrefab(MyPrefab).AsSingle(); +Container.Bind().FromComponentInNewPrefab(MyPrefab).AsSingle(); +Container.Bind().FromComponentInNewPrefab(MyPrefab).AsSingle(); ``` -It will only instantiate the prefab MyPrefab once, since the singleton is identified solely by the prefab when using `FromPrefab`. The concrete type given can be interpreted as "Search the instantiated prefab for this component". But, if instead you want Zenject to instantiate a new instance of the prefab for each `FromPrefab` binding, then you can do that as well by supplying an identifier to the `AsSingle` function like this: +It will only instantiate the prefab MyPrefab once, since the singleton is identified solely by the prefab when using `FromComponentInNewPrefab`. The concrete type given can be interpreted as "Search the instantiated prefab for this component". But, if instead you want Zenject to instantiate a new instance of the prefab for each `FromComponentInNewPrefab` binding, then you can do that as well by supplying an identifier to the `AsSingle` function like this: ```csharp -Container.Bind().FromPrefab(MyPrefab).AsSingle("foo"); -Container.Bind().FromPrefab(MyPrefab).AsSingle("bar"); +Container.Bind().FromComponentInNewPrefab(MyPrefab).AsSingle("foo"); +Container.Bind().FromComponentInNewPrefab(MyPrefab).AsSingle("bar"); ``` Now two instances of the prefab will be created. From a339319647b7bd5c8ff698469d01c4207d97d656 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 11 Feb 2017 21:06:26 -0400 Subject: [PATCH 45/62] Tweak to release notes --- Documentation/ReleaseNotes.md | 15 +++++++++++++++ README.md | 13 ++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Documentation/ReleaseNotes.md b/Documentation/ReleaseNotes.md index bc587ee05..dc439377e 100644 --- a/Documentation/ReleaseNotes.md +++ b/Documentation/ReleaseNotes.md @@ -8,6 +8,13 @@ New Features - Added menu option "Validate All Active Scenes" - Added support for memory pools. This includes a fluent interface similar to how factories work - Added DiContainer.QueueForInject method to support adding pre-made instances to the initial inject list +- Added new construction methods + - FromMethodMultiple + - FromComponentInHierarchy + - FromComponentSibling + - FromComponentInParents + - FromComponentInChildren + - FromScriptableObjectResource Changes - Updated sample projects to be easier to understand @@ -24,6 +31,14 @@ Breaking changes - Renamed BindAllInterfaces to BindInterfacesTo and BindAllInterfacesAndSelf to BindInterfacesAndSelfTo to avoid the extremely common mistake of forgetting the To - Removed support for passing arguments to InjectGameObject and InstantiatePrefab methods (issue #125) - Removed UnityEventManager since it isn't core to keep things lightweight +- Renamed the Resolve overload that included an ID to ResolveId to avoid the ambiguity with the non generic version of Resolve +- Renamed the following construction methods. This was motivated by the fact that with the new construction methods it's unclear which ones are "look ups" versus creating new instances + - FromComponent => FromNewComponentOn + - FromSiblingComponent => FromNewComponentSibling + - FromGameObject => FromNewComponentOnNewGameObject + - FromPrefab => FromComponentInNewPrefab + - FromPrefabResource => FromComponentInNewPrefabResource + - FromSubContainerResolve.ByPrefab => FromSubContainerResolve.ByNewPrefab Bug fixes - Fixed extremely rare bug that would cause an infinite loop when using complex subcontainer setups diff --git a/README.md b/README.md index 2e6fb2121..4c232f96b 100644 --- a/README.md +++ b/README.md @@ -1936,16 +1936,16 @@ See here var foo = Container.Resolve(); ``` - You can also pass an identifier as a parameter: + An exception will be thrown if no bindings were found for the given type or if multiple bindings were found. See TryResolve / ResolveAll for those cases. + +1. **DiContainer.ResolveId** - Same as resolve except includes an identifier ```csharp Container.Bind().WithId("foo1").AsSingle(); ... - var foo = Container.Resolve("foo1"); + var foo = Container.ResolveId("foo1"); ``` - An exception will be thrown if no bindings were found for the given type/identifier, or if multiple bindings were found. See TryResolve / ResolveAll for those cases. - 1. **DiContainer.TryResolve** - Same as DiContainer.Resolve except instead of throwing an exception when a match is not found, a null value is returned. ```csharp @@ -1957,13 +1957,16 @@ See here } ``` +1. **DiContainer.TryResolveId** - Same as DiContainer.TryResolve except also takes an identifier + 1. **DiContainer.ResolveAll** - Same as DiContainer.Resolve except it will return all matches instead of assuming just one. ```csharp List foos = Container.ResolveAll(); - List foos = Container.ResolveAll("foo1"); ``` +1. **DiContainer.ResolveIdAll** - Same as DiContainer.ResolveAll except also takes an identifier + 1. **DiContainer.ResolveType** - Returns the type that would be retrieved/instantiated if Resolve is called with the same type/identifier. ```csharp From c91a5be60e40b97e60671e224719d0ec8005460c Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sat, 11 Feb 2017 23:46:52 -0400 Subject: [PATCH 46/62] - Renamed FromComponentInPrefab to FromComponentInNewPrefab - Renamed FromSubContainerResolve.ByPrefab to ByNewPrefab - Changed to not use overloads when passing the identifier to the Resolve methods to fix the ambiguity with the non-generic version --- ...omComponentInHierarchyGameObjectContext.cs | 2 +- .../Bindings/Editor/TestFromPrefab.cs | 30 ++-- .../Bindings/Editor/TestFromPrefabResource.cs | 30 ++-- .../Editor/TestFromSubContainerPrefab.cs | 34 ++--- .../TestFromSubContainerPrefabResource.cs | 32 ++--- .../Factories/Editor/TestBindFactory.cs | 22 +-- .../Factories/Editor/TestBindFactoryFive.cs | 16 +-- .../Factories/Editor/TestBindFactoryOne.cs | 16 +-- .../Decorators/Editor/TestSceneDecorators.cs | 2 +- .../Editor/Tests/TestAsteroidManager.cs | 2 +- .../Scripts/Installers/GameInstaller.cs | 2 +- .../Scripts/Installers/GameInstaller.cs | 6 +- .../Editor/Bindings/TestFromResolve.cs | 2 +- .../Conditions/TestConditionsComplex.cs | 4 +- .../Editor/Conditions/TestIdentifiers.cs | 10 +- .../FactorySubContainerBinder0.cs | 8 +- .../FactorySubContainerBinderWithParams.cs | 16 +-- .../Binders/Factory/FactoryFromBinderBase.cs | 4 +- .../Binding/Binders/FromBinders/FromBinder.cs | 12 +- .../Binding/Binders/SubContainerBinder.cs | 4 +- .../SubContainerPrefabBindingFinalizer.cs | 8 +- ...ContainerPrefabResourceBindingFinalizer.cs | 8 +- .../Assets/Zenject/Source/Main/DiContainer.cs | 131 ++++++++++++------ .../Singleton/SingletonProviderCreator.cs | 8 +- ...nerSingletonProviderCreatorByNewPrefab.cs} | 6 +- ...ngletonProviderCreatorByNewPrefab.cs.meta} | 6 +- ...etonProviderCreatorByNewPrefabResource.cs} | 6 +- ...roviderCreatorByNewPrefabResource.cs.meta} | 6 +- ...b.cs => SubContainerCreatorByNewPrefab.cs} | 4 +- ...=> SubContainerCreatorByNewPrefab.cs.meta} | 6 +- ...bContainerCreatorByNewPrefabWithParams.cs} | 4 +- ...ainerCreatorByNewPrefabWithParams.cs.meta} | 6 +- 32 files changed, 249 insertions(+), 204 deletions(-) rename UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/{SubContainerSingletonProviderCreatorByPrefab.cs => SubContainerSingletonProviderCreatorByNewPrefab.cs} (94%) rename UnityProject/Assets/Zenject/Source/Providers/{SubContainerCreators/SubContainerCreatorByPrefab.cs.meta => Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefab.cs.meta} (69%) rename UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/{SubContainerSingletonProviderCreatorByPrefabResource.cs => SubContainerSingletonProviderCreatorByNewPrefabResource.cs} (95%) rename UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/{SubContainerSingletonProviderCreatorByPrefab.cs.meta => SubContainerSingletonProviderCreatorByNewPrefabResource.cs.meta} (69%) rename UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/{SubContainerCreatorByPrefab.cs => SubContainerCreatorByNewPrefab.cs} (91%) rename UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/{SubContainerCreatorByPrefabWithParams.cs.meta => SubContainerCreatorByNewPrefab.cs.meta} (69%) rename UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/{SubContainerCreatorByPrefabWithParams.cs => SubContainerCreatorByNewPrefabWithParams.cs} (93%) rename UnityProject/Assets/Zenject/Source/Providers/{Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs.meta => SubContainerCreators/SubContainerCreatorByNewPrefabWithParams.cs.meta} (69%) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs index bf7653af6..80ba716d2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromComponentInHierarchyGameObjectContext.cs @@ -35,7 +35,7 @@ public override void SetUp() public void TestCorrectHierarchy() { Container.Bind().FromSubContainerResolve() - .ByPrefab(FooPrefab).AsSingle().NonLazy(); + .ByNewPrefab(FooPrefab).AsSingle().NonLazy(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs index 414e0c06e..ad00832be 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefab.cs @@ -45,8 +45,8 @@ GameObject JimAndBobPrefab [Test] public void TestTransient() { - Container.Bind().FromComponentInPrefab(FooPrefab).AsTransient(); - Container.Bind().FromComponentInPrefab(FooPrefab).AsTransient(); + Container.Bind().FromComponentInNewPrefab(FooPrefab).AsTransient(); + Container.Bind().FromComponentInNewPrefab(FooPrefab).AsTransient(); Container.BindRootResolve(); @@ -58,8 +58,8 @@ public void TestTransient() [Test] public void TestSingle() { - Container.Bind().To().FromComponentInPrefab(FooPrefab).AsSingle().NonLazy(); - Container.Bind().FromComponentInPrefab(FooPrefab).AsSingle().NonLazy(); + Container.Bind().To().FromComponentInNewPrefab(FooPrefab).AsSingle().NonLazy(); + Container.Bind().FromComponentInNewPrefab(FooPrefab).AsSingle().NonLazy(); Initialize(); @@ -70,8 +70,8 @@ public void TestSingle() public void TestSingle2() { // For ToPrefab, the 'AsSingle' applies to the prefab and not the type, so this is valid - Container.Bind().To().FromComponentInPrefab(FooPrefab).AsSingle(); - Container.Bind().FromComponentInPrefab(FooPrefab2).AsSingle(); + Container.Bind().To().FromComponentInNewPrefab(FooPrefab).AsSingle(); + Container.Bind().FromComponentInNewPrefab(FooPrefab2).AsSingle(); Container.Bind().FromMethod(ctx => ctx.Container.CreateEmptyGameObject("Foo").AddComponent()); Container.BindRootResolve(); @@ -86,8 +86,8 @@ public void TestSingle2() [Test] public void TestSingleIdentifiers() { - Container.Bind().FromComponentInPrefab(FooPrefab).WithGameObjectName("Foo").AsSingle().NonLazy(); - Container.Bind().FromComponentInPrefab(FooPrefab).WithGameObjectName("Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInNewPrefab(FooPrefab).WithGameObjectName("Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInNewPrefab(FooPrefab).WithGameObjectName("Foo").AsSingle().NonLazy(); Initialize(); @@ -100,7 +100,7 @@ public void TestSingleIdentifiers() [Test] public void TestCached1() { - Container.Bind(typeof(Foo), typeof(Bar)).FromComponentInPrefab(FooPrefab).WithGameObjectName("Foo").AsCached().NonLazy(); + Container.Bind(typeof(Foo), typeof(Bar)).FromComponentInNewPrefab(FooPrefab).WithGameObjectName("Foo").AsCached().NonLazy(); Initialize(); @@ -115,7 +115,7 @@ public void TestCached1() public void TestWithArgumentsFail() { // They have required arguments - Container.Bind(typeof(Gorp), typeof(Qux)).FromComponentInPrefab(GorpAndQuxPrefab).AsCached().NonLazy(); + Container.Bind(typeof(Gorp), typeof(Qux)).FromComponentInNewPrefab(GorpAndQuxPrefab).AsCached().NonLazy(); Initialize(); } @@ -125,7 +125,7 @@ public void TestWithArgumentsFail() public void TestWithArgumentsFail2() { Container.Bind(typeof(Gorp), typeof(Qux)) - .FromComponentInPrefab(GorpAndQuxPrefab).WithGameObjectName("Gorp").AsCached() + .FromComponentInNewPrefab(GorpAndQuxPrefab).WithGameObjectName("Gorp").AsCached() .WithArguments(5, "test1").NonLazy(); Initialize(); @@ -134,7 +134,7 @@ public void TestWithArgumentsFail2() [Test] public void TestWithArgumentsSuccess() { - Container.Bind().FromComponentInPrefab(GorpPrefab) + Container.Bind().FromComponentInNewPrefab(GorpPrefab) .WithGameObjectName("Gorp").AsCached() .WithArguments("test1").NonLazy(); @@ -150,7 +150,7 @@ public void TestWithAbstractSearch() { // There are three components that implement INorf on this prefab // and so this should result in a list of 3 INorf's - Container.Bind().FromComponentInPrefab(NorfPrefab).AsTransient().NonLazy(); + Container.Bind().FromComponentInNewPrefab(NorfPrefab).AsTransient().NonLazy(); Initialize(); @@ -163,7 +163,7 @@ public void TestWithAbstractSearch() public void TestAbstractBindingConcreteSearch() { // Should ignore the Norf2 component on it - Container.Bind().To().FromComponentInPrefab(NorfPrefab).AsTransient().NonLazy(); + Container.Bind().To().FromComponentInNewPrefab(NorfPrefab).AsTransient().NonLazy(); Initialize(); @@ -175,7 +175,7 @@ public void TestAbstractBindingConcreteSearch() public void TestCircularDependencies() { // Jim and Bob both depend on each other - Container.Bind(typeof(Jim), typeof(Bob)).FromComponentInPrefab(JimAndBobPrefab).AsCached().NonLazy(); + Container.Bind(typeof(Jim), typeof(Bob)).FromComponentInNewPrefab(JimAndBobPrefab).AsCached().NonLazy(); Container.BindInterfacesTo().AsSingle().NonLazy(); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs index 49b1d3e33..0276890b0 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromPrefabResource.cs @@ -19,7 +19,7 @@ public class TestFromPrefabResource : ZenjectIntegrationTestFixture public void TestTransientError() { // Validation should detect that it doesn't exist - Container.Bind().FromComponentInPrefabResource(PathPrefix + "asdfasdfas").AsTransient().NonLazy(); + Container.Bind().FromComponentInNewPrefabResource(PathPrefix + "asdfasdfas").AsTransient().NonLazy(); Initialize(); } @@ -27,8 +27,8 @@ public void TestTransientError() [Test] public void TestTransient() { - Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").AsTransient(); - Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").AsTransient(); + Container.Bind().FromComponentInNewPrefabResource(PathPrefix + "Foo").AsTransient(); + Container.Bind().FromComponentInNewPrefabResource(PathPrefix + "Foo").AsTransient(); Container.BindRootResolve(); @@ -40,8 +40,8 @@ public void TestTransient() [Test] public void TestSingle() { - Container.Bind().To().FromComponentInPrefabResource(PathPrefix + "Foo").AsSingle().NonLazy(); - Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").AsSingle().NonLazy(); + Container.Bind().To().FromComponentInNewPrefabResource(PathPrefix + "Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInNewPrefabResource(PathPrefix + "Foo").AsSingle().NonLazy(); Initialize(); @@ -52,8 +52,8 @@ public void TestSingle() public void TestSingle2() { // For ToPrefab, the 'AsSingle' applies to the prefab and not the type, so this is valid - Container.Bind().To().FromComponentInPrefabResource(PathPrefix + "Foo").AsSingle(); - Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo2").AsSingle(); + Container.Bind().To().FromComponentInNewPrefabResource(PathPrefix + "Foo").AsSingle(); + Container.Bind().FromComponentInNewPrefabResource(PathPrefix + "Foo2").AsSingle(); Container.Bind().FromMethod(ctx => ctx.Container.CreateEmptyGameObject("Foo").AddComponent()); Container.BindRootResolve(); @@ -68,8 +68,8 @@ public void TestSingle2() [Test] public void TestSingleIdentifiers() { - Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").WithGameObjectName("Foo").AsSingle().NonLazy(); - Container.Bind().FromComponentInPrefabResource(PathPrefix + "Foo").WithGameObjectName("Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInNewPrefabResource(PathPrefix + "Foo").WithGameObjectName("Foo").AsSingle().NonLazy(); + Container.Bind().FromComponentInNewPrefabResource(PathPrefix + "Foo").WithGameObjectName("Foo").AsSingle().NonLazy(); Initialize(); @@ -82,7 +82,7 @@ public void TestSingleIdentifiers() [Test] public void TestCached1() { - Container.Bind(typeof(Foo), typeof(Bar)).FromComponentInPrefabResource(PathPrefix + "Foo") + Container.Bind(typeof(Foo), typeof(Bar)).FromComponentInNewPrefabResource(PathPrefix + "Foo") .WithGameObjectName("Foo").AsCached().NonLazy(); Initialize(); @@ -98,7 +98,7 @@ public void TestCached1() public void TestWithArgumentsFail() { // They have required arguments - Container.Bind(typeof(Gorp), typeof(Qux)).FromComponentInPrefabResource(PathPrefix + "GorpAndQux").AsCached().NonLazy(); + Container.Bind(typeof(Gorp), typeof(Qux)).FromComponentInNewPrefabResource(PathPrefix + "GorpAndQux").AsCached().NonLazy(); Initialize(); } @@ -107,7 +107,7 @@ public void TestWithArgumentsFail() public void TestWithArguments() { Container.Bind(typeof(Gorp)) - .FromComponentInPrefabResource(PathPrefix + "Gorp").WithGameObjectName("Gorp").AsCached() + .FromComponentInNewPrefabResource(PathPrefix + "Gorp").WithGameObjectName("Gorp").AsCached() .WithArguments("test1").NonLazy(); Initialize(); @@ -122,7 +122,7 @@ public void TestWithAbstractSearch() { // There are three components that implement INorf on this prefab // and so this should result in a list of 3 INorf's - Container.Bind().FromComponentInPrefabResource(PathPrefix + "Norf").AsTransient().NonLazy(); + Container.Bind().FromComponentInNewPrefabResource(PathPrefix + "Norf").AsTransient().NonLazy(); Initialize(); @@ -135,7 +135,7 @@ public void TestWithAbstractSearch() public void TestAbstractBindingConcreteSearch() { // Should ignore the Norf2 component on it - Container.Bind().To().FromComponentInPrefabResource(PathPrefix + "Norf").AsTransient().NonLazy(); + Container.Bind().To().FromComponentInNewPrefabResource(PathPrefix + "Norf").AsTransient().NonLazy(); Initialize(); @@ -147,7 +147,7 @@ public void TestAbstractBindingConcreteSearch() public void TestCircularDependencies() { // Jim and Bob both depend on each other - Container.Bind(typeof(Jim), typeof(Bob)).FromComponentInPrefabResource(PathPrefix + "JimAndBob").AsCached().NonLazy(); + Container.Bind(typeof(Jim), typeof(Bob)).FromComponentInNewPrefabResource(PathPrefix + "JimAndBob").AsCached().NonLazy(); Container.BindInterfacesTo().AsSingle().NonLazy(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSubContainerPrefab.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSubContainerPrefab.cs index 6b8efdda1..a7ee25b88 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSubContainerPrefab.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSubContainerPrefab.cs @@ -34,7 +34,7 @@ GameObject FooPrefab2 public void TestSelfSingle() { Container.Bind().FromSubContainerResolve() - .ByPrefab(FooPrefab).AsSingle(); + .ByNewPrefab(FooPrefab).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -51,7 +51,7 @@ public void TestSelfSingle() public void TestSelfSingleValidate() { Container.Bind().FromSubContainerResolve() - .ByPrefab(FooPrefab).AsSingle().NonLazy(); + .ByNewPrefab(FooPrefab).AsSingle().NonLazy(); Initialize(); } @@ -62,7 +62,7 @@ public void TestSelfSingleValidate() public void TestSelfSingleValidateFails() { Container.Bind().FromSubContainerResolve() - .ByPrefab(FooPrefab2).AsSingle().NonLazy(); + .ByNewPrefab(FooPrefab2).AsSingle().NonLazy(); Initialize(); } @@ -70,7 +70,7 @@ public void TestSelfSingleValidateFails() [Test] public void TestSelfTransient() { - Container.Bind().FromSubContainerResolve().ByPrefab(FooPrefab).AsTransient(); + Container.Bind().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsTransient(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -85,7 +85,7 @@ public void TestSelfTransient() [Test] public void TestSelfCached() { - Container.Bind().FromSubContainerResolve().ByPrefab(FooPrefab).AsCached(); + Container.Bind().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -100,8 +100,8 @@ public void TestSelfCached() [Test] public void TestSelfSingleMultipleContracts() { - Container.Bind().FromSubContainerResolve().ByPrefab(FooPrefab).AsSingle(); - Container.Bind().FromSubContainerResolve().ByPrefab(FooPrefab).AsSingle(); + Container.Bind().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsSingle(); + Container.Bind().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -116,7 +116,7 @@ public void TestSelfSingleMultipleContracts() [Test] public void TestSelfCachedMultipleContracts() { - Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByPrefab(FooPrefab).AsCached(); + Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByNewPrefab(FooPrefab).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -131,7 +131,7 @@ public void TestSelfCachedMultipleContracts() [Test] public void TestSelfTransientMultipleContracts() { - Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByPrefab(FooPrefab).AsTransient(); + Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByNewPrefab(FooPrefab).AsTransient(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -146,7 +146,7 @@ public void TestSelfTransientMultipleContracts() [Test] public void TestConcreteSingle() { - Container.Bind().To().FromSubContainerResolve().ByPrefab(FooPrefab).AsSingle(); + Container.Bind().To().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -161,7 +161,7 @@ public void TestConcreteSingle() [Test] public void TestConcreteTransient() { - Container.Bind().To().FromSubContainerResolve().ByPrefab(FooPrefab).AsTransient(); + Container.Bind().To().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsTransient(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -176,7 +176,7 @@ public void TestConcreteTransient() [Test] public void TestConcreteCached() { - Container.Bind().To().FromSubContainerResolve().ByPrefab(FooPrefab).AsCached(); + Container.Bind().To().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -191,8 +191,8 @@ public void TestConcreteCached() [Test] public void TestConcreteSingleMultipleContracts() { - Container.Bind().To().FromSubContainerResolve().ByPrefab(FooPrefab).AsSingle(); - Container.Bind().FromSubContainerResolve().ByPrefab(FooPrefab).AsSingle(); + Container.Bind().To().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsSingle(); + Container.Bind().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -210,7 +210,7 @@ public void TestConcreteSingleMultipleContracts() [Test] public void TestConcreteCachedMultipleContracts() { - Container.Bind(typeof(Foo), typeof(IFoo)).To().FromSubContainerResolve().ByPrefab(FooPrefab).AsCached(); + Container.Bind(typeof(Foo), typeof(IFoo)).To().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -228,7 +228,7 @@ public void TestConcreteCachedMultipleContracts() [ExpectedException] public void TestSelfIdentifiersFails() { - Container.Bind().FromSubContainerResolve().ByPrefab(FooPrefab).AsSingle(); + Container.Bind().FromSubContainerResolve().ByNewPrefab(FooPrefab).AsSingle(); Container.BindRootResolve(); @@ -238,7 +238,7 @@ public void TestSelfIdentifiersFails() [Test] public void TestSelfIdentifiers() { - Container.Bind().FromSubContainerResolve("gorp").ByPrefab(FooPrefab).AsSingle(); + Container.Bind().FromSubContainerResolve("gorp").ByNewPrefab(FooPrefab).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSubContainerPrefabResource.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSubContainerPrefabResource.cs index f63615338..06f6e9e0e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSubContainerPrefabResource.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Bindings/Editor/TestFromSubContainerPrefabResource.cs @@ -20,7 +20,7 @@ public class TestFromSubContainerPrefabResource : ZenjectIntegrationTestFixture public void TestTransientError() { // Validation should detect that it doesn't exist - Container.Bind().FromSubContainerResolve().ByPrefabResource(PathPrefix + "asdfasdfas").AsTransient().NonLazy(); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource(PathPrefix + "asdfasdfas").AsTransient().NonLazy(); Initialize(); } @@ -28,7 +28,7 @@ public void TestTransientError() [Test] public void TestSelfSingle() { - Container.Bind().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsSingle(); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -43,7 +43,7 @@ public void TestSelfSingle() [Test] public void TestSelfTransient() { - Container.Bind().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsTransient(); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsTransient(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -58,7 +58,7 @@ public void TestSelfTransient() [Test] public void TestSelfCached() { - Container.Bind().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsCached(); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -73,8 +73,8 @@ public void TestSelfCached() [Test] public void TestSelfSingleMultipleContracts() { - Container.Bind().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsSingle().NonLazy(); - Container.Bind().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsSingle().NonLazy(); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsSingle().NonLazy(); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsSingle().NonLazy(); Initialize(); @@ -86,7 +86,7 @@ public void TestSelfSingleMultipleContracts() [Test] public void TestSelfCachedMultipleContracts() { - Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsCached().NonLazy(); + Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsCached().NonLazy(); Initialize(); @@ -98,7 +98,7 @@ public void TestSelfCachedMultipleContracts() [Test] public void TestSelfTransientMultipleContracts() { - Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsTransient().NonLazy(); + Container.Bind(typeof(Foo), typeof(Bar)).FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsTransient().NonLazy(); Initialize(); @@ -110,7 +110,7 @@ public void TestSelfTransientMultipleContracts() [Test] public void TestConcreteSingle() { - Container.Bind().To().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsSingle(); + Container.Bind().To().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -125,7 +125,7 @@ public void TestConcreteSingle() [Test] public void TestConcreteTransient() { - Container.Bind().To().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsTransient(); + Container.Bind().To().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsTransient(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -140,7 +140,7 @@ public void TestConcreteTransient() [Test] public void TestConcreteCached() { - Container.Bind().To().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsCached(); + Container.Bind().To().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -155,8 +155,8 @@ public void TestConcreteCached() [Test] public void TestConcreteSingleMultipleContracts() { - Container.Bind().To().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsSingle(); - Container.Bind().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsSingle(); + Container.Bind().To().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsSingle(); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -174,7 +174,7 @@ public void TestConcreteSingleMultipleContracts() [Test] public void TestConcreteCachedMultipleContracts() { - Container.Bind(typeof(Foo), typeof(IFoo)).To().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsCached(); + Container.Bind(typeof(Foo), typeof(IFoo)).To().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsCached(); Container.BindRootResolve(); Container.BindRootResolve(); @@ -192,7 +192,7 @@ public void TestConcreteCachedMultipleContracts() [ExpectedException] public void TestSelfIdentifiersFails() { - Container.Bind().FromSubContainerResolve().ByPrefabResource(FooResourcePath).AsSingle().NonLazy(); + Container.Bind().FromSubContainerResolve().ByNewPrefabResource(FooResourcePath).AsSingle().NonLazy(); Initialize(); } @@ -200,7 +200,7 @@ public void TestSelfIdentifiersFails() [Test] public void TestSelfIdentifiers() { - Container.Bind().FromSubContainerResolve("gorp").ByPrefabResource(FooResourcePath).AsSingle(); + Container.Bind().FromSubContainerResolve("gorp").ByNewPrefabResource(FooResourcePath).AsSingle(); Container.BindRootResolve(); Container.BindRootResolve(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs index 516fc22e1..98a088766 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactory.cs @@ -134,9 +134,9 @@ public void TestFromNewComponentOnConcrete() } [Test] - public void TestFromComponentInPrefab() + public void TestFromComponentInNewPrefab() { - Container.BindFactory().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInNewPrefab(FooPrefab).WithGameObjectName("asdf"); Initialize(); @@ -150,7 +150,7 @@ public void TestFromComponentInPrefab() [Test] public void TestFromComponentInPrefabComponent() { - Container.BindFactory().FromComponentInPrefab(CameraPrefab).WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInNewPrefab(CameraPrefab).WithGameObjectName("asdf"); Initialize(); @@ -166,7 +166,7 @@ public void TestFromComponentInPrefabComponent() public void TestToPrefabSelfFail() { // Foo3 is not on the prefab - Container.BindFactory().FromComponentInPrefab(FooPrefab); + Container.BindFactory().FromComponentInNewPrefab(FooPrefab); Initialize(); @@ -176,7 +176,7 @@ public void TestToPrefabSelfFail() [Test] public void TestToPrefabConcrete() { - Container.BindFactory().To().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().To().FromComponentInNewPrefab(FooPrefab).WithGameObjectName("asdf"); Initialize(); @@ -212,7 +212,7 @@ public void TestToResource() [Test] public void TestToPrefabResourceSelf() { - Container.BindFactory().FromComponentInPrefabResource("TestBindFactory/Foo").WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInNewPrefabResource("TestBindFactory/Foo").WithGameObjectName("asdf"); Initialize(); @@ -226,7 +226,7 @@ public void TestToPrefabResourceSelf() [Test] public void TestToPrefabResourceConcrete() { - Container.BindFactory().To().FromComponentInPrefabResource("TestBindFactory/Foo").WithGameObjectName("asdf"); + Container.BindFactory().To().FromComponentInNewPrefabResource("TestBindFactory/Foo").WithGameObjectName("asdf"); Initialize(); @@ -240,7 +240,7 @@ public void TestToPrefabResourceConcrete() [Test] public void TestToSubContainerPrefabSelf() { - Container.BindFactory().FromSubContainerResolve().ByPrefab(FooSubContainerPrefab); + Container.BindFactory().FromSubContainerResolve().ByNewPrefab(FooSubContainerPrefab); Initialize(); @@ -254,7 +254,7 @@ public void TestToSubContainerPrefabSelf() public void TestToSubContainerPrefabConcrete() { Container.BindFactory() - .To().FromSubContainerResolve().ByPrefab(FooSubContainerPrefab); + .To().FromSubContainerResolve().ByNewPrefab(FooSubContainerPrefab); Initialize(); @@ -267,7 +267,7 @@ public void TestToSubContainerPrefabConcrete() public void TestToSubContainerPrefabResourceSelf() { Container.BindFactory() - .FromSubContainerResolve().ByPrefabResource("TestBindFactory/FooSubContainer"); + .FromSubContainerResolve().ByNewPrefabResource("TestBindFactory/FooSubContainer"); Initialize(); @@ -281,7 +281,7 @@ public void TestToSubContainerPrefabResourceSelf() public void TestToSubContainerPrefabResourceConcrete() { Container.BindFactory() - .To().FromSubContainerResolve().ByPrefabResource("TestBindFactory/FooSubContainer"); + .To().FromSubContainerResolve().ByNewPrefabResource("TestBindFactory/FooSubContainer"); Initialize(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryFive.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryFive.cs index 81f83c00c..a3851f575 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryFive.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryFive.cs @@ -87,7 +87,7 @@ public void TestToMonoBehaviourConcrete() [Test] public void TestToPrefabSelf() { - Container.BindFactory().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInNewPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -101,7 +101,7 @@ public void TestToPrefabSelf() [Test] public void TestToPrefabConcrete() { - Container.BindFactory().To().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().To().FromComponentInNewPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -115,7 +115,7 @@ public void TestToPrefabConcrete() [Test] public void TestToPrefabResourceSelf() { - Container.BindFactory().FromComponentInPrefabResource("TestBindFactoryFive/Foo").WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInNewPrefabResource("TestBindFactoryFive/Foo").WithGameObjectName("asdf"); AddFactoryUser(); @@ -130,7 +130,7 @@ public void TestToPrefabResourceSelf() public void TestToPrefabResourceConcrete() { Container.BindFactory() - .To().FromComponentInPrefabResource("TestBindFactoryFive/Foo").WithGameObjectName("asdf"); + .To().FromComponentInNewPrefabResource("TestBindFactoryFive/Foo").WithGameObjectName("asdf"); AddFactoryUser(); @@ -145,7 +145,7 @@ public void TestToPrefabResourceConcrete() public void TestToSubContainerPrefabSelf() { Container.BindFactory() - .FromSubContainerResolve().ByPrefab(FooSubContainerPrefab); + .FromSubContainerResolve().ByNewPrefab(FooSubContainerPrefab); AddFactoryUser(); @@ -159,7 +159,7 @@ public void TestToSubContainerPrefabSelf() public void TestToSubContainerPrefabConcrete() { Container.BindFactory() - .To().FromSubContainerResolve().ByPrefab(FooSubContainerPrefab); + .To().FromSubContainerResolve().ByNewPrefab(FooSubContainerPrefab); AddFactoryUser(); @@ -172,7 +172,7 @@ public void TestToSubContainerPrefabConcrete() [Test] public void TestToSubContainerPrefabResourceSelf() { - Container.BindFactory().FromSubContainerResolve().ByPrefabResource("TestBindFactoryFive/FooSubContainer"); + Container.BindFactory().FromSubContainerResolve().ByNewPrefabResource("TestBindFactoryFive/FooSubContainer"); AddFactoryUser(); @@ -186,7 +186,7 @@ public void TestToSubContainerPrefabResourceSelf() public void TestToSubContainerPrefabResourceConcrete() { Container.BindFactory() - .To().FromSubContainerResolve().ByPrefabResource("TestBindFactoryFive/FooSubContainer"); + .To().FromSubContainerResolve().ByNewPrefabResource("TestBindFactoryFive/FooSubContainer"); AddFactoryUser(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs index 4585f9ce4..6d75cd2a3 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Factories/Editor/TestBindFactoryOne.cs @@ -87,7 +87,7 @@ public void TestToMonoBehaviourConcrete() [Test] public void TestToPrefabSelf() { - Container.BindFactory().FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInNewPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -102,7 +102,7 @@ public void TestToPrefabSelf() public void TestToPrefabConcrete() { Container.BindFactory().To() - .FromComponentInPrefab(FooPrefab).WithGameObjectName("asdf"); + .FromComponentInNewPrefab(FooPrefab).WithGameObjectName("asdf"); AddFactoryUser(); @@ -116,7 +116,7 @@ public void TestToPrefabConcrete() [Test] public void TestToPrefabResourceSelf() { - Container.BindFactory().FromComponentInPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); + Container.BindFactory().FromComponentInNewPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); AddFactoryUser(); @@ -131,7 +131,7 @@ public void TestToPrefabResourceSelf() public void TestToPrefabResourceConcrete() { Container.BindFactory().To() - .FromComponentInPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); + .FromComponentInNewPrefabResource("TestBindFactoryOne/Foo").WithGameObjectName("asdf"); AddFactoryUser(); @@ -146,7 +146,7 @@ public void TestToPrefabResourceConcrete() public void TestToSubContainerPrefabSelf() { Container.BindFactory() - .FromSubContainerResolve().ByPrefab(FooSubContainerPrefab); + .FromSubContainerResolve().ByNewPrefab(FooSubContainerPrefab); AddFactoryUser(); @@ -160,7 +160,7 @@ public void TestToSubContainerPrefabSelf() public void TestToSubContainerPrefabConcrete() { Container.BindFactory() - .To().FromSubContainerResolve().ByPrefab(FooSubContainerPrefab); + .To().FromSubContainerResolve().ByNewPrefab(FooSubContainerPrefab); AddFactoryUser(); @@ -174,7 +174,7 @@ public void TestToSubContainerPrefabConcrete() public void TestToSubContainerPrefabResourceSelf() { Container.BindFactory() - .FromSubContainerResolve().ByPrefabResource("TestBindFactoryOne/FooSubContainer"); + .FromSubContainerResolve().ByNewPrefabResource("TestBindFactoryOne/FooSubContainer"); AddFactoryUser(); @@ -188,7 +188,7 @@ public void TestToSubContainerPrefabResourceSelf() public void TestToSubContainerPrefabResourceConcrete() { Container.BindFactory() - .To().FromSubContainerResolve().ByPrefabResource("TestBindFactoryOne/FooSubContainer"); + .To().FromSubContainerResolve().ByNewPrefabResource("TestBindFactoryOne/FooSubContainer"); AddFactoryUser(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs index d207ce8e1..5860e5c08 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs @@ -14,7 +14,7 @@ namespace Zenject.Tests.SceneDecorators [TestFixture] public class TestSceneDecorators { - const string CommonFolderPath = "Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators"; + const string CommonFolderPath = "Assets/Mtm.Zenject-IntegrationTests/SceneLoading/Decorators"; const string DecoratorScenePath = CommonFolderPath + "/DecoratorScene.unity"; const string MainScenePath = CommonFolderPath + "/MainScene.unity"; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs index da5fcea60..72bd0f9c2 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs @@ -20,7 +20,7 @@ public void CommonInstall() GameSettingsInstaller.InstallFromResource(Container); var gameSettings = Container.Resolve(); Container.Bind().AsSingle(); - Container.BindFactory().FromComponentInPrefab(gameSettings.AsteroidPrefab); + Container.BindFactory().FromComponentInNewPrefab(gameSettings.AsteroidPrefab); Container.Bind().WithId("Main").FromNewComponentOnNewGameObject().AsTransient(); Container.Bind().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs index 7aff3f502..044f84b89 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Installers/GameInstaller.cs @@ -61,7 +61,7 @@ void InstallAsteroids() // So any classes that want to create new asteroid objects can simply include an injected field // or constructor parameter of type Asteroid.Factory, then call Create() on that Container.BindFactory() - .FromComponentInPrefab(_settings.AsteroidPrefab) + .FromComponentInNewPrefab(_settings.AsteroidPrefab) // We can also tell Zenject what to name the new gameobject here .WithGameObjectName("Asteroid") // GameObjectGroup's are just game objects used for organization diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs index e3b7146ae..005d50b1f 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs @@ -19,17 +19,17 @@ public override void InstallBindings() Container.BindMemoryPool() .FromSubContainerResolve() - .ByPrefab(_settings.EnemyFacadePrefab) + .ByNewPrefab(_settings.EnemyFacadePrefab) .UnderTransformGroup("Enemies"); Container.BindMemoryPool().WithInitialSize(10).ExpandByDoubling() - .FromComponentInPrefab(_settings.BulletPrefab) + .FromComponentInNewPrefab(_settings.BulletPrefab) .UnderTransformGroup("Bullets"); Container.Bind().AsSingle(); Container.BindMemoryPool().WithInitialSize(3) - .FromComponentInPrefab(_settings.ExplosionPrefab) + .FromComponentInNewPrefab(_settings.ExplosionPrefab) .UnderTransformGroup("Explosions"); Container.Bind().AsSingle(); diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs index 4e2ff0b0d..872095623 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Bindings/TestFromResolve.cs @@ -31,7 +31,7 @@ public void TestIdentifier() Container.Bind().WithId("foo").FromInstance(foo).NonLazy(); Container.Bind().To().FromResolve("foo").NonLazy(); - Assert.IsEqual(Container.Resolve(), Container.Resolve("foo")); + Assert.IsEqual(Container.Resolve(), Container.ResolveId("foo")); Assert.IsEqual(Container.Resolve(), foo); } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsComplex.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsComplex.cs index 3e93151dc..4f6aa8e2b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsComplex.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestConditionsComplex.cs @@ -35,8 +35,8 @@ public void TestCorrespondingIdentifiers() Container.BindInstance(foo1).When(c => c.ParentContexts.Where(x => x.MemberType == typeof(Bar) && object.Equals(x.Identifier, "Bar1")).Any()); Container.BindInstance(foo2).When(c => c.ParentContexts.Where(x => x.MemberType == typeof(Bar) && object.Equals(x.Identifier, "Bar2")).Any()); - Assert.IsEqual(Container.Resolve("Bar1").Foo, foo1); - Assert.IsEqual(Container.Resolve("Bar2").Foo, foo2); + Assert.IsEqual(Container.ResolveId("Bar1").Foo, foo1); + Assert.IsEqual(Container.ResolveId("Bar2").Foo, foo2); } } } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestIdentifiers.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestIdentifiers.cs index 4c046c0d7..40a0dedf1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestIdentifiers.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Conditions/TestIdentifiers.cs @@ -23,7 +23,7 @@ public void TestBasic() Assert.Throws( delegate { Container.Resolve(); }); - Container.Resolve("foo"); + Container.ResolveId("foo"); } [Test] @@ -34,7 +34,7 @@ public void TestBasic2() Assert.Throws( delegate { Container.Resolve(); }); - Container.Resolve("foo"); + Container.ResolveId("foo"); } [Test] @@ -45,7 +45,7 @@ public void TestBasic3() Assert.Throws( delegate { Container.Resolve(); }); - Container.Resolve("foo"); + Container.ResolveId("foo"); } [Test] @@ -58,9 +58,9 @@ public void TestBasic4() delegate { Container.Resolve(); }); Assert.Throws( - delegate { Container.Resolve("foo"); }); + delegate { Container.ResolveId("foo"); }); - Assert.IsEqual(Container.ResolveAll("foo").Count, 2); + Assert.IsEqual(Container.ResolveIdAll("foo").Count, 2); } [Test] diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs index 6bed8f249..794a743db 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinder0.cs @@ -24,7 +24,7 @@ public ConditionCopyNonLazyBinder ByMethod(Action installerMethod) #if !NOT_UNITY3D - public NameTransformConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder ByNewPrefab(UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); @@ -33,7 +33,7 @@ public NameTransformConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefa ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProvider(prefab), gameObjectInfo)); @@ -41,7 +41,7 @@ public NameTransformConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefa return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public NameTransformConditionCopyNonLazyBinder ByPrefabResource(string resourcePath) + public NameTransformConditionCopyNonLazyBinder ByNewPrefabResource(string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); @@ -50,7 +50,7 @@ public NameTransformConditionCopyNonLazyBinder ByPrefabResource(string resourceP ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProviderResource(resourcePath), gameObjectInfo)); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs index 796d624ff..dcf284c1f 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinder/SubContainerBinder/FactorySubContainerBinderWithParams.cs @@ -13,13 +13,13 @@ public FactorySubContainerBinderWithParams( #if !NOT_UNITY3D - public NameTransformConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder ByNewPrefab(UnityEngine.Object prefab) where TInstaller : IInstaller { - return ByPrefab(typeof(TInstaller), prefab); + return ByNewPrefab(typeof(TInstaller), prefab); } - public NameTransformConditionCopyNonLazyBinder ByPrefab(Type installerType, UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder ByNewPrefab(Type installerType, UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); @@ -31,7 +31,7 @@ public NameTransformConditionCopyNonLazyBinder ByPrefab(Type installerType, Unit ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, - new SubContainerCreatorByPrefabWithParams( + new SubContainerCreatorByNewPrefabWithParams( installerType, container, new PrefabProvider(prefab), @@ -40,13 +40,13 @@ public NameTransformConditionCopyNonLazyBinder ByPrefab(Type installerType, Unit return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public NameTransformConditionCopyNonLazyBinder ByPrefabResource(string resourcePath) + public NameTransformConditionCopyNonLazyBinder ByNewPrefabResource(string resourcePath) where TInstaller : IInstaller { - return ByPrefabResource(typeof(TInstaller), resourcePath); + return ByNewPrefabResource(typeof(TInstaller), resourcePath); } - public NameTransformConditionCopyNonLazyBinder ByPrefabResource( + public NameTransformConditionCopyNonLazyBinder ByNewPrefabResource( Type installerType, string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); @@ -56,7 +56,7 @@ public NameTransformConditionCopyNonLazyBinder ByPrefabResource( ProviderFunc = (container) => new SubContainerDependencyProvider( ContractType, SubIdentifier, - new SubContainerCreatorByPrefabWithParams( + new SubContainerCreatorByNewPrefabWithParams( installerType, container, new PrefabProviderResource(resourcePath), diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs index bb4fb1661..d16822999 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/Factory/FactoryFromBinderBase.cs @@ -104,7 +104,7 @@ public ConditionCopyNonLazyBinder FromNewComponentOn(GameObject gameObject) return this; } - public NameTransformConditionCopyNonLazyBinder FromComponentInPrefab(UnityEngine.Object prefab) + public NameTransformConditionCopyNonLazyBinder FromComponentInNewPrefab(UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); BindingUtil.AssertIsInterfaceOrComponent(ContractType); @@ -121,7 +121,7 @@ public NameTransformConditionCopyNonLazyBinder FromComponentInPrefab(UnityEngine return new NameTransformConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public NameTransformConditionCopyNonLazyBinder FromComponentInPrefabResource(string resourcePath) + public NameTransformConditionCopyNonLazyBinder FromComponentInNewPrefabResource(string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); BindingUtil.AssertIsInterfaceOrComponent(ContractType); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs index bd9da70a5..7fef1b760 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/FromBinders/FromBinder.cs @@ -160,13 +160,13 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromNewComponentOnNewGame return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefab(UnityEngine.Object prefab) + public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInNewPrefab(UnityEngine.Object prefab) { - return FromComponentInPrefab( + return FromComponentInNewPrefab( prefab, new GameObjectCreationParameters()); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefab( + public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInNewPrefab( UnityEngine.Object prefab, GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsValidPrefab(prefab); @@ -179,12 +179,12 @@ public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefab( return new NameTransformScopeArgConditionCopyNonLazyBinder(BindInfo, gameObjectInfo); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefabResource(string resourcePath) + public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInNewPrefabResource(string resourcePath) { - return FromComponentInPrefabResource(resourcePath, new GameObjectCreationParameters()); + return FromComponentInNewPrefabResource(resourcePath, new GameObjectCreationParameters()); } - public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInPrefabResource( + public NameTransformScopeArgConditionCopyNonLazyBinder FromComponentInNewPrefabResource( string resourcePath, GameObjectCreationParameters gameObjectInfo) { BindingUtil.AssertIsValidResourcePath(resourcePath); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs b/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs index e6def4e73..4ac7d3be2 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Binders/SubContainerBinder.cs @@ -54,7 +54,7 @@ public ScopeConditionCopyNonLazyBinder ByMethod(Action installerMet #if !NOT_UNITY3D - public NameTransformScopeConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object prefab) + public NameTransformScopeConditionCopyNonLazyBinder ByNewPrefab(UnityEngine.Object prefab) { BindingUtil.AssertIsValidPrefab(prefab); @@ -66,7 +66,7 @@ public NameTransformScopeConditionCopyNonLazyBinder ByPrefab(UnityEngine.Object return new NameTransformScopeConditionCopyNonLazyBinder(_bindInfo, gameObjectInfo); } - public NameTransformScopeConditionCopyNonLazyBinder ByPrefabResource(string resourcePath) + public NameTransformScopeConditionCopyNonLazyBinder ByNewPrefabResource(string resourcePath) { BindingUtil.AssertIsValidResourcePath(resourcePath); diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabBindingFinalizer.cs index 041149d3a..07e9353da 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabBindingFinalizer.cs @@ -61,14 +61,14 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) concreteTypes, (_, concreteType) => new SubContainerDependencyProvider( concreteType, _subIdentifier, - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProvider(_prefab), _gameObjectBindInfo))); break; } case ScopeTypes.Cached: { var containerCreator = new SubContainerCreatorCached( - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProvider(_prefab), _gameObjectBindInfo)); RegisterProvidersForAllContractsPerConcreteType( @@ -108,14 +108,14 @@ void FinalizeBindingSelf(DiContainer container) container, (_, contractType) => new SubContainerDependencyProvider( contractType, _subIdentifier, - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProvider(_prefab), _gameObjectBindInfo))); break; } case ScopeTypes.Cached: { var containerCreator = new SubContainerCreatorCached( - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProvider(_prefab), _gameObjectBindInfo)); RegisterProviderPerContract( diff --git a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabResourceBindingFinalizer.cs b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabResourceBindingFinalizer.cs index f6371060b..ea99b594f 100644 --- a/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabResourceBindingFinalizer.cs +++ b/UnityProject/Assets/Zenject/Source/Binding/Finalizers/SubContainerPrefabResourceBindingFinalizer.cs @@ -61,14 +61,14 @@ void FinalizeBindingConcrete(DiContainer container, List concreteTypes) concreteTypes, (_, concreteType) => new SubContainerDependencyProvider( concreteType, _subIdentifier, - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProviderResource(_resourcePath), _gameObjectBindInfo))); break; } case ScopeTypes.Cached: { var containerCreator = new SubContainerCreatorCached( - new SubContainerCreatorByPrefab(container, new PrefabProviderResource(_resourcePath), _gameObjectBindInfo)); + new SubContainerCreatorByNewPrefab(container, new PrefabProviderResource(_resourcePath), _gameObjectBindInfo)); RegisterProvidersForAllContractsPerConcreteType( container, @@ -107,14 +107,14 @@ void FinalizeBindingSelf(DiContainer container) container, (_, contractType) => new SubContainerDependencyProvider( contractType, _subIdentifier, - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProviderResource(_resourcePath), _gameObjectBindInfo))); break; } case ScopeTypes.Cached: { var containerCreator = new SubContainerCreatorCached( - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( container, new PrefabProviderResource(_resourcePath), _gameObjectBindInfo)); RegisterProviderPerContract( diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index bc739d881..8392fa02c 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -488,7 +488,12 @@ public Type ResolveType(InjectContext context) public List ResolveTypeAll(Type type) { - return ResolveTypeAll(new InjectContext(this, type, null)); + return ResolveTypeAll(type, null); + } + + public List ResolveTypeAll(Type type, object identifier) + { + return ResolveTypeAll(new InjectContext(this, type, identifier)); } // Returns all the types that would be returned if ResolveAll was called with the given values @@ -648,7 +653,7 @@ IEnumerable SafeGetInstances(ProviderPair providerPair, InjectContext co // Use the container associated with the provider to address some rare cases // which would otherwise result in an infinite loop. Like this: - // Container.Bind().FromComponentInPrefab(Prefab).AsTransient() + // Container.Bind().FromComponentInNewPrefab(Prefab).AsTransient() // With the prefab being a GameObjectContext containing a script that has a // ICharacter dependency. In this case, we would otherwise use the _resolvesInProgress // associated with the GameObjectContext container, which will allow the recursive @@ -1473,64 +1478,71 @@ public void Inject(object injectable, IEnumerable extraArgs) // public TContract Resolve() { - return Resolve(null); + return (TContract)Resolve(typeof(TContract)); } - public TContract Resolve(object identifier) + public object Resolve(Type contractType) { - return (TContract)Resolve(new InjectContext(this, typeof(TContract), identifier)); + return ResolveId(contractType, null); } - // Same as Resolve<> except it will return null if a value for the given type cannot - // be found. - public TContract TryResolve() - where TContract : class + public TContract ResolveId(object identifier) { - return TryResolve(null); + return (TContract)ResolveId(typeof(TContract), identifier); } - public TContract TryResolve(object identifier) - where TContract : class + public object ResolveId(Type contractType, object identifier) { - return (TContract)TryResolve(typeof(TContract), identifier); + return Resolve( + new InjectContext(this, contractType, identifier)); } - public object TryResolve(Type contractType) + // Same as Resolve<> except it will return null if a value for the given type cannot + // be found. + public TContract TryResolve() + where TContract : class { - return TryResolve(contractType, null); + return (TContract)TryResolve(typeof(TContract)); } - public object TryResolve(Type contractType, object identifier) + public object TryResolve(Type contractType) { - return Resolve(new InjectContext(this, contractType, identifier, true)); + return TryResolveId(contractType, null); } - // Non generic version - public object Resolve(Type contractType) + public TContract TryResolveId(object identifier) + where TContract : class { - return Resolve(new InjectContext(this, contractType, null)); + return (TContract)TryResolveId( + typeof(TContract), identifier); } - public object Resolve(Type contractType, object identifier) + public object TryResolveId(Type contractType, object identifier) { - return Resolve(new InjectContext(this, contractType, identifier)); + return Resolve( + new InjectContext(this, contractType, identifier, true)); } // Same as Resolve<> except it will return all bindings that are associated with the given type public List ResolveAll() { - return ResolveAll(null); + return (List)ResolveAll(typeof(TContract)); } - public List ResolveAll(object identifier) + public IList ResolveAll(Type contractType) { - return ResolveAll(identifier, true); + return ResolveIdAll(contractType, null); } - public List ResolveAll(object identifier, bool optional) + public List ResolveIdAll(object identifier) { - var context = new InjectContext(this, typeof(TContract), identifier, optional); - return (List)ResolveAll(context); + return (List)ResolveIdAll(typeof(TContract), identifier); + } + + public IList ResolveIdAll(Type contractType, object identifier) + { + return ResolveAll( + new InjectContext(this, contractType, identifier, true)); } // Removes all bindings @@ -1543,14 +1555,24 @@ public void UnbindAll() // Remove all bindings bound to the given contract type public bool Unbind() { - return Unbind(null); + return Unbind(typeof(TContract)); + } + + public bool Unbind(Type contractType) + { + return UnbindId(contractType, null); + } + + public bool UnbindId(object identifier) + { + return UnbindId(typeof(TContract), identifier); } - public bool Unbind(object identifier) + public bool UnbindId(Type contractType, object identifier) { FlushBindings(); - var bindingId = new BindingId(typeof(TContract), identifier); + var bindingId = new BindingId(contractType, identifier); return _providers.Remove(bindingId); } @@ -1567,13 +1589,23 @@ public bool HasBinding(InjectContext context) public bool HasBinding() { - return HasBinding(null); + return HasBinding(typeof(TContract)); + } + + public bool HasBinding(Type contractType) + { + return HasBindingId(contractType, null); + } + + public bool HasBindingId(object identifier) + { + return HasBindingId(typeof(TContract), identifier); } - public bool HasBinding(object identifier) + public bool HasBindingId(Type contractType, object identifier) { return HasBinding( - new InjectContext(this, typeof(TContract), identifier)); + new InjectContext(this, contractType, identifier)); } // Do not use this - it is for internal use only @@ -1615,15 +1647,26 @@ public BindFinalizerWrapper StartBinding() public ConcreteBinderGeneric Rebind() { - return Rebind(null); + return RebindId(null); } - public ConcreteBinderGeneric Rebind(object identifier) + public ConcreteBinderGeneric RebindId(object identifier) { - Unbind(identifier); + UnbindId(identifier); return Bind().WithId(identifier); } + public ConcreteBinderNonGeneric Rebind(Type contractType) + { + return RebindId(contractType, null); + } + + public ConcreteBinderNonGeneric RebindId(Type contractType, object identifier) + { + UnbindId(contractType, identifier); + return Bind(contractType).WithId(identifier); + } + // Map the given type to a way of obtaining it // Note that this can include open generic types as well such as List<> public ConcreteIdBinderGeneric Bind() @@ -1695,20 +1738,20 @@ public ConcreteIdBinderNonGeneric Bind( // It's only in rare cases where you need to call this instead of NonLazy() public void BindRootResolve() { - BindRootResolve(null); + BindRootResolveId(null); } - public void BindRootResolve(object identifier) + public void BindRootResolve(IEnumerable rootTypes) { - BindRootResolve(identifier, new Type[] { typeof(TContract) }); + BindRootResolveId(rootTypes, null); } - public void BindRootResolve(IEnumerable rootTypes) + public void BindRootResolveId(object identifier) { - BindRootResolve(null, rootTypes); + BindRootResolveId(new Type[] { typeof(TContract) }, identifier); } - public void BindRootResolve(object identifier, IEnumerable rootTypes) + public void BindRootResolveId(IEnumerable rootTypes, object identifier) { Bind().WithId(DependencyRootIdentifier).To(rootTypes).FromResolve(identifier); } @@ -2009,6 +2052,7 @@ public object InstantiateExplicit(Type concreteType, bool autoInject, InjectArgs } } +#if !NOT_UNITY3D public Component InstantiateComponentExplicit( Type componentType, GameObject gameObject, List extraArgs) { @@ -2110,6 +2154,7 @@ public object InstantiatePrefabForComponentExplicit( return InjectGameObjectForComponentExplicit( gameObj, componentType, args); } +#endif ////////////// Types //////////////// diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonProviderCreator.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonProviderCreator.cs index 23f322e98..be8ba4e4a 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonProviderCreator.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SingletonProviderCreator.cs @@ -10,8 +10,8 @@ public class SingletonProviderCreator readonly SubContainerSingletonProviderCreatorByInstaller _subContainerInstallerProviderCreator; #if !NOT_UNITY3D - readonly SubContainerSingletonProviderCreatorByPrefab _subContainerPrefabProviderCreator; - readonly SubContainerSingletonProviderCreatorByPrefabResource _subContainerPrefabResourceProviderCreator; + readonly SubContainerSingletonProviderCreatorByNewPrefab _subContainerPrefabProviderCreator; + readonly SubContainerSingletonProviderCreatorByNewPrefabResource _subContainerPrefabResourceProviderCreator; readonly PrefabSingletonProviderCreator _prefabProviderCreator; readonly PrefabResourceSingletonProviderCreator _prefabResourceProviderCreator; @@ -25,8 +25,8 @@ public SingletonProviderCreator( _subContainerInstallerProviderCreator = new SubContainerSingletonProviderCreatorByInstaller(container, markRegistry); #if !NOT_UNITY3D - _subContainerPrefabProviderCreator = new SubContainerSingletonProviderCreatorByPrefab(container, markRegistry); - _subContainerPrefabResourceProviderCreator = new SubContainerSingletonProviderCreatorByPrefabResource(container, markRegistry); + _subContainerPrefabProviderCreator = new SubContainerSingletonProviderCreatorByNewPrefab(container, markRegistry); + _subContainerPrefabResourceProviderCreator = new SubContainerSingletonProviderCreatorByNewPrefabResource(container, markRegistry); _prefabProviderCreator = new PrefabSingletonProviderCreator(container, markRegistry); _prefabResourceProviderCreator = new PrefabResourceSingletonProviderCreator(container, markRegistry); diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefab.cs similarity index 94% rename from UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs rename to UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefab.cs index ac4756989..03a715749 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefab.cs @@ -7,14 +7,14 @@ namespace Zenject { - public class SubContainerSingletonProviderCreatorByPrefab + public class SubContainerSingletonProviderCreatorByNewPrefab { readonly SingletonMarkRegistry _markRegistry; readonly DiContainer _container; readonly Dictionary _subContainerCreators = new Dictionary(); - public SubContainerSingletonProviderCreatorByPrefab( + public SubContainerSingletonProviderCreatorByNewPrefab( DiContainer container, SingletonMarkRegistry markRegistry) { @@ -43,7 +43,7 @@ public IProvider CreateProvider( else { var creator = new SubContainerCreatorCached( - new SubContainerCreatorByPrefab(_container, new PrefabProvider(prefab), gameObjectBindInfo)); + new SubContainerCreatorByNewPrefab(_container, new PrefabProvider(prefab), gameObjectBindInfo)); creatorInfo = new CreatorInfo(gameObjectBindInfo, creator); diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs.meta b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefab.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs.meta rename to UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefab.cs.meta index 82979de0d..0da30b062 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefab.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 3a154b5c7f48c9a49bd7a40f5d714807 -timeCreated: 1461708049 -licenseType: Pro +guid: b4b2e202af09d0444a0989ec8699b042 +timeCreated: 1486859770 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefabResource.cs similarity index 95% rename from UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs rename to UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefabResource.cs index fc27b62d7..235f3a832 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefabResource.cs @@ -6,14 +6,14 @@ namespace Zenject { - public class SubContainerSingletonProviderCreatorByPrefabResource + public class SubContainerSingletonProviderCreatorByNewPrefabResource { readonly SingletonMarkRegistry _markRegistry; readonly DiContainer _container; readonly Dictionary _subContainerCreators = new Dictionary(); - public SubContainerSingletonProviderCreatorByPrefabResource( + public SubContainerSingletonProviderCreatorByNewPrefabResource( DiContainer container, SingletonMarkRegistry markRegistry) { @@ -41,7 +41,7 @@ public IProvider CreateProvider( else { var creator = new SubContainerCreatorCached( - new SubContainerCreatorByPrefab( + new SubContainerCreatorByNewPrefab( _container, new PrefabProviderResource(resourcePath), gameObjectBindInfo)); creatorInfo = new CreatorInfo( diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs.meta b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefabResource.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs.meta rename to UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefabResource.cs.meta index 04dddbc7d..6eda9ee36 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefab.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByNewPrefabResource.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: c42d99116eda52640b1405b2bc13b4db -timeCreated: 1461708053 -licenseType: Pro +guid: f229e1c9f405e5e4c9067ba7bfbb6f0b +timeCreated: 1486859771 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefab.cs similarity index 91% rename from UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs rename to UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefab.cs index 99be2ec0f..08e22a277 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefab.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefab.cs @@ -5,13 +5,13 @@ namespace Zenject { - public class SubContainerCreatorByPrefab : ISubContainerCreator + public class SubContainerCreatorByNewPrefab : ISubContainerCreator { readonly GameObjectCreationParameters _gameObjectBindInfo; readonly IPrefabProvider _prefabProvider; readonly DiContainer _container; - public SubContainerCreatorByPrefab( + public SubContainerCreatorByNewPrefab( DiContainer container, IPrefabProvider prefabProvider, GameObjectCreationParameters gameObjectBindInfo) { diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs.meta b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefab.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs.meta rename to UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefab.cs.meta index bcba5f568..4e2b7e000 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefab.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 8f7fd600a5adc634692d997ac1a43225 -timeCreated: 1461708051 -licenseType: Pro +guid: 17fc7cad09fe4e94f939551c85abf6d9 +timeCreated: 1486859770 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefabWithParams.cs similarity index 93% rename from UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs rename to UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefabWithParams.cs index 45c4cc402..0f86d781e 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByPrefabWithParams.cs +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefabWithParams.cs @@ -6,14 +6,14 @@ namespace Zenject { - public class SubContainerCreatorByPrefabWithParams : ISubContainerCreator + public class SubContainerCreatorByNewPrefabWithParams : ISubContainerCreator { readonly DiContainer _container; readonly IPrefabProvider _prefabProvider; readonly Type _installerType; readonly GameObjectCreationParameters _gameObjectBindInfo; - public SubContainerCreatorByPrefabWithParams( + public SubContainerCreatorByNewPrefabWithParams( Type installerType, DiContainer container, IPrefabProvider prefabProvider, GameObjectCreationParameters gameObjectBindInfo) { diff --git a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs.meta b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefabWithParams.cs.meta similarity index 69% rename from UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs.meta rename to UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefabWithParams.cs.meta index 8568e3564..b683f7d2a 100644 --- a/UnityProject/Assets/Zenject/Source/Providers/Singleton/SubContainer/SubContainerSingletonProviderCreatorByPrefabResource.cs.meta +++ b/UnityProject/Assets/Zenject/Source/Providers/SubContainerCreators/SubContainerCreatorByNewPrefabWithParams.cs.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 0d0de4fc1841ab647987350dabdab90a -timeCreated: 1461708048 -licenseType: Pro +guid: 07cb33e44f032a840a46b8b699927d0a +timeCreated: 1486859770 +licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] From 64f4daa6a234b8a6f1630ede67ec2c5edbaf54b8 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 12 Feb 2017 01:06:36 -0400 Subject: [PATCH 47/62] More work on readme --- Documentation/MemoryPools.md | 5 +++++ README.md | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 Documentation/MemoryPools.md diff --git a/Documentation/MemoryPools.md b/Documentation/MemoryPools.md new file mode 100644 index 000000000..bf66b5fee --- /dev/null +++ b/Documentation/MemoryPools.md @@ -0,0 +1,5 @@ + +## Memory Pools + +TBD + diff --git a/README.md b/README.md index 4c232f96b..4ce44fd7f 100644 --- a/README.md +++ b/README.md @@ -118,16 +118,19 @@ The tests may also be helpful to show usage for each specific feature (which you * List Bindings * Global Bindings Using Project Context * Identifiers + * Decorator Bind * Non Generic bindings * Convention Based Binding * Singleton Identifiers * Scriptable Object Installer * Runtime Parameters For Installers * Creating Objects Dynamically Using Factories + * Memory Pools * Update / Initialization Order * Zenject Order Of Operations * Injecting data across scenes * Scene Parenting Using Contract Names + * Just-In-Time Resolving Using Lazy<> * DiContainer Methods * DiContainer.Instantiate * DiContainer.Bind @@ -1535,12 +1538,16 @@ public class MainInstaller : MonoInstaller ## Commands And Signals -See here. +As of version 5.0, in an effort to keep things lightweight, Zenject no longer includes an implementation of commands and signals. The previous commands and signals package has been moved to another github repository. ## Creating Objects Dynamically Using Factories See here. +## Memory Pools + +See here. + ## Update / Initialization Order In many cases, especially for small projects, the order that classes update or initialize in does not matter. However, in larger projects update or initialization order can become an issue. This can especially be an issue in Unity, since it is often difficult to predict in what order the Start(), Awake(), or Update() methods will be called in. Unfortunately, Unity does not have an easy way to control this (besides in `Edit -> Project Settings -> Script Execution Order`, though that can be awkward to use) @@ -1825,6 +1832,10 @@ See here. See here. +## Just-In-Time Resolving Using Lazy<> + +TBD + ## DiContainer Methods In addition to the bind methods documented above, there are also some other methods you might want to occasionally use on DiContainer. For example, if you are writing a custom factory, you might want to directly call one of the `DiContainer.Instantaite` methods. Or you might have a situation where another library is creating instances of your classes (for example, a networking library) and you need to manually call DiContainer.Inject. @@ -2149,6 +2160,10 @@ It is possible to remove or replace bindings that were added in a previous bind 1. **DiContainer.GetDependencyContracts** - Returns a list of all the types that the given type depends on. This might be useful, for exmaple, if you wanted to do some static analysis of your project, or if you wanted to automatically generate a dependency diagram, etc. +## Decorator Bind + +TBD + ## Non Generic bindings In some cases you may not know the exact type you want to bind at compile time. In these cases you can use the overload of the `Bind` method which takes a `System.Type` value instead of a generic parameter. From bd120365d3d4999f103f8e47e729bb133789482d Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 12 Feb 2017 16:10:41 -0400 Subject: [PATCH 48/62] Added back documentation for signals --- Documentation/Signals.md | 356 +++++++++++++++++++++++++++++++++++++++ README.md | 6 +- 2 files changed, 359 insertions(+), 3 deletions(-) create mode 100644 Documentation/Signals.md diff --git a/Documentation/Signals.md b/Documentation/Signals.md new file mode 100644 index 000000000..d69606674 --- /dev/null +++ b/Documentation/Signals.md @@ -0,0 +1,356 @@ + +## Signals + +## Motivation / Theory + +Given two classes A and B that need to communicate, your options are usually: + +1. Directly call a method on B from A. In this case, A is strongly coupled with B. +2. Inverse the dependency by having B observe an event on A. In this case, B is strongly coupled with A. + +So, often you have to ask yourself, should A know about B or should B know about A? + +As a third option, in some cases it might actually be better for neither one to know about the other. This way your code is kept as loosely coupled as possible. You can achieve this by having A and B interact with an intermediary object instead of directly with each other. In Zenject this intermediary object is called a Signal. + +## Signals Quick Start + +If you just want to get up and running immediately, see the following example which shows basic usage: + +```csharp +public class UserJoinedSignal : Signal +{ +} + +public class Greeter1 +{ + public void SayHello(string userName) + { + Debug.Log("Hello " + userName + "!"); + } +} + +public class Greeter2 : IInitializable, IDisposable +{ + UserJoinedSignal _userJoinedSignal; + + public Greeter2(UserJoinedSignal userJoinedSignal) + { + _userJoinedSignal = userJoinedSignal; + } + + public void Initialize() + { + _userJoinedSignal += OnUserJoined; + } + + public void Dispose() + { + _userJoinedSignal -= OnUserJoined; + } + + void OnUserJoined(string username) + { + Debug.Log("Hello again " + username + "!"); + } +} + +public class GameInitializer : IInitializable +{ + readonly UserJoinedSignal _userJoinedSignal; + + public GameInitializer(UserJoinedSignal userJoinedSignal) + { + _userJoinedSignal = userJoinedSignal; + } + + public void Initialize() + { + _userJoinedSignal.Fire("Bob"); + } +} + +public class GameInstaller : MonoInstaller +{ + public override void InstallBindings() + { + Container.Bind().AsSingle(); + Container.DeclareSignal(); + + Container.BindInterfacesTo().AsSingle(); + + Container.BindSignal() + .To(x => x.SayHello).AsSingle(); + + Container.BindInterfacesTo().AsSingle(); + } +} +``` + +To run, just create copy and paste the code above into a new file named GameInstaller then create an empty scene with a new scene context and attach the new installer. + +As you can see in the the above example, there are two ways of creating signal handlers. You can either directly bind a handler method to a signal in an installer (Greeter1) or you can have your signal handler attach and detach itself to the signal (Greeter2). + +For more details on what's going on above see the following sections. + +## Signals Declaration + +Signals are defined like this: + +```csharp +public class DoSomethingSignal : Signal +{ +} +``` + +Note that the signal class must provide itself as a generic argument to the Signal base class. + +Classes that derive from Signal should always be left empty - their only purpose is to represent a single action. + +Any parameters passed along with the signal need to be included as more generic arguments: + +```csharp +public class DoSomethingSignal : Signal +{ +} +``` + +In this case, the signal would take a string and an int parameter. + +Then in an installer they must be declared somewhere: + +```csharp +public override void InstallBindings() +{ + Container.DeclareSignal(); +} +``` + +Note that the declaration is the same regardless of the parameter list. + +The format of the DeclareSignal statement is the following: + +
+Container.DeclareSignal<SignalType>()
+    .RequireHandler()
+    .When(Condition);
+
+ +The When Condition can be any Zenject condition just like any other binding (see Zenject docs for details). When using installer handlers (see below) this can be useful to restrict which classes are allowed to fire the signal + +The `RequireHandler()` method is optional. If not included, then the signal will be allowed to fire with zero handlers attached. If `RequireHandler()` is added to the binding, then an exception will be thrown if the signal is fired and there isn't any handlers attached. + +Then in the firing class: + +```csharp +public class Bar : ITickable +{ + readonly DoSomethingSignal _signal; + + public Bar(DoSomethingSignal signal) + { + _signal = signal; + } + + public void DoSomething() + { + _signal.Fire(); + } +} +``` + +## Signal Handlers + +There are three ways of adding handlers to a signal: + +1. C# events +2. UniRx Stream +3. Installer Binding + +### C# Event Signal Handler + +Probably the easiest method to add a handler is to add it directly from within the handler class. For example: + +```csharp +public class Greeter : IInitializable, IDisposable +{ + AppStartedSignal _appStartedSignal; + + public Greeter(AppStartedSignal appStartedSignal) + { + _appStartedSignal = appStartedSignal; + } + + public void Initialize() + { + _appStartedSignal += OnAppStarted; + } + + public void Dispose() + { + _appStartedSignal -= OnAppStarted; + } + + void OnAppStarted() + { + Debug.Log("Hello world!"); + } +} +``` + +Or, equivalently: + +```csharp +public class Greeter : IInitializable, IDisposable +{ + AppStartedSignal _appStartedSignal; + + public Greeter(AppStartedSignal appStartedSignal) + { + _appStartedSignal = appStartedSignal; + } + + public void Initialize() + { + _appStartedSignal.Listen(OnAppStarted); + } + + public void Dispose() + { + _appStartedSignal.Unlisten(OnAppStarted); + } + + void OnAppStarted() + { + Debug.Log("Hello world!"); + } +} +``` + +### UniRx Signal Handler + +If you are a fan of UniRx, as we are, then you might also want to treat the signal as a UniRx stream. For example: + +```csharp +public class Greeter : MonoBehaviour +{ + [Inject] + AppStartedSignal _appStartedSignal; + + public void Start() + { + _appStartedSignal.Stream.Subscribe(OnAppStarted).AddTo(this); + } + + void OnAppStarted() + { + Debug.Log("Hello World!"); + } +} +``` + +NOTE: Integration with UniRx is disabled by default. To enable, you must add the define `ZEN_SIGNALS_ADD_UNIRX` to your project, which you can do by selecting Edit -> Project Settings -> Player and then adding `ZEN_SIGNALS_ADD_UNIRX` in the "Scripting Define Symbols" section + +### Installer Binding Signal Handler + +Finally, you can also add signal handlers directly within an installer. For example: + +```csharp +public class Greeter1 +{ + public void SayHello() + { + Debug.Log("Hello!"); + } +} + +public class GreeterInstaller : MonoInstaller +{ + public override void InstallBindings() + { + Container.BindSignal() + .To(x => x.SayHello).AsSingle(); + } +} +``` + +Or, when the signal has parameters: + +```csharp +public class Greeter1 +{ + public void SayHello(string name) + { + Debug.Log("Hello " + name + "!"); + } +} + +public class GreeterInstaller : MonoInstaller +{ + public override void InstallBindings() + { + Container.BindSignal() + .To(x => x.SayHello).AsSingle(); + } +} +``` + +This approach has the following advantages: +- More flexible, because you can wire it up in the installer and can have multiple installer configurations +- More loosely coupled, because the handler class can remain completely ignorant of the signal +- Less error prone, because you don't have to remember to unsubscribe. The signal will automatically be unsubscribed when the 'context' is disposed of. This means that if you add a handler within a sub-container, the handler will automatically unsubscribe when the sub-container is disposed of +- You can more easily control which classes are allowed to fire the signal. You can do this by adding a When() conditional to the declaration. (You can't do this with the other handler types because the listener also needs access to the signal to add itself to it) + +Which approach to signal handlers depends on the specifics of each case and personal preference. + +### Signals With Subcontainers + +One interesting feature of signals is that the signal handlers do not need to be in the same container as the signal declaration. The declaration can either be in the same container, a parent container, or a sub-container, and it should trigger the handlers regardless of where they are declared. Note that the declaration will however determine which container the signal can be fired from (the signal itself will be accessible as a dependency for the container it is declared in and all sub-containers just like other bindings) + +For example, you can declare a signal in your ProjectContext and then add signal handlers for each particular scene. Then, when each scene exits, the signal handler that was added in that scene will no longer be called when the signal is fired. + +Or, you could add signal handlers in the ProjectContext and then declare the signal in some particular scene. + +For example, You might use this to implement your GUI entirely in its own scene, loaded alongside the main backend scene. Then you could have the GUI scene strictly fire Signals, which would then have method bindings in the game scene. + +Something else you'll have noticed in the ExitGameSignal example above is that we also needed to install the SignalManager class: + +```csharp +Container.Bind().AsSingle(); +``` + +This needs to be installed somewhere, and it doesn't matter which container this is installed to, as long as the container is "above" or equal to every place that either signals or signal handlers are used. Therefore, the ideal place to put this line would be in the ProjectContext since this is the highest level container that exists. + +### Signals With Identifiers + +If you want to define multiple instances of the same signal, you would need to use identifiers. This works identically to how normal zenject binding identifiers work. For example: + +```csharp +Container.DeclareSignal().WithId("foo"); +``` + +Then for installer handlers: + +```csharp +Container.BindSignal().WithId("foo").To(x => x.DoSomething).AsSingle(); +``` + +Then to access it to fire it, or to add a C# event / unirx handlers: + +```csharp +public class Qux +{ + FooSignal _signal; + + public Qux( + [Inject(Id = "foo")] FooSignal signal) + { + _signal = signal; + } + + public void Run() + { + _signal.Fire(); + } +} +``` + diff --git a/README.md b/README.md index 4ce44fd7f..ef9bc1175 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ The tests may also be helpful to show usage for each specific feature (which you * Scene Decorators * Sub-Containers And Facades * Writing Automated Unit Tests / Integration Tests - * Commands And Signals + * Signals * Auto-Mocking using Moq * Creating Unity EditorWindow's with Zenject * Frequently Asked Questions @@ -1536,9 +1536,9 @@ public class MainInstaller : MonoInstaller } ``` -## Commands And Signals +## Signals -As of version 5.0, in an effort to keep things lightweight, Zenject no longer includes an implementation of commands and signals. The previous commands and signals package has been moved to another github repository. +See here. ## Creating Objects Dynamically Using Factories From 1bcfc9eea0acab1dc0feaa5985dff7139982cbd4 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 12 Feb 2017 16:21:05 -0400 Subject: [PATCH 49/62] Added back signals to the main repo --- .../Zenject/OptionalExtras/Signals.meta | 9 + .../OptionalExtras/Signals/ISignalHandler.cs | 11 + .../Signals/ISignalHandler.cs.meta | 12 + .../Signals/InstanceMethodSignalHandler.cs | 170 ++++++++++ .../InstanceMethodSignalHandler.cs.meta | 12 + .../Zenject/OptionalExtras/Signals/Signal0.cs | 108 ++++++ .../OptionalExtras/Signals/Signal0.cs.meta | 12 + .../Zenject/OptionalExtras/Signals/Signal1.cs | 109 ++++++ .../OptionalExtras/Signals/Signal1.cs.meta | 12 + .../Zenject/OptionalExtras/Signals/Signal2.cs | 110 ++++++ .../OptionalExtras/Signals/Signal2.cs.meta | 12 + .../Zenject/OptionalExtras/Signals/Signal3.cs | 110 ++++++ .../OptionalExtras/Signals/Signal3.cs.meta | 12 + .../Zenject/OptionalExtras/Signals/Signal4.cs | 109 ++++++ .../OptionalExtras/Signals/Signal4.cs.meta | 12 + .../OptionalExtras/Signals/SignalBase.cs | 66 ++++ .../OptionalExtras/Signals/SignalBase.cs.meta | 12 + .../OptionalExtras/Signals/SignalBinder.cs | 38 +++ .../Signals/SignalBinder.cs.meta | 12 + .../Signals/SignalExtensions.cs | 58 ++++ .../Signals/SignalExtensions.cs.meta | 12 + .../Signals/SignalFromBinder.cs | 143 ++++++++ .../Signals/SignalFromBinder.cs.meta | 12 + .../Signals/SignalHandlerBase.cs | 46 +++ .../Signals/SignalHandlerBase.cs.meta | 12 + .../Signals/SignalHandlerBinder.cs | 321 ++++++++++++++++++ .../Signals/SignalHandlerBinder.cs.meta | 12 + .../OptionalExtras/Signals/SignalManager.cs | 75 ++++ .../Signals/SignalManager.cs.meta | 12 + .../Signals/StaticMethodSignalHandler.cs | 134 ++++++++ .../Signals/StaticMethodSignalHandler.cs.meta | 12 + .../UnitTests/Editor/Signals.meta | 9 + .../UnitTests/Editor/Signals/TestSignals.cs | 120 +++++++ .../Editor/Signals/TestSignals.cs.meta | 12 + .../UnitTests/Editor/Signals/TestSignals2.cs | 235 +++++++++++++ .../Editor/Signals/TestSignals2.cs.meta | 12 + .../Editor/Signals/TestSignalsFourParams.cs | 96 ++++++ .../Signals/TestSignalsFourParams.cs.meta | 12 + .../Editor/Signals/TestSignalsOneParam.cs | 96 ++++++ .../Signals/TestSignalsOneParam.cs.meta | 12 + .../Signals/TestSignalsSubcontainers.cs | 114 +++++++ .../Signals/TestSignalsSubcontainers.cs.meta | 12 + .../Signals/TestSignalsWithIdentifiers.cs | 166 +++++++++ .../TestSignalsWithIdentifiers.cs.meta | 12 + .../Editor/Signals/TestSignalsWithIds2.cs | 121 +++++++ .../Signals/TestSignalsWithIds2.cs.meta | 12 + .../Signals/TestSignalsWithParameters2.cs | 178 ++++++++++ .../TestSignalsWithParameters2.cs.meta | 12 + .../UnitTests/Editor/Signals/TestTriggers1.cs | 46 +++ .../Editor/Signals/TestTriggers1.cs.meta | 12 + .../ProjectSettings/ProjectSettings.asset | 3 +- 51 files changed, 3088 insertions(+), 1 deletion(-) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/ISignalHandler.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/ISignalHandler.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/InstanceMethodSignalHandler.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/InstanceMethodSignalHandler.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal0.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal0.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBase.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBase.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBinder.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBinder.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalExtensions.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalExtensions.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalFromBinder.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalFromBinder.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBase.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBase.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBinder.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBinder.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalManager.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalManager.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/StaticMethodSignalHandler.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/StaticMethodSignalHandler.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals2.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals2.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSubcontainers.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSubcontainers.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIds2.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIds2.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs.meta create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals.meta new file mode 100644 index 000000000..720d99a45 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d31d2c8470fe19a4cb54efeae3418b72 +folderAsset: yes +timeCreated: 1486931461 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/ISignalHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/ISignalHandler.cs new file mode 100644 index 000000000..e6a133cff --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/ISignalHandler.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public interface ISignalHandler + { + void Execute(object[] args); + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/ISignalHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/ISignalHandler.cs.meta new file mode 100644 index 000000000..37e901747 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/ISignalHandler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b6e8cb801211c484a872c4ed493bb30a +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/InstanceMethodSignalHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/InstanceMethodSignalHandler.cs new file mode 100644 index 000000000..7240dc976 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/InstanceMethodSignalHandler.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using ModestTree.Util; + +namespace Zenject +{ + public abstract class InstanceMethodSignalHandlerBase : SignalHandlerBase + { + readonly Lazy _handler; + + [Inject] + public InstanceMethodSignalHandlerBase( + BindingId signalId, SignalManager manager, + Lazy handler) + : base(signalId, manager) + { + _handler = handler; + } + + public override void Execute(object[] args) + { + InternalExecute(_handler.Value, args); + } + + protected abstract void InternalExecute(THandler handler, object[] args); + } + + public class InstanceMethodSignalHandler : InstanceMethodSignalHandlerBase + { + readonly Func _methodGetter; + + [Inject] + public InstanceMethodSignalHandler( + BindingId signalId, SignalManager manager, Lazy handler, + Func methodGetter) + : base(signalId, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsEmpty()); + + var method = _methodGetter(handler); +#if UNITY_EDITOR + using (ProfileBlock.Start(method.ToDebugString())) +#endif + { + method(); + } + } + } + + public class InstanceMethodSignalHandler : InstanceMethodSignalHandlerBase + { + readonly Func> _methodGetter; + + [Inject] + public InstanceMethodSignalHandler( + BindingId signalId, SignalManager manager, Lazy handler, + Func> methodGetter) + : base(signalId, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + + var method = _methodGetter(handler); +#if UNITY_EDITOR + using (ProfileBlock.Start(method.ToDebugString())) +#endif + { + method((TParam1)args[0]); + } + } + } + + public class InstanceMethodSignalHandler : InstanceMethodSignalHandlerBase + { + readonly Func> _methodGetter; + + [Inject] + public InstanceMethodSignalHandler( + BindingId signalId, SignalManager manager, Lazy handler, + Func> methodGetter) + : base(signalId, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsLength(2)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + var method = _methodGetter(handler); +#if UNITY_EDITOR + using (ProfileBlock.Start(method.ToDebugString())) +#endif + { + method((TParam1)args[0], (TParam2)args[1]); + } + } + } + + public class InstanceMethodSignalHandler : InstanceMethodSignalHandlerBase + { + readonly Func> _methodGetter; + + [Inject] + public InstanceMethodSignalHandler( + BindingId signalId, SignalManager manager, Lazy handler, + Func> methodGetter) + : base(signalId, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsLength(3)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + ValidateParameter(args[2]); + var method = _methodGetter(handler); +#if UNITY_EDITOR + using (ProfileBlock.Start(method.ToDebugString())) +#endif + { + method((TParam1)args[0], (TParam2)args[1], (TParam3)args[2]); + } + } + } + + public class InstanceMethodSignalHandler : InstanceMethodSignalHandlerBase + { + readonly Func> _methodGetter; + + [Inject] + public InstanceMethodSignalHandler( + BindingId signalId, SignalManager manager, Lazy handler, + Func> methodGetter) + : base(signalId, manager, handler) + { + _methodGetter = methodGetter; + } + + protected override void InternalExecute(THandler handler, object[] args) + { + Assert.That(args.IsLength(4)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + ValidateParameter(args[2]); + ValidateParameter(args[3]); + var method = _methodGetter(handler); +#if UNITY_EDITOR + using (ProfileBlock.Start(method.ToDebugString())) +#endif + { + method((TParam1)args[0], (TParam2)args[1], (TParam3)args[2], (TParam4)args[3]); + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/InstanceMethodSignalHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/InstanceMethodSignalHandler.cs.meta new file mode 100644 index 000000000..7db301a43 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/InstanceMethodSignalHandler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 86d57d44320c4e44d83238355141c01f +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal0.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal0.cs new file mode 100644 index 000000000..c802e637b --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal0.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using ModestTree.Util; + +#if ZEN_SIGNALS_ADD_UNIRX +using UniRx; +#endif + +namespace Zenject +{ + // This is just used for generic constraints + public interface ISignal : ISignalBase + { + void Fire(); + } + + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal + { + readonly List _listeners = new List(); +#if ZEN_SIGNALS_ADD_UNIRX + readonly Subject _stream = new Subject(); +#endif + +#if ZEN_SIGNALS_ADD_UNIRX + public IObservableRx Stream + { + get + { + return _stream; + } + } +#endif + + public int NumListeners + { + get { return _listeners.Count; } + } + + public void Listen(Action listener) + { + Assert.That(!_listeners.Contains(listener), + () => "Tried to add method '{0}' to signal '{1}' but it has already been added" + .Fmt(listener.ToDebugString(), this.GetType())); + _listeners.Add(listener); + } + + public void Unlisten(Action listener) + { + bool success = _listeners.Remove(listener); + + Assert.That(success, + () => "Tried to remove method '{0}' from signal '{1}' without adding it first" + .Fmt(listener.ToDebugString(), this.GetType())); + } + + public static TDerived operator + (Signal signal, Action listener) + { + signal.Listen(listener); + return (TDerived)signal; + } + + public static TDerived operator - (Signal signal, Action listener) + { + signal.Unlisten(listener); + return (TDerived)signal; + } + + public void Fire() + { +#if UNITY_EDITOR + using (ProfileBlock.Start("Signal '{0}'", this.GetType().Name)) +#endif + { + var wasHandled = Manager.Trigger(SignalId, new object[0]); + + wasHandled |= !_listeners.IsEmpty(); + + // Use ToArray in case they remove in the handler + foreach (var listener in _listeners.ToArray()) + { +#if UNITY_EDITOR + using (ProfileBlock.Start(listener.ToDebugString())) +#endif + { + listener(); + } + } + +#if ZEN_SIGNALS_ADD_UNIRX + wasHandled |= _stream.HasObservers; +#if UNITY_EDITOR + using (ProfileBlock.Start("UniRx Stream")) +#endif + { + _stream.OnNext(); + } +#endif + if (Settings.RequiresHandler && !wasHandled) + { + throw Assert.CreateException( + "Signal '{0}' was fired but no handlers were attached and the signal is marked to require a handler!", SignalId); + } + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal0.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal0.cs.meta new file mode 100644 index 000000000..179b27767 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal0.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 73e64a3716d96cc429847a36a154d506 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs new file mode 100644 index 000000000..166bbe774 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using ModestTree.Util; + +#if ZEN_SIGNALS_ADD_UNIRX +using UniRx; +#endif + +namespace Zenject +{ + // This is just used for generic constraints + public interface ISignal : ISignalBase + { + void Fire(TParam1 p1); + } + + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal + { + readonly List> _listeners = new List>(); +#if ZEN_SIGNALS_ADD_UNIRX + readonly Subject _stream = new Subject(); +#endif + +#if ZEN_SIGNALS_ADD_UNIRX + public IObservableRx Stream + { + get + { + return _stream; + } + } +#endif + + public int NumListeners + { + get { return _listeners.Count; } + } + + public void Listen(Action listener) + { + Assert.That(!_listeners.Contains(listener), + () => "Tried to add method '{0}' to signal '{1}' but it has already been added" + .Fmt(listener.ToDebugString(), this.GetType())); + _listeners.Add(listener); + } + + public void Unlisten(Action listener) + { + bool success = _listeners.Remove(listener); + + Assert.That(success, + () => "Tried to remove method '{0}' from signal '{1}' without adding it first" + .Fmt(listener.ToDebugString(), this.GetType())); + } + + public static TDerived operator + (Signal signal, Action listener) + { + signal.Listen(listener); + return (TDerived)signal; + } + + public static TDerived operator - (Signal signal, Action listener) + { + signal.Unlisten(listener); + return (TDerived)signal; + } + + public void Fire(TParam1 p1) + { +#if UNITY_EDITOR + using (ProfileBlock.Start("Signal '{0}'", this.GetType().Name)) +#endif + { + var wasHandled = Manager.Trigger(SignalId, new object[] { p1 }); + + wasHandled |= !_listeners.IsEmpty(); + + // Use ToArray in case they remove in the handler + foreach (var listener in _listeners.ToArray()) + { +#if UNITY_EDITOR + using (ProfileBlock.Start(listener.ToDebugString())) +#endif + { + listener(p1); + } + } + +#if ZEN_SIGNALS_ADD_UNIRX + wasHandled |= _stream.HasObservers; +#if UNITY_EDITOR + using (ProfileBlock.Start("UniRx Stream")) +#endif + { + _stream.OnNext(p1); + } +#endif + + if (Settings.RequiresHandler && !wasHandled) + { + throw Assert.CreateException( + "Signal '{0}' was fired but no handlers were attached and the signal is marked to require a handler!", SignalId); + } + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs.meta new file mode 100644 index 000000000..081e33e35 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 143387d13293ae64aafa2908ea74ec94 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs new file mode 100644 index 000000000..66a4bdb1e --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using ModestTree.Util; + +#if ZEN_SIGNALS_ADD_UNIRX +using UniRx; +#endif + +namespace Zenject +{ + // This is just used for generic constraints + public interface ISignal : ISignalBase + { + void Fire(TParam1 p1, TParam2 p2); + } + + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal + { + readonly List> _listeners = new List>(); + +#if ZEN_SIGNALS_ADD_UNIRX + readonly Subject> _stream = new Subject>(); +#endif + +#if ZEN_SIGNALS_ADD_UNIRX + public IObservableRx> Stream + { + get + { + return _stream; + } + } +#endif + + public int NumListeners + { + get { return _listeners.Count; } + } + + public void Listen(Action listener) + { + Assert.That(!_listeners.Contains(listener), + () => "Tried to add method '{0}' to signal '{1}' but it has already been added" + .Fmt(listener.ToDebugString(), this.GetType())); + _listeners.Add(listener); + } + + public void Unlisten(Action listener) + { + bool success = _listeners.Remove(listener); + Assert.That(success, + () => "Tried to remove method '{0}' from signal '{1}' without adding it first" + .Fmt(listener.ToDebugString(), this.GetType())); + } + + public static TDerived operator + (Signal signal, Action listener) + { + signal.Listen(listener); + return (TDerived)signal; + } + + public static TDerived operator - (Signal signal, Action listener) + { + signal.Unlisten(listener); + return (TDerived)signal; + } + + public void Fire(TParam1 p1, TParam2 p2) + { +#if UNITY_EDITOR + using (ProfileBlock.Start("Signal '{0}'", this.GetType().Name)) +#endif + { + var wasHandled = Manager.Trigger(SignalId, new object[] { p1, p2 }); + + wasHandled |= !_listeners.IsEmpty(); + + // Use ToArray in case they remove in the handler + foreach (var listener in _listeners.ToArray()) + { +#if UNITY_EDITOR + using (ProfileBlock.Start(listener.ToDebugString())) +#endif + { + listener(p1, p2); + } + } + +#if ZEN_SIGNALS_ADD_UNIRX + wasHandled |= _stream.HasObservers; +#if UNITY_EDITOR + using (ProfileBlock.Start("UniRx Stream")) +#endif + { + _stream.OnNext(ValuePair.New(p1, p2)); + } +#endif + + if (Settings.RequiresHandler && !wasHandled) + { + throw Assert.CreateException( + "Signal '{0}' was fired but no handlers were attached and the signal is marked to require a handler!", SignalId); + } + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs.meta new file mode 100644 index 000000000..dadc5091a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d8ec0a54fda132541951795c50af8433 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs new file mode 100644 index 000000000..4e05da6d5 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using ModestTree.Util; + +#if ZEN_SIGNALS_ADD_UNIRX +using UniRx; +#endif + +namespace Zenject +{ + // This is just used for generic constraints + public interface ISignal : ISignalBase + { + void Fire(TParam1 p1, TParam2 p2, TParam3 p3); + } + + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal + { + readonly List> _listeners = new List>(); +#if ZEN_SIGNALS_ADD_UNIRX + readonly Subject> _stream = new Subject>(); +#endif + +#if ZEN_SIGNALS_ADD_UNIRX + public IObservableRx> Stream + { + get + { + return _stream; + } + } +#endif + + public int NumListeners + { + get { return _listeners.Count; } + } + + public void Listen(Action listener) + { + Assert.That(!_listeners.Contains(listener), + () => "Tried to add method '{0}' to signal '{1}' but it has already been added" + .Fmt(listener.ToDebugString(), this.GetType())); + _listeners.Add(listener); + } + + public void Unlisten(Action listener) + { + bool success = _listeners.Remove(listener); + Assert.That(success, + () => "Tried to remove method '{0}' from signal '{1}' without adding it first" + .Fmt(listener.ToDebugString(), this.GetType())); + } + + public static TDerived operator + (Signal signal, Action listener) + { + signal.Listen(listener); + return (TDerived)signal; + } + + public static TDerived operator - (Signal signal, Action listener) + { + signal.Unlisten(listener); + return (TDerived)signal; + } + + public void Fire(TParam1 p1, TParam2 p2, TParam3 p3) + { +#if UNITY_EDITOR + using (ProfileBlock.Start("Signal '{0}'", this.GetType().Name)) +#endif + { + var wasHandled = Manager.Trigger(SignalId, new object[] { p1, p2, p3 }); + + wasHandled |= !_listeners.IsEmpty(); + + // Use ToArray in case they remove in the handler + foreach (var listener in _listeners.ToArray()) + { +#if UNITY_EDITOR + using (ProfileBlock.Start(listener.ToDebugString())) +#endif + { + listener(p1, p2, p3); + } + } + +#if ZEN_SIGNALS_ADD_UNIRX + wasHandled |= _stream.HasObservers; +#if UNITY_EDITOR + using (ProfileBlock.Start("UniRx Stream")) +#endif + { + _stream.OnNext(ValuePair.New(p1, p2, p3)); + } +#endif + + if (Settings.RequiresHandler && !wasHandled) + { + throw Assert.CreateException( + "Signal '{0}' was fired but no handlers were attached and the signal is marked to require a handler!", SignalId); + } + } + } + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs.meta new file mode 100644 index 000000000..c0a3554a4 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 524b1ea47ab401847b0e00b3c854a4ce +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs new file mode 100644 index 000000000..cc50c0ec0 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using ModestTree.Util; + +#if ZEN_SIGNALS_ADD_UNIRX +using UniRx; +#endif + +namespace Zenject +{ + // This is just used for generic constraints + public interface ISignal : ISignalBase + { + void Fire(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4); + } + + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal + { + readonly List> _listeners = new List>(); +#if ZEN_SIGNALS_ADD_UNIRX + readonly Subject> _stream = new Subject>(); +#endif + +#if ZEN_SIGNALS_ADD_UNIRX + public IObservableRx> Stream + { + get + { + return _stream; + } + } +#endif + + public int NumListeners + { + get { return _listeners.Count; } + } + + public void Listen(Action listener) + { + Assert.That(!_listeners.Contains(listener), + () => "Tried to add method '{0}' to signal '{1}' but it has already been added" + .Fmt(listener.ToDebugString(), this.GetType())); + _listeners.Add(listener); + } + + public void Unlisten(Action listener) + { + bool success = _listeners.Remove(listener); + Assert.That(success, + () => "Tried to remove method '{0}' from signal '{1}' without adding it first" + .Fmt(listener.ToDebugString(), this.GetType())); + } + + public static TDerived operator + (Signal signal, Action listener) + { + signal.Listen(listener); + return (TDerived)signal; + } + + public static TDerived operator - (Signal signal, Action listener) + { + signal.Unlisten(listener); + return (TDerived)signal; + } + + public void Fire(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4) + { +#if UNITY_EDITOR + using (ProfileBlock.Start("Signal '{0}'", this.GetType().Name)) +#endif + { + var wasHandled = Manager.Trigger(SignalId, new object[] { p1, p2, p3, p4 }); + + wasHandled |= !_listeners.IsEmpty(); + + // Use ToArray in case they remove in the handler + foreach (var listener in _listeners.ToArray()) + { +#if UNITY_EDITOR + using (ProfileBlock.Start(listener.ToDebugString())) +#endif + { + listener(p1, p2, p3, p4); + } + } + +#if ZEN_SIGNALS_ADD_UNIRX + wasHandled |= _stream.HasObservers; +#if UNITY_EDITOR + using (ProfileBlock.Start("UniRx Stream")) +#endif + { + _stream.OnNext(ValuePair.New(p1, p2, p3, p4)); + } +#endif + + if (Settings.RequiresHandler && !wasHandled) + { + throw Assert.CreateException( + "Signal '{0}' was fired but no handlers were attached and the signal is marked to require a handler!", SignalId); + } + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs.meta new file mode 100644 index 000000000..b935e7c34 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e1c56dfb59b7617489380785a5ae27f6 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBase.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBase.cs new file mode 100644 index 000000000..bd3bf1c28 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBase.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public interface ISignalBase + { + int NumHandlers + { + get; + } + + bool HasHandler + { + get; + } + } + + public class SignalSettings + { + public bool RequiresHandler; + } + + public abstract class SignalBase : ISignalBase + { + SignalManager _manager; + + [Inject] + void Construct(SignalManager manager, SignalSettings settings, BindInfo bindInfo) + { + _manager = manager; + + SignalId = new BindingId(this.GetType(), bindInfo.Identifier); + Settings = settings; + } + + protected BindingId SignalId + { + get; + private set; + } + + protected SignalSettings Settings + { + get; + private set; + } + + protected SignalManager Manager + { + get { return _manager; } + } + + public int NumHandlers + { + get { return _manager.GetNumHandlers(SignalId); } + } + + public bool HasHandler + { + get { return _manager.IsHandlerRegistered(SignalId); } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBase.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBase.cs.meta new file mode 100644 index 000000000..c6332978c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBase.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3ec17db36cb69f84792d5dd931297f1e +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBinder.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBinder.cs new file mode 100644 index 000000000..4c62d7338 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBinder.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +namespace Zenject +{ + public class SignalBinder : ConditionCopyNonLazyBinder + { + readonly SignalSettings _signalSettings; + + public SignalBinder( + BindInfo bindInfo, SignalSettings signalSettings) + : base(bindInfo) + { + _signalSettings = signalSettings; + } + + public ConditionCopyNonLazyBinder RequireHandler() + { + _signalSettings.RequiresHandler = true; + return this; + } + } + + public class SignalBinderWithId : SignalBinder + { + public SignalBinderWithId( + BindInfo bindInfo, SignalSettings signalSettings) + : base(bindInfo, signalSettings) + { + } + + public SignalBinder WithId(object identifier) + { + this.BindInfo.Identifier = identifier; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBinder.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBinder.cs.meta new file mode 100644 index 000000000..e4d28fe67 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f1933dc35532fca48849ce65a3a31760 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalExtensions.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalExtensions.cs new file mode 100644 index 000000000..799c4b202 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalExtensions.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public static class SignalExtensions + { + public static SignalBinderWithId DeclareSignal(this DiContainer container) + where T : ISignalBase + { + var info = new BindInfo(typeof(T)); + var signalSettings = new SignalSettings(); + container.Bind(info).AsCached().WithArguments(signalSettings, info); + return new SignalBinderWithId(info, signalSettings); + } + + public static SignalHandlerBinderWithId BindSignal(this DiContainer container) + where TSignal : ISignal + { + var binder = container.StartBinding(); + return new SignalHandlerBinderWithId( + container, typeof(TSignal), binder); + } + + public static SignalHandlerBinderWithId BindSignal(this DiContainer container) + where TSignal : ISignal + { + var binder = container.StartBinding(); + return new SignalHandlerBinderWithId( + container, typeof(TSignal), binder); + } + + public static SignalHandlerBinderWithId BindSignal(this DiContainer container) + where TSignal : ISignal + { + var binder = container.StartBinding(); + return new SignalHandlerBinderWithId( + container, typeof(TSignal), binder); + } + + public static SignalHandlerBinderWithId BindSignal(this DiContainer container) + where TSignal : ISignal + { + var binder = container.StartBinding(); + return new SignalHandlerBinderWithId( + container, typeof(TSignal), binder); + } + + public static SignalHandlerBinderWithId BindSignal(this DiContainer container) + where TSignal : ISignal + { + var binder = container.StartBinding(); + return new SignalHandlerBinderWithId( + container, typeof(TSignal), binder); + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalExtensions.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalExtensions.cs.meta new file mode 100644 index 000000000..d7084d588 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalExtensions.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 81f656f8be3ab824f81de7580bdde054 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalFromBinder.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalFromBinder.cs new file mode 100644 index 000000000..f23f6c19a --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalFromBinder.cs @@ -0,0 +1,143 @@ +using System; + +#if !NOT_UNITY3D +using UnityEngine; +#endif + +namespace Zenject +{ + // We wrap FromBinderGeneric because some things in there that don't really work for signals + // like CopyInSubContainers, conditions, subcontainers + public class SignalFromBinder : ScopeArgNonLazyBinder + { + readonly BindInfo _info; + readonly FromBinderGeneric _subBinder; + + public SignalFromBinder( + BindInfo info, FromBinderGeneric subBinder) + : base(info) + { + _info = info; + _subBinder = subBinder; + } + + public ScopeArgNonLazyBinder FromFactory() + where TFactory : IFactory + { + _subBinder.FromFactory(); + return this; + } + + public ScopeArgNonLazyBinder FromFactory() + where TFactory : IFactory + where TConcrete : TContract + { + _subBinder.FromFactory(); + return this; + } + + public ScopeArgNonLazyBinder FromMethod(Func method) + { + _subBinder.FromMethod(method); + return this; + } + + public ScopeNonLazyBinder FromResolveGetter(Func method) + { + _subBinder.FromResolveGetter(method); + return new ScopeNonLazyBinder(_info); + } + + public ScopeNonLazyBinder FromResolveGetter(object identifier, Func method) + { + _subBinder.FromResolveGetter(identifier, method); + return new ScopeNonLazyBinder(_info); + } + + public ScopeNonLazyBinder FromInstance(TContract instance) + { + _subBinder.FromInstance(instance); + return new ScopeNonLazyBinder(_info); + } + + public ScopeNonLazyBinder FromInstance(TContract instance, bool allowNull) + { + _subBinder.FromInstance(instance, allowNull); + return new ScopeNonLazyBinder(_info); + } + + // This is the default if nothing else is called + public ScopeArgNonLazyBinder FromNew() + { + _subBinder.FromNew(); + return this; + } + + public ScopeNonLazyBinder FromResolve() + { + _subBinder.FromResolve(); + return new ScopeNonLazyBinder(_info); + } + + public ScopeNonLazyBinder FromResolve(object subIdentifier) + { + _subBinder.FromResolve(subIdentifier); + return new ScopeNonLazyBinder(_info); + } + + public ScopeArgNonLazyBinder FromFactory(Type factoryType) + { + _subBinder.FromFactory(factoryType); + return this; + } + +#if !NOT_UNITY3D + + public ScopeArgNonLazyBinder FromNewComponentOn(GameObject gameObject) + { + _subBinder.FromNewComponentOn(gameObject); + return this; + } + + public ArgNonLazyBinder FromNewComponentSibling() + { + _subBinder.FromNewComponentSibling(); + return this; + } + + public NameTransformScopeArgNonLazyBinder FromNewComponentOnNewGameObject() + { + var gameObjectInfo = new GameObjectCreationParameters(); + _subBinder.FromNewComponentOnNewGameObject(gameObjectInfo); + return new NameTransformScopeArgNonLazyBinder(_info, gameObjectInfo); + } + + public NameTransformScopeArgNonLazyBinder FromComponentInNewPrefab(UnityEngine.Object prefab) + { + var gameObjectInfo = new GameObjectCreationParameters(); + _subBinder.FromComponentInNewPrefab(prefab, gameObjectInfo); + return new NameTransformScopeArgNonLazyBinder(_info, gameObjectInfo); + } + + public NameTransformScopeArgNonLazyBinder FromComponentInNewPrefabResource(string resourcePath) + { + var gameObjectInfo = new GameObjectCreationParameters(); + _subBinder.FromComponentInNewPrefabResource(resourcePath, gameObjectInfo); + return new NameTransformScopeArgNonLazyBinder(_info, gameObjectInfo); + } + + public ScopeNonLazyBinder FromResource(string resourcePath) + { + _subBinder.FromResource(resourcePath); + return new ScopeNonLazyBinder(_info); + } + +#endif + + public ScopeArgNonLazyBinder FromMethodUntyped(Func method) + { + _subBinder.FromMethodUntyped(method); + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalFromBinder.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalFromBinder.cs.meta new file mode 100644 index 000000000..d64b8deef --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalFromBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1127d585dc0aa7a45a61d1e0ec7e5fe2 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBase.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBase.cs new file mode 100644 index 000000000..5d29603c4 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBase.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public abstract class SignalHandlerBase : ISignalHandler, IDisposable, IInitializable + { + readonly SignalManager _manager; + readonly BindingId _signalId; + + [Inject] + public SignalHandlerBase( + BindingId signalId, SignalManager manager) + { + _manager = manager; + _signalId = signalId; + } + + public void Initialize() + { + _manager.Register(_signalId, this); + } + + public void Dispose() + { + _manager.Unregister(_signalId, this); + } + + protected void ValidateParameter(object value) + { + if (value == null) + { + Assert.That(!typeof(T).IsValueType()); + } + else + { + Assert.That(value.GetType().DerivesFromOrEqual()); + } + } + + public abstract void Execute(object[] args); + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBase.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBase.cs.meta new file mode 100644 index 000000000..71b1e8b7f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBase.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fabf0ea555da0ed44adeaadfc3bc02b5 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBinder.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBinder.cs new file mode 100644 index 000000000..276f6e3fa --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBinder.cs @@ -0,0 +1,321 @@ +using System; +using System.Collections.Generic; +using ModestTree; + +namespace Zenject +{ + public abstract class SignalHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _signalType; + readonly DiContainer _container; + + public SignalHandlerBinder( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _signalType = signalType; + _finalizerWrapper = finalizerWrapper; + } + + protected object Identifier + { + get; + set; + } + + public SignalFromBinder To(Func methodGetter) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(methodGetter, lazyLookup, new BindingId(_signalType, Identifier)); + + var info = new BindInfo(typeof(THandler)); + + return new SignalFromBinder( + info, _container.Bind(info).WithId(lookupId).To()); + } + + public void To(Action method) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To().AsCached() + .WithArguments(method, new BindingId(_signalType, Identifier)); + } + } + + public class SignalHandlerBinderWithId : SignalHandlerBinder + { + public SignalHandlerBinderWithId( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + : base(container, signalType, finalizerWrapper) + { + } + + public SignalHandlerBinder WithId(object identifier) + { + Identifier = identifier; + return this; + } + } + + public abstract class SignalHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _signalType; + readonly DiContainer _container; + + public SignalHandlerBinder( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _signalType = signalType; + _finalizerWrapper = finalizerWrapper; + } + + protected object Identifier + { + get; + set; + } + + public SignalFromBinder To(Func> methodGetter) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(methodGetter, lazyLookup, new BindingId(_signalType, Identifier)); + + var info = new BindInfo(typeof(THandler)); + + return new SignalFromBinder( + info, _container.Bind(info).WithId(lookupId).To()); + } + + public void To(Action method) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(method, new BindingId(_signalType, Identifier)); + } + } + + public class SignalHandlerBinderWithId : SignalHandlerBinder + { + public SignalHandlerBinderWithId( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + : base(container, signalType, finalizerWrapper) + { + } + + public SignalHandlerBinder WithId(object identifier) + { + Identifier = identifier; + return this; + } + } + + public abstract class SignalHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _signalType; + readonly DiContainer _container; + + public SignalHandlerBinder( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _signalType = signalType; + _finalizerWrapper = finalizerWrapper; + } + + protected object Identifier + { + get; + set; + } + + public SignalFromBinder To(Func> methodGetter) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(methodGetter, lazyLookup, new BindingId(_signalType, Identifier)); + + var info = new BindInfo(typeof(THandler)); + + return new SignalFromBinder( + info, _container.Bind(info).WithId(lookupId).To()); + } + + public void To(Action method) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(method, new BindingId(_signalType, Identifier)); + } + } + + public class SignalHandlerBinderWithId : SignalHandlerBinder + { + public SignalHandlerBinderWithId( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + : base(container, signalType, finalizerWrapper) + { + } + + public SignalHandlerBinderWithId WithId(object identifier) + { + Identifier = identifier; + return this; + } + } + + public abstract class SignalHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _signalType; + readonly DiContainer _container; + + public SignalHandlerBinder( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _signalType = signalType; + _finalizerWrapper = finalizerWrapper; + } + + protected object Identifier + { + get; + set; + } + + public SignalFromBinder To(Func> methodGetter) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(methodGetter, lazyLookup, new BindingId(_signalType, Identifier)); + + var info = new BindInfo(typeof(THandler)); + + return new SignalFromBinder( + info, _container.Bind(info).WithId(lookupId).To()); + } + + public void To(Action method) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(method, new BindingId(_signalType, Identifier)); + } + } + + public class SignalHandlerBinderWithId : SignalHandlerBinder + { + public SignalHandlerBinderWithId( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + : base(container, signalType, finalizerWrapper) + { + } + + public SignalHandlerBinderWithId WithId(object identifier) + { + Identifier = identifier; + return this; + } + } + + public abstract class SignalHandlerBinder + { + readonly BindFinalizerWrapper _finalizerWrapper; + readonly Type _signalType; + readonly DiContainer _container; + + public SignalHandlerBinder( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + { + _container = container; + _signalType = signalType; + _finalizerWrapper = finalizerWrapper; + } + + protected object Identifier + { + get; + set; + } + + public SignalFromBinder To(Func> methodGetter) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + var lookupId = Guid.NewGuid(); + var lazyLookup = new Lazy( + _container, new InjectContext(_container, typeof(THandler), lookupId)); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(methodGetter, lazyLookup, new BindingId(_signalType, Identifier)); + + var info = new BindInfo(typeof(THandler)); + + return new SignalFromBinder( + info, _container.Bind(info).WithId(lookupId).To()); + } + + public void To(Action method) + { + // This is just to ensure they don't stop at BindSignal + _finalizerWrapper.SubFinalizer = new NullBindingFinalizer(); + + _container.Bind(typeof(IInitializable), typeof(IDisposable)).To>().AsCached() + .WithArguments(method, new BindingId(_signalType, Identifier)); + } + } + + public class SignalHandlerBinderWithId : SignalHandlerBinder + { + public SignalHandlerBinderWithId( + DiContainer container, Type signalType, BindFinalizerWrapper finalizerWrapper) + : base(container, signalType, finalizerWrapper) + { + } + + public SignalHandlerBinderWithId WithId(object identifier) + { + Identifier = identifier; + return this; + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBinder.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBinder.cs.meta new file mode 100644 index 000000000..d38db8565 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalHandlerBinder.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a3dbdd63eab270c4d99190b197aff23c +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalManager.cs new file mode 100644 index 000000000..1b8cc4625 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalManager.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using System.Linq; +using ModestTree.Util; + +namespace Zenject +{ + public class SignalManager : ILateDisposable + { + readonly Dictionary> _signalHandlers = new Dictionary>(); + + public int GetNumHandlers(BindingId signalType) + { + return GetList(signalType).Count(); + } + + public bool IsHandlerRegistered(BindingId signalType) + { + return !GetList(signalType).IsEmpty(); + } + + List GetList(BindingId signalType) + { + List handlers; + + if (!_signalHandlers.TryGetValue(signalType, out handlers)) + { + handlers = new List(); + _signalHandlers.Add(signalType, handlers); + } + + return handlers; + } + + public void Register(BindingId signalType, ISignalHandler handler) + { + GetList(signalType).Add(handler); + } + + public void Unregister(BindingId signalType, ISignalHandler handler) + { + GetList(signalType).RemoveWithConfirm(handler); + } + + public void LateDispose() + { + Assert.Warn(_signalHandlers.Values.SelectMany(x => x).IsEmpty(), + "Found signals still registered on SignalManager"); + } + + // Returns true the signal was handled + public bool Trigger(BindingId signalType, object[] args) + { + var handlers = GetList(signalType); + + if (handlers.IsEmpty()) + { + return false; + } + +#if UNITY_EDITOR + using (ProfileBlock.Start("Signal '{0}'", signalType)) +#endif + { + foreach (var handler in handlers) + { + handler.Execute(args); + } + } + + return true; + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalManager.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalManager.cs.meta new file mode 100644 index 000000000..d1a0ab747 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/SignalManager.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b21bac0f5047e384ca08f5f15782b3ee +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/StaticMethodSignalHandler.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/StaticMethodSignalHandler.cs new file mode 100644 index 000000000..9ee3e4074 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/StaticMethodSignalHandler.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using ModestTree; +using ModestTree.Util; + +namespace Zenject +{ + public class StaticMethodSignalHandler : SignalHandlerBase + { + readonly Action _method; + + public StaticMethodSignalHandler( + BindingId signalId, SignalManager manager, Action method) + : base(signalId, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsEmpty()); + +#if UNITY_EDITOR + using (ProfileBlock.Start(_method.ToDebugString())) +#endif + { + _method(); + } + } + } + + public class StaticMethodSignalHandler : SignalHandlerBase + { + readonly Action _method; + + public StaticMethodSignalHandler( + BindingId signalId, SignalManager manager, Action method) + : base(signalId, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); +#if UNITY_EDITOR + using (ProfileBlock.Start(_method.ToDebugString())) +#endif + { + _method((TParam1)args[0]); + } + } + } + + public class StaticMethodSignalHandler : SignalHandlerBase + { + readonly Action _method; + + public StaticMethodSignalHandler( + BindingId signalId, SignalManager manager, Action method) + : base(signalId, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); +#if UNITY_EDITOR + using (ProfileBlock.Start(_method.ToDebugString())) +#endif + { + _method((TParam1)args[0], (TParam2)args[1]); + } + } + } + + public class StaticMethodSignalHandler : SignalHandlerBase + { + readonly Action _method; + + public StaticMethodSignalHandler( + BindingId signalId, SignalManager manager, Action method) + : base(signalId, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + ValidateParameter(args[2]); +#if UNITY_EDITOR + using (ProfileBlock.Start(_method.ToDebugString())) +#endif + { + _method((TParam1)args[0], (TParam2)args[1], (TParam3)args[2]); + } + } + } + + public class StaticMethodSignalHandler : SignalHandlerBase + { + readonly Action _method; + + public StaticMethodSignalHandler( + BindingId signalId, SignalManager manager, Action method) + : base(signalId, manager) + { + _method = method; + } + + public override void Execute(object[] args) + { + Assert.That(args.IsLength(1)); + ValidateParameter(args[0]); + ValidateParameter(args[1]); + ValidateParameter(args[2]); + ValidateParameter(args[3]); +#if UNITY_EDITOR + using (ProfileBlock.Start(_method.ToDebugString())) +#endif + { + _method((TParam1)args[0], (TParam2)args[1], (TParam3)args[2], (TParam4)args[3]); + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/StaticMethodSignalHandler.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/StaticMethodSignalHandler.cs.meta new file mode 100644 index 000000000..fe7298790 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/StaticMethodSignalHandler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: be92b263b562bc94790fd2af8d30ee45 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals.meta new file mode 100644 index 000000000..1157d8096 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5807ecfa581fab14e9f8dc8642a02b1d +folderAsset: yes +timeCreated: 1486931461 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs new file mode 100644 index 000000000..8fbcf9349 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestSignals : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void RunTest() + { + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + + Container.DeclareSignal(); + + Initialize(); + + var foo = Container.Resolve(); + var bar = Container.Resolve(); + bar.Initialize(); + + Assert.That(!bar.ReceivedSignal); + foo.DoSomething(); + Assert.That(bar.ReceivedSignal); + + bar.Dispose(); + } + + [Test] + public void RunTestSignalInterfaces() + { + Container.DeclareSignal(); + + Container.DeclareSignal(); + + Container.Bind() + .To(typeof(AnotherSignal), typeof(SomethingHappenedSignal)).FromResolve(); + + Initialize(); + + var fooSignals = Container.ResolveAll(); + + Assert.IsEqual(fooSignals.Count, 2); + } + + public interface IFooSignal + { + } + + public class SomethingHappenedSignal : Signal, IFooSignal + { + } + + public class AnotherSignal : Signal, IFooSignal + { + } + + public class Foo + { + SomethingHappenedSignal _trigger; + + public Foo(SomethingHappenedSignal trigger) + { + _trigger = trigger; + } + + public void DoSomething() + { + _trigger.Fire(); + } + } + + public class Bar + { + SomethingHappenedSignal _signal; + bool _receivedSignal; + + public Bar(SomethingHappenedSignal signal) + { + _signal = signal; + } + + public bool ReceivedSignal + { + get + { + return _receivedSignal; + } + } + + public void Initialize() + { + _signal += OnStarted; + } + + public void Dispose() + { + _signal -= OnStarted; + } + + void OnStarted() + { + _receivedSignal = true; + } + } + } +} diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs.meta new file mode 100644 index 000000000..91e982fb7 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fb2be2ab4306cc043a5507c8c6327763 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals2.cs new file mode 100644 index 000000000..f5ec42412 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals2.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +#if ZEN_SIGNALS_ADD_UNIRX +using UniRx; +#endif + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestSignals2 : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void TestToSingle1() + { + Bar.WasTriggered = false; + Bar.InstanceCount = 0; + + Container.Bind().AsSingle(); + + Container.DeclareSignal(); + Container.BindSignal() + .To(x => x.Execute).AsSingle(); + + Initialize(); + + Container.Resolve(); + var cmd = Container.Resolve(); + + Assert.IsEqual(Bar.InstanceCount, 1); + Assert.That(!Bar.WasTriggered); + + cmd.Fire(); + + Assert.That(Bar.WasTriggered); + Assert.IsEqual(Bar.InstanceCount, 1); + } + + [Test] + public void TestToCached1() + { + Bar.WasTriggered = false; + Bar.InstanceCount = 0; + + Container.Bind().AsCached(); + + Container.DeclareSignal(); + Container.BindSignal() + .To(x => x.Execute).AsCached(); + + Initialize(); + + Container.Resolve(); + var cmd = Container.Resolve(); + + Assert.IsEqual(Bar.InstanceCount, 1); + Assert.That(!Bar.WasTriggered); + + cmd.Fire(); + + Assert.That(Bar.WasTriggered); + Assert.IsEqual(Bar.InstanceCount, 2); + + cmd.Fire(); + Assert.IsEqual(Bar.InstanceCount, 2); + } + + [Test] + public void TestNoHandlerDefault() + { + Container.DeclareSignal(); + + Initialize(); + + var cmd = Container.Resolve(); + cmd.Fire(); + } + + [Test] + public void TestNoHandlerRequiredFailure() + { + Container.DeclareSignal().RequireHandler(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.Throws(() => cmd.Fire()); + } + + [Test] + public void TestNoHandlerRequiredSuccess() + { + Container.DeclareSignal().RequireHandler(); + Container.BindSignal() + .To(x => x.Execute).AsCached(); + + Initialize(); + + var cmd = Container.Resolve(); + cmd.Fire(); + } + + [Test] + public void TestHandlerRequiredEventStyle() + { + Container.DeclareSignal().RequireHandler(); + + Initialize(); + + var signal = Container.Resolve(); + + Assert.Throws(() => signal.Fire()); + + bool received = false; + + Action receiveSignal = () => received = true; + + signal += receiveSignal; + + Assert.That(!received); + signal.Fire(); + Assert.That(received); + + signal -= receiveSignal; + + Assert.Throws(() => signal.Fire()); + } + +#if ZEN_SIGNALS_ADD_UNIRX + [Test] + public void TestHandlerRequiredUniRxStyle() + { + Container.DeclareSignal().RequireHandler(); + + Initialize(); + + var signal = Container.Resolve(); + + Assert.Throws(() => signal.Fire()); + + bool received = false; + + var subscription = signal.Stream.Subscribe(() => received = true); + + Assert.That(!received); + signal.Fire(); + Assert.That(received); + + subscription.Dispose(); + + Assert.Throws(() => signal.Fire()); + } +#endif + + [Test] + public void TestToMethod() + { + bool wasCalled = false; + + Container.DeclareSignal(); + Container.BindSignal() + .To(() => wasCalled = true); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.That(!wasCalled); + cmd.Fire(); + Assert.That(wasCalled); + } + + [Test] + public void TestMultipleHandlers() + { + bool wasCalled1 = false; + bool wasCalled2 = false; + + Container.DeclareSignal(); + Container.BindSignal() + .To(() => wasCalled1 = true); + Container.BindSignal() + .To(() => wasCalled2 = true); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.That(!wasCalled1); + Assert.That(!wasCalled2); + cmd.Fire(); + Assert.That(wasCalled1); + Assert.That(wasCalled2); + } + + public class DoSomethingSignal : Signal + { + } + + public class Bar + { + public static int InstanceCount = 0; + + public Bar() + { + InstanceCount ++; + } + + public static bool WasTriggered + { + get; + set; + } + + public void Execute() + { + WasTriggered = true; + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals2.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals2.cs.meta new file mode 100644 index 000000000..5f1ab807f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignals2.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8f9e44048f82279448670e488fc6de55 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs new file mode 100644 index 000000000..e5ae6227b --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestSignalsSixParams : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void RunTest() + { + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + + Container.DeclareSignal(); + + Initialize(); + + var foo = Container.Resolve(); + var bar = Container.Resolve(); + bar.Initialize(); + + Assert.IsNull(bar.ReceivedValue); + foo.DoSomething("asdf", 5, 1.2f, "zxcv"); + Assert.IsEqual(bar.ReceivedValue, "zxcv"); + + bar.Dispose(); + } + + public class SomethingHappenedSignal : Signal + { + } + + public class Foo + { + SomethingHappenedSignal _signal; + + public Foo(SomethingHappenedSignal signal) + { + _signal = signal; + } + + public void DoSomething(string value1, int value2, float value3, string value4) + { + _signal.Fire(value1, value2, value3, value4); + } + } + + public class Bar + { + SomethingHappenedSignal _signal; + string _receivedValue; + + public Bar(SomethingHappenedSignal signal) + { + _signal = signal; + } + + public string ReceivedValue + { + get + { + return _receivedValue; + } + } + + public void Initialize() + { + _signal += OnStarted; + } + + public void Dispose() + { + _signal -= OnStarted; + } + + void OnStarted(string value1, int value2, float value3, string value4) + { + _receivedValue = value4; + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs.meta new file mode 100644 index 000000000..8381a3452 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f0e9dc5c8f3c8804ea3e0873152ee7e8 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs new file mode 100644 index 000000000..6eb12324b --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestSignalsOneParam : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void RunTest() + { + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + + Container.DeclareSignal(); + + Initialize(); + + var foo = Container.Resolve(); + var bar = Container.Resolve(); + bar.Initialize(); + + Assert.IsNull(bar.ReceivedValue); + foo.DoSomething("asdf"); + Assert.IsEqual(bar.ReceivedValue, "asdf"); + + bar.Dispose(); + } + + public class SomethingHappenedSignal : Signal + { + } + + public class Foo + { + SomethingHappenedSignal _trigger; + + public Foo(SomethingHappenedSignal trigger) + { + _trigger = trigger; + } + + public void DoSomething(string value) + { + _trigger.Fire(value); + } + } + + public class Bar + { + SomethingHappenedSignal _signal; + string _receivedValue; + + public Bar(SomethingHappenedSignal signal) + { + _signal = signal; + } + + public string ReceivedValue + { + get + { + return _receivedValue; + } + } + + public void Initialize() + { + _signal += OnStarted; + } + + public void Dispose() + { + _signal -= OnStarted; + } + + void OnStarted(string value) + { + _receivedValue = value; + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs.meta new file mode 100644 index 000000000..1aabeb997 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4fce2bc53a6ad18499b06d3914750ebd +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSubcontainers.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSubcontainers.cs new file mode 100644 index 000000000..f699db230 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSubcontainers.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestSignalsSubcontainers : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void TestMissingDeclaration() + { + Container.BindSignal().To(x => x.Execute).AsSingle(); + Initialize(); + } + + [Test] + public void TestDeclarationBelowHandler() + { + Bar.WasTriggered = false; + + Container.BindSignal().To(x => x.Execute).AsSingle(); + + Container.BindInterfacesAndSelfTo().FromSubContainerResolve().ByMethod(InstallFoo).AsSingle().NonLazy(); + + Initialize(); + + Assert.Throws(() => Container.Resolve()); + + var foo = Container.Resolve(); + + Assert.That(!Bar.WasTriggered); + foo.Trigger(); + Assert.That(Bar.WasTriggered); + } + + static void InstallFoo(DiContainer container) + { + container.Bind().AsSingle(); + container.DeclareSignal(); + } + + [Test] + public void TestDeclarationAboveHandler() + { + Bar.WasTriggered = false; + + Container.DeclareSignal(); + + Container.BindInterfacesAndSelfTo().FromSubContainerResolve().ByMethod(InstallFoo2).AsSingle().NonLazy(); + + Initialize(); + + var cmd = Container.Resolve(); + var foo = Container.Resolve(); + + Assert.That(!Bar.WasTriggered); + cmd.Fire(); + Assert.That(Bar.WasTriggered); + } + + static void InstallFoo2(DiContainer container) + { + container.Bind().AsSingle(); + container.BindSignal().To(x => x.Execute).AsSingle(); + } + + public class Foo : Kernel + { + readonly DoSomethingSignal _command; + + public Foo(DoSomethingSignal command) + { + _command = command; + } + + public void Trigger() + { + _command.Fire(); + } + } + + public class DoSomethingSignal : Signal + { + } + + public class Bar + { + public static bool WasTriggered + { + get; + set; + } + + public void Execute() + { + WasTriggered = true; + } + } + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSubcontainers.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSubcontainers.cs.meta new file mode 100644 index 000000000..41f632a6b --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsSubcontainers.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4eb0c7ebe1daa5b479001496938cc4d9 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs new file mode 100644 index 000000000..61cbbe17e --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestSignalsWithIdentifiers : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void RunTest() + { + Container.DeclareSignal(); + + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + + Container.DeclareSignal().WithId("special"); + + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + + Initialize(); + + var foo = Container.Resolve(); + var bar = Container.Resolve(); + + var fooSpecial = Container.Resolve(); + var barSpecial = Container.Resolve(); + + bar.Initialize(); + barSpecial.Initialize(); + + Assert.IsNull(bar.ReceivedValue); + Assert.IsNull(barSpecial.ReceivedValue); + + foo.DoSomething("asdf"); + + Assert.IsEqual(bar.ReceivedValue, "asdf"); + Assert.IsNull(barSpecial.ReceivedValue); + + bar.ReceivedValue = null; + + fooSpecial.DoSomething("zxcv"); + + Assert.IsEqual(barSpecial.ReceivedValue, "zxcv"); + Assert.IsNull(bar.ReceivedValue); + + bar.Dispose(); + barSpecial.Dispose(); + } + + public class SomethingHappenedSignal : Signal + { + } + + public class Foo + { + SomethingHappenedSignal _signal; + + public Foo( + SomethingHappenedSignal signal) + { + _signal = signal; + } + + public void DoSomething(string value) + { + _signal.Fire(value); + } + } + + public class Bar + { + SomethingHappenedSignal _signal; + + public Bar(SomethingHappenedSignal signal) + { + _signal = signal; + } + + public string ReceivedValue + { + get; + set; + } + + public void Initialize() + { + _signal += OnStarted; + } + + public void Dispose() + { + _signal -= OnStarted; + } + + void OnStarted(string value) + { + ReceivedValue = value; + } + } + + public class FooSpecial + { + SomethingHappenedSignal _signal; + + public FooSpecial( + [Inject(Id = "special")] + SomethingHappenedSignal signal) + { + _signal = signal; + } + + public void DoSomething(string value) + { + _signal.Fire(value); + } + } + + public class BarSpecial + { + SomethingHappenedSignal _signal; + + public BarSpecial( + [Inject(Id = "special")] + SomethingHappenedSignal signal) + { + _signal = signal; + } + + public string ReceivedValue + { + get; + set; + } + + public void Initialize() + { + _signal += OnStarted; + } + + public void Dispose() + { + _signal -= OnStarted; + } + + void OnStarted(string value) + { + ReceivedValue = value; + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs.meta new file mode 100644 index 000000000..533494de1 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7a21cb4e5c86ab44ba187662530b44d8 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIds2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIds2.cs new file mode 100644 index 000000000..24178beb5 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIds2.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestSignalsWithIds2 : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void TestNormal() + { + Bar.WasTriggered = false; + + Container.DeclareSignal(); + Container.BindSignal().To(x => x.Execute).AsSingle(); + + Initialize(); + + Assert.That(!Bar.WasTriggered); + + Container.Resolve().Fire(); + + Assert.That(Bar.WasTriggered); + } + + [Test] + public void TestIdsError() + { + Bar.WasTriggered = false; + + Container.DeclareSignal().WithId("asdf"); + Container.BindSignal().To(x => x.Execute).AsSingle(); + + Initialize(); + + Assert.Throws(() => Container.Resolve()); + + Assert.That(!Bar.WasTriggered); + Container.ResolveId("asdf").Fire(); + Assert.That(!Bar.WasTriggered); + } + + [Test] + public void TestIdsSuccess() + { + Bar.WasTriggered = false; + Bar2.WasTriggered = false; + + Container.DeclareSignal().WithId("asdf"); + Container.BindSignal().WithId("asdf").To(x => x.Execute).AsSingle(); + + Container.DeclareSignal().WithId("qwer"); + Container.BindSignal().WithId("qwer").To(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd1 = Container.ResolveId("asdf"); + var cmd2 = Container.ResolveId("qwer"); + + Assert.That(!Bar.WasTriggered); + Assert.That(!Bar2.WasTriggered); + + cmd1.Fire(); + + Assert.That(Bar.WasTriggered); + Assert.That(!Bar2.WasTriggered); + + Bar.WasTriggered = false; + + cmd2.Fire(); + + Assert.That(!Bar.WasTriggered); + Assert.That(Bar2.WasTriggered); + } + + public class DoSomethingSignal : Signal + { + } + + public class Bar + { + public static bool WasTriggered + { + get; + set; + } + + public void Execute() + { + WasTriggered = true; + } + } + + public class Bar2 + { + public static bool WasTriggered + { + get; + set; + } + + public void Execute() + { + WasTriggered = true; + } + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIds2.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIds2.cs.meta new file mode 100644 index 000000000..370a9594f --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIds2.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b2f07642236a7964a91858eb2e9d38f1 +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs new file mode 100644 index 000000000..5cac15a5c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestSignalsWithParameters2 : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void TestParameters1() + { + Bar1.Value = null; + + Container.DeclareSignal(); + Container.BindSignal() + .To(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.IsNull(Bar1.Value); + + cmd.Fire("asdf"); + + Assert.IsEqual(Bar1.Value, "asdf"); + } + + [Test] + public void TestParameters2() + { + Bar2.Value1 = null; + Bar2.Value2 = 0; + + Container.DeclareSignal(); + Container.BindSignal() + .To(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.IsNull(Bar2.Value1); + Assert.IsEqual(Bar2.Value2, 0); + + cmd.Fire("asdf", 4); + + Assert.IsEqual(Bar2.Value1, "asdf"); + Assert.IsEqual(Bar2.Value2, 4); + } + + [Test] + public void TestParameters3() + { + Bar3.Value1 = null; + Bar3.Value2 = 0; + Bar3.Value3 = 0.0f; + + Container.DeclareSignal(); + Container.BindSignal() + .To(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.IsNull(Bar3.Value1); + Assert.IsEqual(Bar3.Value2, 0); + Assert.IsEqual(Bar3.Value3, 0.0f); + + cmd.Fire("asdf", 4, 7.2f); + + Assert.IsEqual(Bar3.Value1, "asdf"); + Assert.IsEqual(Bar3.Value2, 4); + Assert.IsEqual(Bar3.Value3, 7.2f); + } + + [Test] + public void TestParameters4() + { + Bar4.Value1 = null; + Bar4.Value2 = 0; + Bar4.Value3 = 0.0f; + Bar4.Value4 = '0'; + + Container.DeclareSignal(); + Container.BindSignal() + .To(x => x.Execute).AsSingle(); + + Initialize(); + + var cmd = Container.Resolve(); + + Assert.IsNull(Bar4.Value1); + Assert.IsEqual(Bar4.Value2, 0); + Assert.IsEqual(Bar4.Value3, 0.0f); + Assert.IsEqual(Bar4.Value4, '0'); + + cmd.Fire("asdf", 4, 7.2f, 'z'); + + Assert.IsEqual(Bar4.Value1, "asdf"); + Assert.IsEqual(Bar4.Value2, 4); + Assert.IsEqual(Bar4.Value3, 7.2f); + Assert.IsEqual(Bar4.Value4, 'z'); + } + + public class DoSomethingSignal1 : Signal { } + public class DoSomethingSignal2 : Signal { } + public class DoSomethingSignal3 : Signal { } + public class DoSomethingSignal4 : Signal { } + + public class Bar1 + { + public static string Value; + + public void Execute(string value) + { + Value = value; + } + } + + public class Bar2 + { + public static string Value1; + public static int Value2; + + public void Execute(string value1, int value2) + { + Value1 = value1; + Value2 = value2; + } + } + + public class Bar3 + { + public static string Value1; + public static int Value2; + public static float Value3; + + public void Execute(string value1, int value2, float value3) + { + Value1 = value1; + Value2 = value2; + Value3 = value3; + } + } + + public class Bar4 + { + public static string Value1; + public static int Value2; + public static float Value3; + public static char Value4; + + public void Execute(string value1, int value2, float value3, char value4) + { + Value1 = value1; + Value2 = value2; + Value3 = value3; + Value4 = value4; + } + } + } +} + + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs.meta new file mode 100644 index 000000000..e5ca1901c --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ea2c73d661afc9648a8db4feb5aa715d +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs new file mode 100644 index 000000000..ef4183f82 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ModestTree; +using Assert=ModestTree.Assert; +using Zenject; + +namespace ZenjectSignalsAndSignals.Tests +{ + [TestFixture] + public class TestTriggers1 : ZenjectIntegrationTestFixture + { + [SetUp] + public void CommonInstall() + { + Container.BindInterfacesAndSelfTo().AsSingle(); + } + + [Test] + public void Test1() + { + Container.DeclareSignal(); + + Initialize(); + + var signal = Container.Resolve(); + + bool received = false; + signal += delegate { received = true; }; + + // This is a compiler error + //signal.Event(); + + Assert.That(!received); + signal.Fire(); + Assert.That(received); + } + + public class FooSignal : Signal + { + } + } +} + diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs.meta new file mode 100644 index 000000000..dff0accbb --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestTriggers1.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 775eec8339ae09c4fb591e60714566de +timeCreated: 1486914624 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/ProjectSettings/ProjectSettings.asset b/UnityProject/ProjectSettings/ProjectSettings.asset index be84e671f..4b59f04a9 100644 --- a/UnityProject/ProjectSettings/ProjectSettings.asset +++ b/UnityProject/ProjectSettings/ProjectSettings.asset @@ -445,7 +445,8 @@ PlayerSettings: webGLUseEmbeddedResources: 0 webGLUseWasm: 0 webGLCompressionFormat: 1 - scriptingDefineSymbols: {} + scriptingDefineSymbols: + 13: ZEN_SIGNALS_ADD_UNIRX platformArchitecture: iOS: 2 scriptingBackend: From e87ecadca2c511d2832ca79f50a563033462eae4 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 12 Feb 2017 18:51:19 -0400 Subject: [PATCH 50/62] Added documentation for memory pools --- Documentation/MemoryPools.md | 427 ++++++++++++++++++++++++++++++++++- 1 file changed, 426 insertions(+), 1 deletion(-) diff --git a/Documentation/MemoryPools.md b/Documentation/MemoryPools.md index bf66b5fee..64706eea1 100644 --- a/Documentation/MemoryPools.md +++ b/Documentation/MemoryPools.md @@ -1,5 +1,430 @@ ## Memory Pools -TBD +### Introduction + +Before understanding memory pools it would be helpful to understand factories, so please read the docs on factories first. + +It doesn't take long when developing games in Unity before you realize that proper memory management is very important if you want your game to run smoothly (especially on mobile). Depending on the constraints of the platform and the type of game you are working on, it might be very important to avoid unnecessary heap allocations as much as possible. One very effective way to do this is to use memory pools. + +As an example let's look at at a case where we are dynamically creating a class: + +```csharp +public class Foo +{ + public class Factory : Factory + { + } +} + +public class Bar +{ + readonly Foo.Factory _fooFactory; + readonly List _foos = new List(); + + public Bar(Foo.Factory fooFactory) + { + _fooFactory = fooFactory; + } + + public void AddFoo() + { + _foos.Add(_fooFactory.Create()); + } + + public void RemoveFoo() + { + _foos.RemoveAt(0); + } +} + +public class TestInstaller : MonoInstaller +{ + public override void InstallBindings() + { + Container.Bind().AsSingle(); + Container.BindFactory(); + } +} +``` + +Here, every time we call Bar.AddFoo it will always allocate new heap memory. And every time we call Bar.RemoveFoo, the Bar class will stop referencing one of the instances of Foo, and therefore the memory for that instance will be marked for garbage collection. If this happens enough times, then eventually the garbage collector will kick in and you will get a (sometimes very noticeable) spike in your game. + +We can fix this spike by using memory pools instead: + +```csharp +public class Foo +{ + public class Pool : MemoryPool + { + } +} + +public class Bar +{ + readonly Foo.Pool _fooPool; + readonly List _foos = new List(); + + public Bar(Foo.Pool fooPool) + { + _fooPool = fooPool; + } + + public void AddFoo() + { + _foos.Add(_fooPool.Spawn()); + } + + public void RemoveFoo() + { + var foo = _foos[0]; + _fooPool.Despawn(foo); + _foos.Remove(foo); + } +} + +public class TestInstaller : MonoInstaller +{ + public override void InstallBindings() + { + Container.Bind().AsSingle(); + Container.BindMemoryPool(); + } +} +``` + +As you can see, this works very similarly to factories, except that the terminology is a bit different (Pool instead of Factory, Spawn instead of Create) and unlike factories, you have to return the instance to the pool rather than just stop referencing it. + +With this new implementation above, there will be some initial heap allocation with every call to AddFoo(), but if you call RemoveFoo() then AddFoo() in sequence this will re-use the previous instance and therefore save you a heap allocation. + +This is better, but we might still want to avoid the spikes from the initial heap allocations as well. One way to do this is to do all the heap allocations all at once as your game is starting up: + +```csharp +public class TestInstaller : MonoInstaller +{ + public override void InstallBindings() + { + Container.Bind().AsSingle(); + Container.BindMemoryPool().WithInitialSize(10); + } +} +``` + +When we use WithInitialSize like this in the Bind statement for our pool, 10 instances of Foo will be created immediately on startup to seed the pool. + +## Syntax + +The syntax for memory pools are almost identical to factories. The recommended convention is to use a public nested class named Pool (though this is just a convention). + +```csharp +public class Foo +{ + public class Pool : MemoryPool + { + } +} +``` + +Parameters are added by adding generic arguments: + +```csharp +public class Foo +{ + public class Pool : MemoryPool + { + } +} +``` + +The full format of the binding is the following: + +
+Container.BindMemoryPool<Param1Type, Param2Type, etc..., ObjectType, MemoryPoolType>()
+    .With(InitialSize|FixedSize)()
+    .ExpandBy(OneAtATime|Doubling)()
+    .To<ResultType>()
+    .WithId(Identifier)
+    .FromConstructionMethod()
+    .WithArguments(Arguments)
+    .When(Condition)
+    .CopyIntoAllSubContainers()
+    .NonLazy();
+
+ +Where: + +* **With** = Determines the number of instances that the pool is seeded with. When not specified, the pool starts with zero instances. The options are: + + * WithInitializeSize(x) - Create x instances immediately when the pool is created. The pool is also allowed to grow as necessary if it exceeds that amount + * WithFixedSize(x) - Create x instances immediately when the pool is created. If the pool size is exceeded then an exception is thrown. + +* **ExpandBy** = Determines the behaviour to invoke when the pool reaches its maximum size. Note that when specifying WithFixedSize, this option is not available. The options are: + + * ExpandByOneAtATime - Only allocate new instances one at a time as necessary + * ExpandByDoubling - When the pool is full and a new instance is requested, the pool will double in size before returning the requested instance. This approach can be useful if you prefer having large infrequent allocations to many small frequent allocations + +The rest of the bind methods behave the same as the normal bind methods documented here + +## Resetting + +One very important thing to be aware of when using memory pools instead of factories is that you must make sure to completely "refresh" the given instance. This is necessary otherwise you might have state a previous "life" of the instance bleeding in to the behaviour of the new instance. + +You can refresh the object by implementing any of the following methods in your memory pool derived class: + +```csharp +public class Foo +{ + public class Pool : MemoryPool + { + protected override void OnCreated(Foo item) + { + // Called immediately after the item is first added to the pool + } + + protected override void OnSpawned(Foo item) + { + // Called immediately after the item is removed from the pool + } + + protected override void OnDespawned(Foo item) + { + // Called immediately after the item is returned to the pool + } + + protected override void Reinitialize(Foo foo) + { + // Similar to OnSpawned + // Called immediately after the item is removed from the pool + // This method will also contain any parameters that are passed along + // to the memory pool from the spawning code + } + } +} +``` + +In most cases, you will probably only have to implement the Reinitialize method. For example, let's introduce some state to our first example by adding a Position value to Foo: + +```csharp +public class Foo +{ + Vector3 _position = Vector3.zero; + + public void Move(Vector3 delta) + { + _position += delta; + } + + public class Pool : MemoryPool + { + protected override void Reinitialize(Foo foo) + { + foo._position = Vector3.zero; + } + } +} +``` + +Note that our pool class is free to access private variables inside Foo because of the fact that it is a nested class. + +Or, if we wanted to avoid the duplication in Foo and Foo.Pool, we could do it this way: + +```csharp +public class Foo +{ + Vector3 _position; + + public Foo() + { + Reset(); + } + + public void Move(Vector3 delta) + { + _position += delta; + } + + void Reset() + { + _position = Vector3.zero; + } + + public class Pool : MemoryPool + { + protected override void Reinitialize(Foo foo) + { + foo.Reset(); + } + } +} +``` + +## Parameters + +Just like Factories, you can also pass runtime parameters when spawning new instances of your pooled classes. The difference is, instead of the parameters being injected into the class, they are passed to the Reinitialize method: + +```csharp +public class Foo +{ + Vector3 _position; + Vector3 _velocity; + + public Foo() + { + Reset(); + } + + public void Tick() + { + _position += _velocity * Time.deltaTime; + } + + void Reset() + { + _position = Vector3.zero; + _velocity = Vector3.zero; + } + + public class Pool : MemoryPool + { + protected override void Reinitialize(Foo foo, Vector3 velocity) + { + foo.Reset(); + foo._velocity = velocity; + } + } +} + +public class Bar +{ + readonly Foo.Pool _fooPool; + readonly List _foos = new List(); + + public Bar(Foo.Pool fooPool) + { + _fooPool = fooPool; + } + + public void AddFoo() + { + float maxSpeed = 10.0f; + float minSpeed = 1.0f; + + _foos.Add(_fooPool.Spawn( + Random.onUnitSphere * Random.Range(minSpeed, maxSpeed))); + } + + public void RemoveFoo() + { + var foo = _foos[0]; + _fooPool.Despawn(foo); + _foos.Remove(foo); + } +} +``` + +## Memory Pools for MonoBehaviours + +Memory pools for GameObjects works similarly. For example: + +```csharp +public class Foo : MonoBehaviour +{ + Vector3 _velocity; + + [Inject] + public void Construct() + { + Reset(); + } + + public void Update() + { + transform.position += _velocity * Time.deltaTime; + } + + void Reset() + { + transform.position = Vector3.zero; + _velocity = Vector3.zero; + } + + public class Pool : MonoMemoryPool + { + protected override void Reinitialize(Foo foo, Vector3 velocity) + { + foo.Reset(); + foo._velocity = velocity; + } + } +} + +public class Bar +{ + readonly Foo.Pool _fooPool; + readonly List _foos = new List(); + + public Bar(Foo.Pool fooPool) + { + _fooPool = fooPool; + } + + public void AddFoo() + { + float maxSpeed = 10.0f; + float minSpeed = 1.0f; + + _foos.Add(_fooPool.Spawn( + Random.onUnitSphere * Random.Range(minSpeed, maxSpeed))); + } + + public void RemoveFoo() + { + var foo = _foos[0]; + _fooPool.Despawn(foo); + _foos.Remove(foo); + } +} + +public class TestInstaller : MonoInstaller +{ + public GameObject FooPrefab; + + public override void InstallBindings() + { + Container.Bind().AsSingle(); + + Container.BindMemoryPool() + .WithInitialSize(2) + .FromComponentInNewPrefab(FooPrefab) + .UnderTransformGroup("Foos"); + } +} +``` + +The main difference here is that Foo.Pool now derives from MonoMemoryPool instead of MemoryPool. MonoMemoryPool is a helper class that will automatically enable and disable the game object for us when it is added/removed from the pool. The implementation for MonoMemoryPool is simply this: + +```csharp +public abstract class MonoMemoryPool : MemoryPool + where TValue : Component +{ + protected override void OnCreated(TValue item) + { + item.gameObject.SetActive(false); + } + + protected override void OnSpawned(TValue item) + { + item.gameObject.SetActive(true); + } + + protected override void OnDespawned(TValue item) + { + item.gameObject.SetActive(false); + } +} +``` + +Therefore, if you override one of these methods you will have to make sure to call the base version as well. + +Also, worth noting is the fact that for this logic to work, our MonoBehaviour must be at the root of the prefab, since otherwise only the transform associated with Foo and any children will be disabled. From 1736b90ea993a8271a41489d78e93e0e879f4705 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 12 Feb 2017 19:29:27 -0400 Subject: [PATCH 51/62] Added documentation for Lazy<> construct --- README.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ef9bc1175..382dcf70d 100644 --- a/README.md +++ b/README.md @@ -1834,7 +1834,66 @@ See here. ## Just-In-Time Resolving Using Lazy<> -TBD +In some cases it can be useful to delay the creation of certain dependencies until after startup. You can use the `Lazy<>` construct for this. + +For example, let's imagine a scenario like this: + +```csharp +public class Foo +{ + public void Run() + { + ... + } +} + +public class Bar +{ + Foo _foo; + + public Bar(Foo foo) + { + _foo = foo; + } + + public void Run() + { + _foo.Run(); + } +} + +public class TestInstaller : MonoInstaller +{ + public override void InstallBindings() + { + Container.Bind().AsSingle(); + Container.Bind().AsSingle(); + } +} +``` + +Let's also imagine that we would only like to create an instance of Foo if it's actually used (that is, when the Bar.Run method is called). As it stands above, Foo would always be created every time that Bar is created, even if Bar.Run is never called. We can fix this by changing Bar to the following: + +```csharp +public class Bar +{ + Lazy _foo; + + public Bar(Lazy foo) + { + _foo = foo; + } + + public void DoThing() + { + _foo.Value.DoThing(); + } +} +``` + +Now, by using `Lazy<>` instead, the Foo class will not be created until Bar.DoThing is first called. After that, it will use the same instance of Foo. + +Note that the installers remain the same in both cases. Any injected dependency can be made lazy by simply wrapping it in `Lazy<>`. ## DiContainer Methods From b6b9f1149f32eb61f3c17fba74d7e6a34a7ab9c9 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 12 Feb 2017 19:54:56 -0400 Subject: [PATCH 52/62] Added documentation for abstract memory pools --- Documentation/MemoryPools.md | 66 +++++++++++++++++++ .../ProjectSettings/ProjectSettings.asset | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Documentation/MemoryPools.md b/Documentation/MemoryPools.md index 64706eea1..15bba50f1 100644 --- a/Documentation/MemoryPools.md +++ b/Documentation/MemoryPools.md @@ -428,3 +428,69 @@ Therefore, if you override one of these methods you will have to make sure to ca Also, worth noting is the fact that for this logic to work, our MonoBehaviour must be at the root of the prefab, since otherwise only the transform associated with Foo and any children will be disabled. +## Abstract Memory Pools + +Just like abstract factories, sometimes you might want to create a memory pool that returns an interface, with the concrete type decided inside an installer. This works very similarly to abstract factories. For example: + +```csharp +public interface IFoo +{ +} + +public class Foo1 : IFoo +{ +} + +public class Foo2 : IFoo +{ +} + +public class FooPool : MemoryPool +{ +} + +public class Bar +{ + readonly FooPool _fooPool; + readonly List _foos = new List(); + + public Bar(FooPool fooPool) + { + _fooPool = fooPool; + } + + public void AddFoo() + { + _foos.Add(_fooPool.Spawn()); + } + + public void RemoveFoo() + { + var foo = _foos[0]; + _fooPool.Despawn(foo); + _foos.Remove(foo); + } +} + +public class TestInstaller : MonoInstaller +{ + public bool Use1; + + public override void InstallBindings() + { + Container.Bind().AsSingle(); + + if (Use1) + { + Container.BindMemoryPool().WithInitialSize(10).To(); + } + else + { + Container.BindMemoryPool().WithInitialSize(10).To(); + } + } +} +``` + +We might also want to add a Reset() method to the IFoo interface as well here, and call that on Reinitialize() + diff --git a/UnityProject/ProjectSettings/ProjectSettings.asset b/UnityProject/ProjectSettings/ProjectSettings.asset index 4b59f04a9..d60ee1839 100644 --- a/UnityProject/ProjectSettings/ProjectSettings.asset +++ b/UnityProject/ProjectSettings/ProjectSettings.asset @@ -446,7 +446,7 @@ PlayerSettings: webGLUseWasm: 0 webGLCompressionFormat: 1 scriptingDefineSymbols: - 13: ZEN_SIGNALS_ADD_UNIRX + 13: platformArchitecture: iOS: 2 scriptingBackend: From afa5f7a34e59c806d6098fb5bd5d8eb702610b6f Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 12 Feb 2017 20:06:07 -0400 Subject: [PATCH 53/62] Re-ordered the parameter list in MemoryPool.Reinitialize to be consistent with the generic args. Fixed minor bug with validating memory pools --- .../Decorators/Editor/TestSceneDecorators.cs | 2 +- .../Scripts/Enemy/EnemyFacade.cs | 2 +- .../Scripts/Installers/GameInstaller.cs | 1 + .../Scripts/Misc/Bullet.cs | 2 +- .../Factories/Bindings/TestMemoryPool1.cs | 22 ++++++++++++++++--- .../Source/Factories/Pooling/MemoryPool.cs | 20 ++++++++--------- .../Factories/Pooling/MemoryPoolBase.cs | 7 ++++-- 7 files changed, 38 insertions(+), 18 deletions(-) diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs index 5860e5c08..d207ce8e1 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators/Editor/TestSceneDecorators.cs @@ -14,7 +14,7 @@ namespace Zenject.Tests.SceneDecorators [TestFixture] public class TestSceneDecorators { - const string CommonFolderPath = "Assets/Mtm.Zenject-IntegrationTests/SceneLoading/Decorators"; + const string CommonFolderPath = "Assets/Zenject/OptionalExtras/IntegrationTests/SceneLoading/Decorators"; const string DecoratorScenePath = CommonFolderPath + "/DecoratorScene.unity"; const string MainScenePath = CommonFolderPath + "/MainScene.unity"; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs index a89e42b1d..004e542f8 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/EnemyFacade.cs @@ -43,7 +43,7 @@ public void Die() public class Pool : MonoMemoryPool { - protected override void Reinitialize(EnemyFacade enemy, EnemyTunables tunables) + protected override void Reinitialize(EnemyTunables tunables, EnemyFacade enemy) { enemy._tunables.Accuracy = tunables.Accuracy; enemy._tunables.Speed = tunables.Speed; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs index 005d50b1f..d086ce400 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Installers/GameInstaller.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using UnityEngine; using Zenject; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs index 6305fd186..78872447c 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Misc/Bullet.cs @@ -75,7 +75,7 @@ public void Despawn() public class Pool : MonoMemoryPool { - protected override void Reinitialize(Bullet bullet, float speed, float lifeTime, BulletTypes type) + protected override void Reinitialize(float speed, float lifeTime, BulletTypes type, Bullet bullet) { bullet._type = type; bullet._speed = speed; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs index b98ede78f..7844f336b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Factories/Bindings/TestMemoryPool1.cs @@ -7,13 +7,15 @@ namespace Zenject.Tests.Bindings { [TestFixture] - public class TestMemoryPool1 : ZenjectUnitTestFixture + public class TestMemoryPool1 : ZenjectIntegrationTestFixture { [Test] public void TestFactoryProperties() { Container.BindMemoryPool(); + Initialize(); + var pool = Container.Resolve(); Assert.IsEqual(pool.NumActive, 0); @@ -98,7 +100,7 @@ public int ResetCount public class Pool : MemoryPool { - protected override void Reinitialize(Foo foo, string value) + protected override void Reinitialize(string value, Foo foo) { foo.Value = value; foo.ResetCount++; @@ -106,10 +108,16 @@ protected override void Reinitialize(Foo foo, string value) } } + [Test] + public void TestAbstractMemoryPoolValidate() + { + TestAbstractMemoryPoolInternal(); + } + [Test] public void TestAbstractMemoryPool() { - Container.BindMemoryPool().To(); + TestAbstractMemoryPoolInternal(); var pool = Container.Resolve(); @@ -118,6 +126,14 @@ public void TestAbstractMemoryPool() Assert.IsEqual(foo.GetType(), typeof(Bar)); } + void TestAbstractMemoryPoolInternal() + { + Container.BindMemoryPool() + .WithInitialSize(3).To().NonLazy(); + + Initialize(); + } + public interface IBar { } diff --git a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs index ac4fe29f4..42a364a04 100644 --- a/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs +++ b/UnityProject/Assets/Zenject/Source/Factories/Pooling/MemoryPool.cs @@ -27,11 +27,11 @@ public abstract class MemoryPool public TValue Spawn(TParam1 param) { var item = GetInternal(); - Reinitialize(item, param); + Reinitialize(param, item); return item; } - protected virtual void Reinitialize(TValue item, TParam1 p1) + protected virtual void Reinitialize(TParam1 p1, TValue item) { // Optional } @@ -44,11 +44,11 @@ public abstract class MemoryPool public TValue Spawn(TParam1 param1, TParam2 param2) { var item = GetInternal(); - Reinitialize(item, param1, param2); + Reinitialize(param1, param2, item); return item; } - protected abstract void Reinitialize(TValue item, TParam1 p1, TParam2 p2); + protected abstract void Reinitialize(TParam1 p1, TParam2 p2, TValue item); } // Three parameters @@ -58,11 +58,11 @@ public abstract class MemoryPool public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3) { var item = GetInternal(); - Reinitialize(item, param1, param2, param3); + Reinitialize(param1, param2, param3, item); return item; } - protected abstract void Reinitialize(TValue item, TParam1 p1, TParam2 p2, TParam3 p3); + protected abstract void Reinitialize(TParam1 p1, TParam2 p2, TParam3 p3, TValue item); } // Four parameters @@ -72,11 +72,11 @@ public abstract class MemoryPool public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) { var item = GetInternal(); - Reinitialize(item, param1, param2, param3, param4); + Reinitialize(param1, param2, param3, param4, item); return item; } - protected abstract void Reinitialize(TValue item, TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4); + protected abstract void Reinitialize(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TValue item); } // Five parameters @@ -86,10 +86,10 @@ public abstract class MemoryPool(initialSize); - for (int i = 0; i < initialSize; i++) + if (!container.IsValidating) { - _inactiveItems.Push(AllocNew()); + for (int i = 0; i < initialSize; i++) + { + _inactiveItems.Push(AllocNew()); + } } } From 5ffe99387c287a7705251bbf0d0ed082f4fbdd56 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Sun, 12 Feb 2017 20:21:24 -0400 Subject: [PATCH 54/62] Added a few games to the games list --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 382dcf70d..c44f29a42 100644 --- a/README.md +++ b/README.md @@ -2577,10 +2577,6 @@ Something else to note is that the rate at which the ITickable.Tick method gets Yet another option is to use a coroutine library that implements similar functionality to what Unity provides. See [here](https://github.com/svermeulen/UnityCoroutinesWithoutMonoBehaviours) for one example that we've used in the past at Modest Tree -* **How do I use Zenject with pools to minimize memory allocations?** - - Currently, Zenject does not support memory pooling. When you bind something to transient or use a factory, Zenject will always create a brand new instance from scratch. We realize that this can be inefficient in cases where you are creating many objects (especially on mobile) so it is something we want to address in future versions. - * **What games/tools/libraries are using Zenject?** If you know of other projects that are using Zenject, please add a comment [here](https://github.com/modesttree/Zenject/issues/153) so that I can add it to this list. @@ -2595,6 +2591,8 @@ Something else to note is that the rate at which the ITickable.Tick method gets * [Farm Away!](http://www.farmawaygame.com/) (iOS and Android) * [Build Away!](http://www.buildawaygame.com/) (iOS and Android) * Stick Soccer 2 ([iOS](https://itunes.apple.com/gb/app/stick-soccer-2/id1104214157?mt=8) and [Android](https://play.google.com/store/apps/details?id=com.sticksports.soccer2&hl=en_GB)) + * [Untethered](https://play.google.com/store/apps/details?id=com.numinousgames.Untethered&hl=en) (Google VR) + * [Toy Clash](https://toyclash.com/) - ([GearVR](https://www.oculus.com/experiences/gear-vr/1407846952568081/)) Libraries From 9d6297bf64879b2c82d0bb349d8e0c3e782e921e Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 13 Feb 2017 00:01:34 -0400 Subject: [PATCH 55/62] Tweaks to readme --- Documentation/CheatSheet.md | 4 +- Documentation/Factories.md | 10 +- Documentation/SubContainers.md | 22 +-- README.md | 282 +++++++++++++++++++-------------- 4 files changed, 178 insertions(+), 140 deletions(-) diff --git a/Documentation/CheatSheet.md b/Documentation/CheatSheet.md index d2fcf69b3..2ef2e215a 100644 --- a/Documentation/CheatSheet.md +++ b/Documentation/CheatSheet.md @@ -40,10 +40,10 @@ Container.Bind().To().AsSingle(); Container.Bind(typeof(Foo)).AsSingle(); Container.Bind(typeof(IFoo)).AsSingle(typeof(Foo)); -///////////// BindAllInterfaces +///////////// BindInterfaces // Bind all interfaces that Foo implements to a new singleton of type Foo -Container.BindAllInterfaces().To().AsSingle(); +Container.BindInterfacesTo().AsSingle(); // So for example if Foo implements ITickable and IInitializable then the above // line is equivalent to this: diff --git a/Documentation/Factories.md b/Documentation/Factories.md index a0d64b625..fb39753d1 100644 --- a/Documentation/Factories.md +++ b/Documentation/Factories.md @@ -115,7 +115,7 @@ public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.Bind().AsSingle(); Container.BindFactory(); } @@ -165,7 +165,7 @@ public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.Bind().AsSingle(); Container.BindFactory(); } @@ -207,7 +207,7 @@ public class TestInstaller : MonoInstaller public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.Bind().AsSingle(); Container.BindFactory().FromPrefab(EnemyPrefab); } @@ -275,7 +275,7 @@ public class GameInstaller : MonoInstaller public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); if (UseAStar) { @@ -369,7 +369,7 @@ public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.Bind().AsSingle(); Container.BindFactory().FromFactory(); } diff --git a/Documentation/SubContainers.md b/Documentation/SubContainers.md index c8a8bf68a..ee38e49db 100644 --- a/Documentation/SubContainers.md +++ b/Documentation/SubContainers.md @@ -48,7 +48,7 @@ public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.Bind().FromSubContainerResolve().ByMethod(InstallGreeter).AsSingle(); } @@ -106,8 +106,8 @@ public class TestInstaller : MonoInstaller { subContainer.Bind().AsSingle(); - subContainer.BindAllInterfaces().To().AsSingle(); - subContainer.BindAllInterfaces().To().AsSingle(); + subContainer.BindInterfacesTo().AsSingle(); + subContainer.BindInterfacesTo().AsSingle(); } } ``` @@ -143,16 +143,16 @@ public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfacesAndSelf() - .To().FromSubContainerResolve().ByMethod(InstallGreeter).AsSingle().NonLazy(); + Container.BindInterfacesAndSelfTo() + .FromSubContainerResolve().ByMethod(InstallGreeter).AsSingle().NonLazy(); } void InstallGreeter(DiContainer subContainer) { subContainer.Bind().AsSingle(); - subContainer.BindAllInterfaces().To().AsSingle(); - subContainer.BindAllInterfaces().To().AsSingle(); + subContainer.BindInterfacesTo().AsSingle(); + subContainer.BindInterfacesTo().AsSingle(); } } @@ -160,7 +160,7 @@ public class TestInstaller : MonoInstaller Now if we run it, we should see the Hello message, then if we stop playing we should see the Goodbye message. -The reason this works is because we are now binding IInitializable, IDisposable, and ITickable on the root container to the Greeter class given by `Container.BindAllInterfacesAndSelf().To()`. Greeter now inherits from Kernel, which inherits from all these interfaces and also handles forwarding these calls to the IInitializable's / ITickable's / IDisposable's in our sub container. Note that we use AsSingle() here, which is important otherwise it will create a new sub-container for every interface which is not what we want. +The reason this works is because we are now binding IInitializable, IDisposable, and ITickable on the root container to the Greeter class given by `Container.BindInterfacesAndSelfTo()`. Greeter now inherits from Kernel, which inherits from all these interfaces and also handles forwarding these calls to the IInitializable's / ITickable's / IDisposable's in our sub container. Note that we use AsSingle() here, which is important otherwise it will create a new sub-container for every interface which is not what we want. ## Creating Sub-Containers on GameObject's by using Game Object Context @@ -220,7 +220,7 @@ public class GameInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); } } ``` @@ -338,7 +338,7 @@ public class GameInstaller : MonoInstaller public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.BindFactory().FromSubContainerResolve().ByPrefab(ShipPrefab); } @@ -387,7 +387,7 @@ public class GameInstaller : MonoInstaller public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); Container.BindFactory().FromSubContainerResolve().ByPrefab(ShipPrefab); } diff --git a/README.md b/README.md index c44f29a42..ad7a879ba 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,8 @@ The tests may also be helpful to show usage for each specific feature (which you * ITickable * IInitializable * IDisposable - * Using the Unity Inspector To Configure Settings + * BindInterfacesTo and BindInterfacesAndSelfTo + * Using the Unity Inspector To Configure Settings * Object Graph Validation * Scene Bindings * General Guidelines / Recommendations / Gotchas / Tips and Tricks @@ -118,7 +119,6 @@ The tests may also be helpful to show usage for each specific feature (which you * List Bindings * Global Bindings Using Project Context * Identifiers - * Decorator Bind * Non Generic bindings * Convention Based Binding * Singleton Identifiers @@ -387,11 +387,11 @@ Using [Inject] methods to inject dependencies is the recommended approach for Mo **Recommendations** -* Best practice is to prefer constructor injection or method injection to field or property injection. - * Constructor injection forces the dependency to only be resolved once, at class creation, which is usually what you want. In most cases you don't want to expose a public property for your initial dependencies because this suggests that it's open to changing. - * Constructor injection guarantees no circular dependencies between classes, which is generally a bad thing to do. You can do this however using method injection or field injection if necessary. - * Constructor/Method injection is more portable for cases where you decide to re-use the code without a DI framework such as Zenject. You can do the same with public properties but it's more error prone (it's easier to forget to initialize one field and leave the object in an invalid state) - * Finally, Constructor/Method injection makes it clear what all the dependencies of a class are when another programmer is reading the code. They can simply look at the parameter list of the method. This is also good because it will be more obvious when a class has too many dependencies and should therefore be split up (since it's constructor parameter list will start to seem long) +Best practice is to prefer constructor injection or method injection to field or property injection. +* Constructor injection forces the dependency to only be resolved once, at class creation, which is usually what you want. In most cases you don't want to expose a public property for your initial dependencies because this suggests that it's open to changing. +* Constructor injection guarantees no circular dependencies between classes, which is generally a bad thing to do. You can do this however using method injection or field injection if necessary. +* Constructor/Method injection is more portable for cases where you decide to re-use the code without a DI framework such as Zenject. You can do the same with public properties but it's more error prone (it's easier to forget to initialize one field and leave the object in an invalid state) +* Finally, Constructor/Method injection makes it clear what all the dependencies of a class are when another programmer is reading the code. They can simply look at the parameter list of the method. This is also good because it will be more obvious when a class has too many dependencies and should therefore be split up (since it's constructor parameter list will start to seem long) ## Binding @@ -542,6 +542,9 @@ Where: // This is also what you would typically use for primitive types Container.BindInstance(5.13f); Container.BindInstance("foo"); + + // Or, if you have many instances, you can use BindInstances + Container.BindInstances(5.13f, "foo", new Foo()); ``` 1. **FromMethod** - Create via a custom method @@ -573,7 +576,7 @@ Where: } ``` -1. **FromFactory** - Create instance using a custom factory class. This construction method is similar to `FromMethod` except can be cleaner in cases where the logic is more complicated or requires dependencies (the factory itself can have dependencies injected) +1. **FromFactory** - Create instance using a custom factory class. This construction method is similar to `FromMethod` except can be cleaner in cases where the logic is more complicated or requires dependencies (since the factory itself can have dependencies injected) ```csharp class FooFactory : IFactory @@ -596,7 +599,7 @@ Where: **ResultType** must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case -1. **FromComponentInNewPrefabResource** - Instantiate the given prefab at the given resource path as a new game object, inject any MonoBehaviour's on it, and then search the result for type **ResultType**. +1. **FromComponentInNewPrefabResource** - Instantiate the given prefab (found at the given resource path) as a new game object, inject any MonoBehaviour's on it, and then search the result for type **ResultType**. ```csharp Container.Bind().FromComponentInNewPrefabResource("Some/Path/Foo"); @@ -612,7 +615,7 @@ Where: **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case -1. **FromNewComponentOn** - Add a new component of the given type on the given game object then inject on it. +1. **FromNewComponentOn** - Instantiate a new component of the given type on the given game object ```csharp Container.Bind().FromComponent(someGameObject); @@ -620,7 +623,7 @@ Where: **ResultType** must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case -1. **FromNewComponentSibling** - Add a new component on the current transform and inject on it. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type. +1. **FromNewComponentSibling** - Instantiate a new component of the given on the current transform. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type. ```csharp Container.Bind().FromNewComponentSibling(); @@ -788,8 +791,8 @@ public class FooInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces().To().AsSingle(); Container.Bind().AsSingle(); + Container.BindInterfacesTo().AsSingle(); // etc... } } @@ -839,7 +842,7 @@ When calling installers from other installers it is common to want to pass param ## ITickable -In many cases it is preferable to avoid the extra weight of MonoBehaviours in favour of just normal C# classes. Zenject allows you to do this much more easily by providing interfaces that mirror functionality that you would normally need to use a MonoBehaviour for. +In some cases it is preferable to avoid the extra weight of MonoBehaviours in favour of just normal C# classes. Zenject allows you to do this much more easily by providing interfaces that mirror functionality that you would normally need to use a MonoBehaviour for. For example, if you have code that needs to run per frame, then you can implement the `ITickable` interface: @@ -853,19 +856,15 @@ public class Ship : ITickable } ``` -Then it's just a matter of including the following in one of your installers: +Then, to hook it up in an installer: ```csharp Container.Bind().To().AsSingle(); ``` -Or if you don't want to have to remember which interfaces Ship implements: - -```csharp -Container.BindAllInterfaces().To().AsSingle(); -``` +Or if you don't want to have to always remember which interfaces your class implements, you can use the shortcut described here -Note that the order that Tick() is called on all ITickables is also configurable, as outlined here. +Note that the order that the Tick() is called in for all ITickables is also configurable, as outlined here. Also note that there are interfaces `ILateTickable` and `IFixedTickable` which work similarly for the other unity update methods. @@ -873,9 +872,19 @@ Also note that there are interfaces `ILateTickable` and `IFixedTickable` which w If you have some initialization that needs to occur on a given object, you could include this code in the constructor. However, this means that the initialization logic would occur in the middle of the object graph being constructed, so it may not be ideal. -One alternative is to implement `IInitializable`, and then perform initialization logic in an `Initialize()` method. This Initialize method would then be called after the entire object graph is constructed and all constructors have been called. +A better alternative is to implement `IInitializable`, and then perform initialization logic in an `Initialize()` method. + +Then, to hook it up in an installer: + +```csharp +Container.Bind().To().AsSingle(); +``` -Note that the constructors for the initial object graph are called during Unity's Awake event, and that the `IInitializable.Initialize` methods are called immediately on Unity's Start event. Using `IInitializable` as opposed to a constructor is therefore more in line with Unity's own recommendations, which suggest that the Awake phase be used to set up object references, and the Start phase should be used for more involved initialization logic. +Or if you don't want to have to always remember which interfaces your class implements, you can use the shortcut described here + +The Foo.Initialize method would then be called after the entire object graph is constructed and all constructors have been called. + +Note that the constructors for the initial object graph are called during Unity's Awake event, and that the `IInitializable.Initialize` methods are called immediately on Unity's Start event. Using `IInitializable` as opposed to a constructor is therefore more in line with Unity's own recommendations, which suggest that the Awake phase be used to set up object references, and the Start phase be used for more involved initialization logic. This can also be better than using constructors or `[Inject]` methods because the initialization order is customizable in a similar way to `ITickable`, as explained here. @@ -909,7 +918,7 @@ public class Foo ## IDisposable -If you have external resources that you want to clean up when the app closes, the scene changes, or for whatever reason the context object is destroyed, you can simply declare your class as `IDisposable` like below: +If you have external resources that you want to clean up when the app closes, the scene changes, or for whatever reason the context object is destroyed, you can declare your class as `IDisposable` like below: ```csharp public class Logger : IInitializable, IDisposable @@ -941,47 +950,124 @@ Container.Bind().To().AsSingle(); Container.Bind().To().AsSingle(); ``` -Or you can use the following shortcut: +Or you can use the BindInterfaces shortcut: ```csharp -Container.BindAllInterfacesAndSelf().To().AsSingle(); +Container.BindInterfacesAndSelfTo().AsSingle(); ``` This works because when the scene changes or your unity application is closed, the unity event OnDestroy() is called on all MonoBehaviours, including the SceneContext class, which then triggers Dispose() on all objects that are bound to `IDisposable` -Note that this example may or may not be a good idea (for example, the file will be left open if your app crashes), but illustrates the point :) +## BindInterfacesTo and BindInterfacesAndSelfTo + +If you end up using the ITickable, IInitializable, and IDisposable interfaces as described above, you will often end up with code like this: + +```csharp +Container.Bind().AsSingle(); +Container.Bind().To().AsSingle(); +Container.Bind().To().AsSingle(); +``` + +You can simplify this a bit by using the non generic bind method: + +```csharp +Container.Bind(typeof(Foo), typeof(IInitializable), typeof(IDisposable)).To().AsSingle(); +``` + +This is better but it could still be more readable. Also, this is still not ideal because if I later on decide that Foo doesn't need a Tick() or a Dispose() then I have to keep the installer in sync. + +A better idea would be to just always use the interfaces like this: + +```csharp +Container.Bind(new[] { typeof(Foo) }.Concat(typeof(Foo).GetInterfaces())).To().AsSingle(); +``` + +This pattern is useful enough that Zenject includes a custom bind method for it. The above code is equivalent to: + +```csharp +Container.BindInterfacesAndSelfTo().AsSingle(); +``` + +Now, we can add and remove interfaces to/from Foo and the installer remains the same. + +In some cases you might *only* want to bind the interfaces, and keep Foo hidden from other classes. In that case you would use the BindInterfacesTo method instead: + +```csharp +Container.BindInterfacesTo().AsSingle() +``` + +Which, in this case, would expand to: + +```csharp +Container.Bind(typeof(IInitializable), typeof(IDisposable)).To().AsSingle(); +``` + +Or, equivalently: + +```csharp +Container.Bind().To().AsSingle(); +Container.Bind().To().AsSingle(); +``` ## Using the Unity Inspector To Configure Settings -One implication of writing most of your code as normal C# classes instead of MonoBehaviour's is that you lose the ability to configure data on them using the inspector. You can however still take advantage of this in Zenject by using the following pattern, as seen in the sample project: +One implication of writing most of your code as normal C# classes instead of MonoBehaviour's is that you lose the ability to configure data on them using the inspector. You can however still take advantage of this in Zenject by using the following pattern: ```csharp -public class AsteroidsInstaller : MonoInstaller +public class Foo : ITickable { - public Settings SceneSettings; + readonly Settings _settings; - public override void InstallBindings() + public Foo(Settings settings) { - ... - Container.BindInstance(SceneSettings.StateMoving); - ... + _settings = settings; + } + + public void Tick() + { + Debug.Log("Speed: " + _settings.Speed); } [Serializable] public class Settings { - ... - public ShipStateMoving.Settings StateMoving; - ... + public float Speed; } } ``` -Note that if you follow this method, you will have to make sure to always include the [Serializable] attribute on your settings wrappers, otherwise they won't show up in the Unity inspector. +Then, in an installer: -To see this in action, start the asteroids scene and try adjusting `Ship -> State Moving -> Move Speed` setting and watch live as your ship changes speed. +```csharp +public class TestInstaller : MonoInstaller +{ + public Foo.Settings FooSettings; -Another way to do this is to use ScriptableObjectInstaller to store settings, which have the added advantage that you can change your settings at runtime and have those changes automatically persist when play mode is stopped. See here for details. + public override void InstallBindings() + { + Container.BindInstance(FooSettings); + Container.BindInterfacesTo().AsSingle(); + } +} +``` + +Or, equivalently: + +```csharp +public class TestInstaller : MonoInstaller +{ + public Foo.Settings FooSettings; + + public override void InstallBindings() + { + Container.BindInterfacesTo().AsSingle().WithArguments(FooSettings); + } +} +``` + +Now, if we run our scene we can change the speed value to tune the Foo class in real time. + +Another (arguably better) way to do this is to use ScriptableObjectInstaller instead of MonoInstaller, which have the added advantage that you can change your settings at runtime and have those changes automatically persist when play mode is stopped. See here for details. ## Object Graph Validation @@ -1065,30 +1151,30 @@ The `ZenjectBinding` component has the following properties: Container.Bind().FromInstance(_foo); ``` - Which is also the same as this: + Or, equivalently: ```csharp Container.BindInstance(_foo); ``` - So if we duplicate this game object to have multiple game objects with `Foo` on them (and its `ZenjectBinding`), they will all be bound to the Container this way. So after doing this, we would have to change `GameRunner` above to take a `List` otherwise we would get Zenject exceptions (see here for info on list bindings). + So if we duplicate this game object to have multiple game objects with `Foo` on them (as well as the `ZenjectBinding`), they will all be bound to the Container this way. So after doing this, we would have to change `GameRunner` above to take a `List` otherwise we would get Zenject exceptions (see here for info on list bindings). 2. `AllInterfaces` This bind type is equivalent to the following: ```csharp - Container.BindAllInterfaces(_foo.GetType()).FromInstance(_foo); + Container.BindInterfacesTo(_foo.GetType()).FromInstance(_foo); ``` - Note however, in this case, that `GameRunner` must ask for type `IFoo` in its constructor. If we left `GameRunner` asking for type `Foo` then Zenject would throw exceptions, since the `BindAllInterfaces` method only binds the interfaces, not the concrete type. If you want the concrete type as well then you can use: + Note however, in this case, that `GameRunner` must ask for type `IFoo` in its constructor. If we left `GameRunner` asking for type `Foo` then Zenject would throw exceptions, since the `BindInterfaces` method only binds the interfaces, not the concrete type. If you want the concrete type as well then you can use: 3. `AllInterfacesAndSelf` This bind type is equivalent to the following: ```csharp - Container.BindAllInterfacesAndSelf(_foo.GetType()).FromInstance(_foo); + Container.BindInterfacesAndSelfTo(_foo.GetType()).FromInstance(_foo); ``` This is the same as AllInterfaces except we can directly access Foo using type Foo instead of needing an interface. @@ -1107,12 +1193,12 @@ The `ZenjectBinding` component has the following properties: Container.BindInstance(_foo).WithId("Foo1"); ``` -* Context - This is completely optional and in most cases should be left unset. This will determine which Context to apply the binding to. If left unset, it will use whatever context the GameObject is in. In most cases this will be SceneContext, but if it's inside a GameObjectContext it will be bound into that container instead. One important use case for this field is to allow dragging the SceneContext into this field, for cases where the component is inside a GameObjectContext. This allows you to treat this MonoBehaviour as a Facade for the entire sub-container given by the GameObjectContext. +* Context - This is completely optional and in most cases should be left unset. This will determine which Context to apply the binding to. If left unset, it will use whatever context the GameObject is in. In most cases this will be SceneContext, but if it's inside a GameObjectContext it will be bound into the GameObjectContext container instead. One important use case for this field is to allow dragging the SceneContext into this field, for cases where the component is inside a GameObjectContext. This allows you to treat this MonoBehaviour as a Facade for the entire sub-container given by the GameObjectContext. ## General Guidelines / Recommendations / Gotchas / Tips and Tricks * **Do not use GameObject.Instantiate if you want your objects to have their dependencies injected** - * If you want to instantiate a prefab at runtime and have any MonoBehaviour's automatically injected, we recommend using a factory. You can also instantiate a prefab by directly using the DiContainer by calling any of the `InstantiatePrefab` methods. Using these ways as opposed to GameObject.Instantiate will ensure any fields that are marked with the [Inject] attribute are filled in properly, and all [Inject] methods within the prefab are called. + * If you want to instantiate a prefab at runtime and have any MonoBehaviour's automatically injected, we recommend using a factory. You can also instantiate a prefab by directly using the DiContainer by calling any of the InstantiatePrefab methods. Using these ways as opposed to GameObject.Instantiate will ensure any fields that are marked with the [Inject] attribute are filled in properly, and all [Inject] methods within the prefab are called. * **Best practice with DI is to *only* reference the container in the composition root "layer"** * Note that factories are part of this layer and the container can be referenced there (which is necessary to create objects at runtime). For example, see ShipStateFactory in the sample project. See here for more details on this. @@ -1140,7 +1226,7 @@ The `ZenjectBinding` component has the following properties: * **Transient is the default scope** * Another common mistake is to leave out the call which defines the scope (eg. `AsSingle`, `AsTransient`, or `AsCached`) and therefore unintentionally use the default (`AsTransient`). For example: - ``` Container.BindAllInterfacesAndSelf().To(); ``` + ```Container.BindInterfacesAndSelfTo();``` * The above binding is almost certainly not what you want to do, because it will create an instance of Foo for every interface that Foo has. Instead, you almost certainly want to use either `AsCached` or `AsSingle` in this case @@ -1148,13 +1234,13 @@ Please feel free to submit any other sources of confusion to sfvermeulen@gmail.c ## Game Object Bind Methods -For bindings that create new game objects (eg. FromComponentInNewPrefab or FromGameObject) there are also two extra bind methods +For bindings that create new game objects (eg. FromComponentInNewPrefab or FromGameObject) there are also two extra bind methods. * **WithGameObjectName** = The name to give the new Game Object associated with this binding. ```csharp Container.Bind().FromComponentInNewPrefabResource("Some/Path/Foo").WithGameObjectName("Foo1"); - Container.Bind().FromGameObject().WithGameObjectName("Foo2"); + Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName("Foo1"); ``` * **UnderTransformGroup(string)** = The name of the transform group to place the new game object under. This is especially useful for factories, which can be used to create many copies of a prefab, so it can be nice to have them automatically grouped together within the scene heirarchy. @@ -1290,20 +1376,7 @@ public class Bar } ``` -Also worth noting is that if you try and declare a single dependency of IFoo (like Bar below) and there are multiple bindings for it, then Zenject will throw an exception, since Zenject doesn't know which instance of IFoo to use. - -```csharp -public class Bar -{ - public Bar(IFoo foo) - { - } -} -``` - -Also, if the empty list is valid, then you should mark your List constructor parameter (or [Inject] field) as optional (see here for details). - -The order of the list will be the same as the order in which they were added with a Bind method. The list will also be sorted by subcontainer, with the first set of instances taken from the bottom most subcontainer, and then the parent, then the grandparent, etc. +The order of the list will be the same as the order in which they were added with a Bind method. The only exception is when you use subcontainers, since in that case the list will be ordered first by the associated subcontainer, with the first set of instances taken from the bottom most subcontainer, and then the parent, then the grandparent, etc. ## Global Bindings Using Project Context @@ -1319,7 +1392,7 @@ Note also that this only occurs once. If you load another scene from the first The reason that all the bindings you add to a global installer are available for any classes within each individual scene, is because the Container in each scene uses the ProjectContext Container as it's "parent". For more information on nested containers see here. -ProjectContext is a very convenient place to put objects that you want to persist across scenes. However, the fact that it's completely global to every scene can lead to some unintended behaviour. For example, this means that even if you write a simple test scene that uses Zenject, it will load the ProjectContext, which may not be what you want. To address these problems it is sometimes better to use Scene Parenting instead, since that approach allows you to be selective in terms of which scenes inherit the same common bindings. See here for more details on that approach. +ProjectContext is a very convenient place to put objects that you want to persist across scenes. However, the fact that it's completely global to every scene can lead to some unintended behaviour. For example, this means that even if you write a simple test scene that uses Zenject, it will load the ProjectContext, which may not be what you want. To address these problems it is often better to use Scene Parenting instead, since that approach allows you to be selective in terms of which scenes inherit the same common bindings. See here for more details on that approach. ## Identifiers @@ -1401,9 +1474,7 @@ public class GameSettings : ScriptableObjectInstaller public override void InstallBindings() { - Container.BindInstance(Player); - Container.BindInstance(SomethingElse); - // ... etc. + Container.BindInstances(Player, SomethingElse, etc.); } } @@ -1492,49 +1563,17 @@ public class MainInstaller : MonoInstaller { // For this to work, there must be a prefab with FooInstaller attached to it at // Resources/My/Custom/ResourcePath.prefab - FooInstaller.InstallFromResource("My/Custom/ResourcePath", Container, "asdf"); + FooInstaller.InstallFromResource("My/Custom/ResourcePath", Container, new object[] { "asdf" }); - // In this case the prefab will be assumed to exist at 'Resources/Installers/FooInstaller' - // FooInstaller.InstallFromResource(Container, "asdf"); + // If a resource path is not provided then it is assumed to exist at resource path + // 'Resources/Installers/FooInstaller' + // For example: + // FooInstaller.InstallFromResource(Container, new object[] { "asdf" }); } } ``` -Or, by using a ScriptableObjectInstaller: - -```csharp -public class FooInstaller : ScriptableObjectInstaller -{ - string _value; - - // Note that in this case we can't use a constructor - [Inject] - public void Construct(string value) - { - _value = value; - } - - public override void InstallBindings() - { - ... - - Container.BindInstance(_value).WhenInjectedInto(); - } -} - -public class MainInstaller : MonoInstaller -{ - public override void InstallBindings() - { - // For this to work, there must be an instance of FooInstaller added at - // Resources/My/Custom/ResourcePath.asset - FooInstaller.InstallFromResource("My/Custom/ResourcePath", Container, "asdf"); - - // In this case the FooInstaller asset will be assumed to exist at 'Resources/Installers/FooInstaller' - // FooInstaller.InstallFromResource(Container, "asdf"); - } -} -``` +ScriptableObjectInstaller works the same as MonoInstaller in this regard. ## Signals @@ -1629,6 +1668,7 @@ What follows below is a more detailed view of what happens when running a scene * These same steps repeated for LateUpdate and ILateTickable * At the same time, These same steps are repeated for FixedUpdate according to the physics timestep * Unity scene is unloaded + * Dispose() is called on all objects mapped to `IDisposable` within all the GameObjectContext's (see here for details) * Dispose() is called on all objects mapped to `IDisposable` within the SceneContext installers (see here for details) * App is exitted * Dispose() is called on all objects mapped to `IDisposable` within the ProjectContext installers (see here for details) @@ -1773,7 +1813,7 @@ It is called 'Contract Name' because all the environment scenes will be expected Note that you do not need to load the environment scene and the ship scene at the same time for this to work. For example, you might want to have a menu embedded inside the environment to allow the user to choose their ship before starting. So you could create a menu scene and load that after the environment scene. Then once the user chooses their ship, you could load the associated ship scene by calling the unity method `SceneManager.LoadScene` (making sure to use `LoadSceneMode.Additive`). -Also note that the Validate command can be used to quickly verify the different multi-scene setups. +Also note that the Validate command can be used to quickly verify the different multi-scene setups. If you find that scenes are unloaded when you do this see here. Also, I should mention that Unity currently doesn't have a built-in way to save and restore multi-scene setups. We use a simple editor script for this that you can find here if interested. @@ -1818,7 +1858,7 @@ public class TestHotKeysAdder : ITickable If you run your scene it should now behave exactly like the main scene except with the added functionality in your decorator installer. Also note that while not shown here, both scenes can access each other's bindings as if everything was in the same scene. -Also note that the Validate command (CTRL+SHIFT+V) can be used to quickly verify the different multi-scene setups. +Also note that the Validate command (CTRL+SHIFT+V) can be used to quickly verify the different multi-scene setups. If you find that scenes are unloaded when you do this see here. Also, note that decorator scenes must be loaded before the scenes that they are decorating. @@ -1884,26 +1924,26 @@ public class Bar _foo = foo; } - public void DoThing() + public void Run() { - _foo.Value.DoThing(); + _foo.Value.Run(); } } ``` -Now, by using `Lazy<>` instead, the Foo class will not be created until Bar.DoThing is first called. After that, it will use the same instance of Foo. +Now, by using `Lazy<>` instead, the Foo class will not be created until Bar.Run is first called. After that, it will use the same instance of Foo. Note that the installers remain the same in both cases. Any injected dependency can be made lazy by simply wrapping it in `Lazy<>`. ## DiContainer Methods -In addition to the bind methods documented above, there are also some other methods you might want to occasionally use on DiContainer. For example, if you are writing a custom factory, you might want to directly call one of the `DiContainer.Instantaite` methods. Or you might have a situation where another library is creating instances of your classes (for example, a networking library) and you need to manually call DiContainer.Inject. +In addition to the bind methods documented above, there are also some other methods you might want to occasionally use on DiContainer. For example, if you are writing a custom factory, you might want to directly call one of the `DiContainer.Instantiate` methods. Or you might have a situation where another library is creating instances of your classes (for example, a networking library) and you need to manually call DiContainer.Inject. -DiContainer is always added to itself, so you can always get it injected into any class. However, note that this is usually a sign of bad practice, since there is almost always a better way to design your code such that you don't need to reference DiContainer directly. Once again, best practice with dependency injection is to only reference the DiContainer in the "composition root layer" which includes any custom factories you might have as well as the installers. However there are exceptions to this rule. +DiContainer is always added to itself, so you can always get it injected into any class. However, note that injecting the DiContainer is usually a sign of bad practice, since there is almost always a better way to design your code such that you don't need to reference DiContainer directly (the exception being custom factories). Once again, best practice with dependency injection is to only reference the DiContainer in the "composition root layer" which includes any custom factories you might have as well as the installers. However there are exceptions to this rule. ### DiContainer.Instantiate -These instantiate methods might be useful for example when creating a custom factory. Note however that in most cases, you can probably get away with using a normal Factory instead without needing to directly reference DiContainer. +These instantiate methods might be useful for example inside a custom factory. Note however that in most cases, you can probably get away with using a normal Factory instead without needing to directly reference DiContainer. When instantiating objects directly, you can either use DiContainer or you can use IInstantiator, which DiContainer inherits from. IInstantiator exists because often, in custom factories, you are only interested in the instantiate operation so you don't need the Bind, Resolve, etc. methods @@ -2173,7 +2213,7 @@ This is also precisely how the initial MonoBehaviour's in the scene are injected It is possible to remove or replace bindings that were added in a previous bind statement. -1. Unbind - Remove all bindings matching the given type/id from container. +1. **Unbind** - Remove all bindings matching the given type/id from container. ```csharp Container.Bind().To(); @@ -2182,7 +2222,7 @@ It is possible to remove or replace bindings that were added in a previous bind Container.Unbind(); ``` -1. Rebind - Override existing bindings with a new one. This is equivalent to calling unbind with the given type and then immediately calling bind afterwards. +1. **Rebind** - Override existing bindings with a new one. This is equivalent to calling unbind with the given type and then immediately calling bind afterwards. ```csharp Container.Bind().To(); @@ -2219,10 +2259,6 @@ It is possible to remove or replace bindings that were added in a previous bind 1. **DiContainer.GetDependencyContracts** - Returns a list of all the types that the given type depends on. This might be useful, for exmaple, if you wanted to do some static analysis of your project, or if you wanted to automatically generate a dependency diagram, etc. -## Decorator Bind - -TBD - ## Non Generic bindings In some cases you may not know the exact type you want to bind at compile time. In these cases you can use the overload of the `Bind` method which takes a `System.Type` value instead of a generic parameter. @@ -2275,7 +2311,7 @@ Container.Bind(typeof(ITickable), typeof(IInitializable), typeof(IDisposable)).T Though in this particular example there is already a built-in shortcut method for this: ```csharp -Container.BindAllInterfaces().To().AsSingle(); +Container.BindInterfacesTo().AsSingle(); ``` ## Convention Based Binding @@ -2385,7 +2421,7 @@ Note that you can chain together any combination of the below conditionals in th .To(x => x.AllNonAbstractClasses().InNamespace("MyGame.Things")); ``` - This is equivalent to calling `Container.BindAllInterfaces().To()` for every type in the namespace "MyGame.Things". This works because, as touched on above, Zenject will skip any bindings in which the concrete type does not actually derive from the base type. So even though we are using `AllInterfaces` which matches every single interface in every single loaded assembly, this is ok because it will not try and bind an interface to a type that doesn't implement this interface. + This is equivalent to calling `Container.BindInterfacesTo()` for every type in the namespace "MyGame.Things". This works because, as touched on above, Zenject will skip any bindings in which the concrete type does not actually derive from the base type. So even though we are using `AllInterfaces` which matches every single interface in every single loaded assembly, this is ok because it will not try and bind an interface to a type that doesn't implement this interface. ## Singleton Identifiers @@ -2452,7 +2488,7 @@ public class TimerWindow : ZenjectEditorWindow public override void InstallBindings() { Container.BindInstance(_timerState); - Container.BindAllInterfaces().To().AsSingle(); + Container.BindInterfacesTo().AsSingle(); } } @@ -2523,6 +2559,8 @@ Something else to note is that the rate at which the ITickable.Tick method gets Zenject uses C# reflection which is typically slow, but in Zenject this work is cached so any performance hits only occur once for each class type. In other words, Zenject avoids costly reflection operations by making a trade-off between performance and memory to ensure good performance. + You can also force Zenject to populate this cache by calling `Zenject.TypeAnalyzer.GetInfo` for each type you want Zenject to cache the reflection information for. + For some benchmarks on Zenject versus other DI frameworks, see [here](https://github.com/svermeulen/IocPerformance/tree/Zenject). Zenject should also produce zero per-frame heap allocations. From 52e687076b9edde41e14a8141f895b4c1eb83994 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 13 Feb 2017 00:04:23 -0400 Subject: [PATCH 56/62] Added BindInstances method --- .../Assets/Zenject/Source/Main/DiContainer.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs index 8392fa02c..1c735dcf4 100644 --- a/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs +++ b/UnityProject/Assets/Zenject/Source/Main/DiContainer.cs @@ -1835,6 +1835,19 @@ public IdScopeConditionCopyNonLazyBinder BindInstance(TContract insta return new IdScopeConditionCopyNonLazyBinder(bindInfo); } + // Unfortunately we can't support setting scope / condition / etc. here since all the + // bindings are finalized one at a time + public void BindInstances(params object[] instances) + { + foreach (var instance in instances) + { + Assert.That(!ZenUtilInternal.IsNull(instance), + "Found null instance provided to BindInstances method"); + + Bind(instance.GetType()).FromInstance(instance); + } + } + FactoryToChoiceIdBinder BindFactoryInternal() where TFactoryConcrete : TFactoryContract, IFactory where TFactoryContract : IFactory From bea707ee5fe16355edea88d4e66668ce50b022c7 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 13 Feb 2017 00:10:09 -0400 Subject: [PATCH 57/62] Fixes to get release script working --- Build/python/mtm/zen/CreateRelease.py | 2 + NonUnityBuild/Zenject.sln | 20 +++++ .../Signals/Zenject.Signals.csproj | 77 +++++++++++++++++++ .../Assets/Zenject/Source/Zenject.csproj | 9 +-- 4 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/Signals/Zenject.Signals.csproj diff --git a/Build/python/mtm/zen/CreateRelease.py b/Build/python/mtm/zen/CreateRelease.py index 8bf366b9f..e00cd3993 100644 --- a/Build/python/mtm/zen/CreateRelease.py +++ b/Build/python/mtm/zen/CreateRelease.py @@ -97,6 +97,7 @@ def _createNonUnityZip(self, zipPath): self._log.info('Copying Zenject dlls') self._sys.copyFile('{0}/Zenject.dll'.format(binDir), '{0}/Zenject.dll'.format(tempDir)) + self._sys.copyFile('{0}/Zenject.Signals.dll'.format(binDir), '{0}/Zenject.Signals.dll'.format(tempDir)) self._zipHelper.createZipFile(tempDir, zipPath) @@ -128,6 +129,7 @@ def _createCSharpPackage(self, includeSample, outputPath): self._sys.removeFile('[ZenTempDir]/OptionalExtras/AutoMocking.meta') self._sys.removeFile('[ZenTempDir]/Source/Zenject.csproj') + self._sys.removeFile('[ZenTempDir]/OptionalExtras/Signals/Zenject.Signals.csproj') if not includeSample: self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/SampleGame1 (Beginner)') diff --git a/NonUnityBuild/Zenject.sln b/NonUnityBuild/Zenject.sln index 2bd3743fd..b0633a082 100644 --- a/NonUnityBuild/Zenject.sln +++ b/NonUnityBuild/Zenject.sln @@ -7,20 +7,40 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zenject", "..\UnityProject\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zenject-tests", "..\UnityProject\Assets\Zenject\OptionalExtras\UnitTests\Editor\Zenject-tests.csproj", "{34E27462-3046-4DC7-A7FA-45E4F4F7D413}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zenject.Signals", "..\UnityProject\Assets\Zenject\OptionalExtras\Signals\Zenject.Signals.csproj", "{8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug.InternalCloud|Any CPU = Debug.InternalCloud|Any CPU Debug|Any CPU = Debug|Any CPU + Release.InternalCloud|Any CPU = Release.InternalCloud|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {46F25A62-2E29-48CB-95F3-BDBCB0976DDC}.Debug.InternalCloud|Any CPU.ActiveCfg = Debug|Any CPU + {46F25A62-2E29-48CB-95F3-BDBCB0976DDC}.Debug.InternalCloud|Any CPU.Build.0 = Debug|Any CPU {46F25A62-2E29-48CB-95F3-BDBCB0976DDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {46F25A62-2E29-48CB-95F3-BDBCB0976DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {46F25A62-2E29-48CB-95F3-BDBCB0976DDC}.Release.InternalCloud|Any CPU.ActiveCfg = Release|Any CPU + {46F25A62-2E29-48CB-95F3-BDBCB0976DDC}.Release.InternalCloud|Any CPU.Build.0 = Release|Any CPU {46F25A62-2E29-48CB-95F3-BDBCB0976DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU {46F25A62-2E29-48CB-95F3-BDBCB0976DDC}.Release|Any CPU.Build.0 = Release|Any CPU + {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Debug.InternalCloud|Any CPU.ActiveCfg = Debug|Any CPU + {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Debug.InternalCloud|Any CPU.Build.0 = Debug|Any CPU {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Release.InternalCloud|Any CPU.ActiveCfg = Release|Any CPU + {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Release.InternalCloud|Any CPU.Build.0 = Release|Any CPU {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Release|Any CPU.ActiveCfg = Release|Any CPU {34E27462-3046-4DC7-A7FA-45E4F4F7D413}.Release|Any CPU.Build.0 = Release|Any CPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}.Debug.InternalCloud|Any CPU.ActiveCfg = Debug|Any CPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}.Debug.InternalCloud|Any CPU.Build.0 = Debug|Any CPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}.Release.InternalCloud|Any CPU.ActiveCfg = Release|Any CPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}.Release.InternalCloud|Any CPU.Build.0 = Release|Any CPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Zenject.Signals.csproj b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Zenject.Signals.csproj new file mode 100644 index 000000000..b0e6c3514 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Zenject.Signals.csproj @@ -0,0 +1,77 @@ + + + + + Debug + AnyCPU + {8FB1D1DE-C5E7-47C2-AFF0-1E1A49DA08BD} + Library + Properties + Zenject.Signals + Zenject.Signals + v3.5 + 512 + + true + full + false + DEBUG;TRACE + prompt + 4 + + + true + full + false + ..\..\..\..\..\NonUnityBuild\Temp\Debug\ + ..\..\..\..\..\NonUnityBuild\Temp\Debug\ + ..\..\..\..\..\NonUnityBuild\Bin\Debug\ + TRACE;DEBUG;NOT_UNITY3D + prompt + 4 + + + pdbonly + true + ..\..\..\..\..\NonUnityBuild\Temp\Release\ + ..\..\..\..\..\NonUnityBuild\Temp\Release\ + ..\..\..\..\..\NonUnityBuild\Bin\Release\ + TRACE;NOT_UNITY3D + prompt + 4 + + + + + + + + + + + + {46f25a62-2e29-48cb-95f3-bdbcb0976ddc} + Zenject + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Source/Zenject.csproj b/UnityProject/Assets/Zenject/Source/Zenject.csproj index 2e34a6606..c72bab943 100644 --- a/UnityProject/Assets/Zenject/Source/Zenject.csproj +++ b/UnityProject/Assets/Zenject/Source/Zenject.csproj @@ -53,6 +53,7 @@ + @@ -74,6 +75,7 @@ + @@ -166,7 +168,6 @@ - @@ -214,10 +215,6 @@ - - - - @@ -226,7 +223,6 @@ - @@ -240,7 +236,6 @@ - From 0d350c41dfcd6321570f611733f849efb2d7c278 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 13 Feb 2017 00:26:46 -0400 Subject: [PATCH 58/62] Changed signals to have the derived class as the last generic argument since that's the convention everywhere else --- Documentation/Signals.md | 4 ++-- .../Assets/Zenject/OptionalExtras/Signals/Signal1.cs | 8 ++++---- .../Assets/Zenject/OptionalExtras/Signals/Signal2.cs | 8 ++++---- .../Assets/Zenject/OptionalExtras/Signals/Signal3.cs | 8 ++++---- .../Assets/Zenject/OptionalExtras/Signals/Signal4.cs | 8 ++++---- .../UnitTests/Editor/Signals/TestSignalsFourParams.cs | 2 +- .../UnitTests/Editor/Signals/TestSignalsOneParam.cs | 2 +- .../Editor/Signals/TestSignalsWithIdentifiers.cs | 2 +- .../Editor/Signals/TestSignalsWithParameters2.cs | 8 ++++---- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Documentation/Signals.md b/Documentation/Signals.md index d69606674..a02ddf6a6 100644 --- a/Documentation/Signals.md +++ b/Documentation/Signals.md @@ -17,7 +17,7 @@ As a third option, in some cases it might actually be better for neither one to If you just want to get up and running immediately, see the following example which shows basic usage: ```csharp -public class UserJoinedSignal : Signal +public class UserJoinedSignal : Signal { } @@ -109,7 +109,7 @@ Classes that derive from Signal should always be left empty - their only purpose Any parameters passed along with the signal need to be included as more generic arguments: ```csharp -public class DoSomethingSignal : Signal +public class DoSomethingSignal : Signal { } ``` diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs index 166bbe774..5681d2f49 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal1.cs @@ -15,8 +15,8 @@ public interface ISignal : ISignalBase void Fire(TParam1 p1); } - public abstract class Signal : SignalBase, ISignal - where TDerived : Signal + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal { readonly List> _listeners = new List>(); #if ZEN_SIGNALS_ADD_UNIRX @@ -55,13 +55,13 @@ public void Unlisten(Action listener) .Fmt(listener.ToDebugString(), this.GetType())); } - public static TDerived operator + (Signal signal, Action listener) + public static TDerived operator + (Signal signal, Action listener) { signal.Listen(listener); return (TDerived)signal; } - public static TDerived operator - (Signal signal, Action listener) + public static TDerived operator - (Signal signal, Action listener) { signal.Unlisten(listener); return (TDerived)signal; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs index 66a4bdb1e..ab589288b 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal2.cs @@ -15,8 +15,8 @@ public interface ISignal : ISignalBase void Fire(TParam1 p1, TParam2 p2); } - public abstract class Signal : SignalBase, ISignal - where TDerived : Signal + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal { readonly List> _listeners = new List>(); @@ -55,13 +55,13 @@ public void Unlisten(Action listener) .Fmt(listener.ToDebugString(), this.GetType())); } - public static TDerived operator + (Signal signal, Action listener) + public static TDerived operator + (Signal signal, Action listener) { signal.Listen(listener); return (TDerived)signal; } - public static TDerived operator - (Signal signal, Action listener) + public static TDerived operator - (Signal signal, Action listener) { signal.Unlisten(listener); return (TDerived)signal; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs index 4e05da6d5..3536e3f4e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal3.cs @@ -15,8 +15,8 @@ public interface ISignal : ISignalBase void Fire(TParam1 p1, TParam2 p2, TParam3 p3); } - public abstract class Signal : SignalBase, ISignal - where TDerived : Signal + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal { readonly List> _listeners = new List>(); #if ZEN_SIGNALS_ADD_UNIRX @@ -54,13 +54,13 @@ public void Unlisten(Action listener) .Fmt(listener.ToDebugString(), this.GetType())); } - public static TDerived operator + (Signal signal, Action listener) + public static TDerived operator + (Signal signal, Action listener) { signal.Listen(listener); return (TDerived)signal; } - public static TDerived operator - (Signal signal, Action listener) + public static TDerived operator - (Signal signal, Action listener) { signal.Unlisten(listener); return (TDerived)signal; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs index cc50c0ec0..c1b40a835 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Signal4.cs @@ -15,8 +15,8 @@ public interface ISignal : ISignalBase void Fire(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4); } - public abstract class Signal : SignalBase, ISignal - where TDerived : Signal + public abstract class Signal : SignalBase, ISignal + where TDerived : Signal { readonly List> _listeners = new List>(); #if ZEN_SIGNALS_ADD_UNIRX @@ -54,13 +54,13 @@ public void Unlisten(Action listener) .Fmt(listener.ToDebugString(), this.GetType())); } - public static TDerived operator + (Signal signal, Action listener) + public static TDerived operator + (Signal signal, Action listener) { signal.Listen(listener); return (TDerived)signal; } - public static TDerived operator - (Signal signal, Action listener) + public static TDerived operator - (Signal signal, Action listener) { signal.Unlisten(listener); return (TDerived)signal; diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs index e5ae6227b..7c5f4048e 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsFourParams.cs @@ -39,7 +39,7 @@ public void RunTest() bar.Dispose(); } - public class SomethingHappenedSignal : Signal + public class SomethingHappenedSignal : Signal { } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs index 6eb12324b..3e9ee3c20 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsOneParam.cs @@ -39,7 +39,7 @@ public void RunTest() bar.Dispose(); } - public class SomethingHappenedSignal : Signal + public class SomethingHappenedSignal : Signal { } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs index 61cbbe17e..9c508fc23 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithIdentifiers.cs @@ -61,7 +61,7 @@ public void RunTest() barSpecial.Dispose(); } - public class SomethingHappenedSignal : Signal + public class SomethingHappenedSignal : Signal { } diff --git a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs index 5cac15a5c..885e751d7 100644 --- a/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs +++ b/UnityProject/Assets/Zenject/OptionalExtras/UnitTests/Editor/Signals/TestSignalsWithParameters2.cs @@ -116,10 +116,10 @@ public void TestParameters4() Assert.IsEqual(Bar4.Value4, 'z'); } - public class DoSomethingSignal1 : Signal { } - public class DoSomethingSignal2 : Signal { } - public class DoSomethingSignal3 : Signal { } - public class DoSomethingSignal4 : Signal { } + public class DoSomethingSignal1 : Signal { } + public class DoSomethingSignal2 : Signal { } + public class DoSomethingSignal3 : Signal { } + public class DoSomethingSignal4 : Signal { } public class Bar1 { From fa4d3d844074b99154325b9b08f19d5d55b6c609 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 13 Feb 2017 11:40:46 -0400 Subject: [PATCH 59/62] More tweaks to the docs --- Documentation/CheatSheet.md | 48 ++++++------- Documentation/Factories.md | 6 +- Documentation/MemoryPools.md | 4 +- Documentation/Signals.md | 67 ++++++++++++------- Documentation/SubContainers.md | 16 ++--- .../Signals/Zenject.Signals.csproj.meta} | 4 +- 6 files changed, 79 insertions(+), 66 deletions(-) rename UnityProject/Assets/Zenject/{Source/Zenject.csproj.user.meta => OptionalExtras/Signals/Zenject.Signals.csproj.meta} (64%) diff --git a/Documentation/CheatSheet.md b/Documentation/CheatSheet.md index 2ef2e215a..ac7161e35 100644 --- a/Documentation/CheatSheet.md +++ b/Documentation/CheatSheet.md @@ -10,17 +10,10 @@ For more examples, you may also be interested in reading some of the Unit tests // Create a new instance of Foo for every class that asks for it Container.Bind().AsTransient(); -// This is equivalent since AsTransient is the default -Container.Bind(); - // Create a new instance of Foo for every class that asks for an IFoo Container.Bind().To().AsTransient(); -// This is equivalent since Transient is the default -Container.Bind().To(); - -// Non generic versions -Container.Bind(typeof(IFoo)).AsTransient(); +// Non generic version Container.Bind(typeof(IFoo)).To(typeof(Foo)).AsTransient(); ///////////// AsSingle @@ -38,7 +31,10 @@ Container.Bind().To().AsSingle(); // Non generic versions Container.Bind(typeof(Foo)).AsSingle(); -Container.Bind(typeof(IFoo)).AsSingle(typeof(Foo)); +Container.Bind(typeof(IFoo)).To(typeof(Foo)).AsSingle(); + +// Or, as one bind statement +Container.Bind(typeof(Foo), typeof(IFoo)).To(typeof(Foo)).AsSingle(); ///////////// BindInterfaces @@ -127,18 +123,18 @@ Container.Bind().FromResolveGetter(foo => foo.GetBar()); // Another example using values Container.Bind().FromResolveGetter(foo => foo.GetTitle()); -///////////// FromGameObject (singleton) +///////////// FromNewComponentOnNewGameObject (singleton) // Create a new game object at the root of the scene, add the Foo MonoBehaviour to it, and name it "Foo" -Container.Bind().FromGameObject().AsSingle(); +Container.Bind().FromNewComponentOnNewGameObject().AsSingle(); // You can also specify the game object name to use using WithGameObjectName -Container.Bind().FromGameObject().WithGameObjectName("Foo1").AsSingle(); +Container.Bind().FromNewComponentOnNewGameObject().WithGameObjectName("Foo1").AsSingle(); // Bind to an interface instead -Container.Bind().To().FromGameObject().AsSingle(); +Container.Bind().To().FromNewComponentOnNewGameObject().AsSingle(); -///////////// FromPrefab (singleton) +///////////// FromComponentInNewPrefab (singleton) // Create a new game object at the root of the scene using the given prefab // It is assumed that the Foo is a MonoBehaviour here and that Foo has been @@ -146,10 +142,10 @@ Container.Bind().To().FromGameObject().AsSingle(); // After zenject creates a new GameObject from the given prefab, it will // search the prefab for a component of type 'Foo' and return that GameObject fooPrefab; -Container.Bind().FromPrefab(fooPrefab).AsSingle(); +Container.Bind().FromComponentInNewPrefab(fooPrefab).AsSingle(); // Bind to interface instead -Container.Bind().To().FromPrefab(fooPrefab).AsSingle(); +Container.Bind().To().FromComponentInNewPrefab(fooPrefab).AsSingle(); // In this example we use AsSingle but with different components // Note here that only one instance of the given prefab will be @@ -158,21 +154,21 @@ Container.Bind().To().FromPrefab(fooPrefab).AsSingle(); // For this to work, there must be both a Foo MonoBehaviour and // a Bar MonoBehaviour somewhere on the prefab GameObject prefab; -Container.Bind().FromPrefab(prefab).AsSingle(); -Container.Bind().FromPrefab(prefab).AsSingle(); +Container.Bind().FromComponentInNewPrefab(prefab).AsSingle(); +Container.Bind().FromComponentInNewPrefab(prefab).AsSingle(); -///////////// FromPrefab (Transient) +///////////// FromComponentInNewPrefab (Transient) // Instantiate a new copy of 'fooPrefab' every time an instance of Foo is // requested by a constructor parameter, injected field, etc. GameObject fooPrefab = null; -Container.Bind().FromPrefab(fooPrefab); +Container.Bind().FromComponentInNewPrefab(fooPrefab); // Again, this is equivalent since AsTransient is the default -Container.Bind().FromPrefab(fooPrefab).AsTransient(); +Container.Bind().FromComponentInNewPrefab(fooPrefab).AsTransient(); // Bind to interface instead -Container.Bind().To().FromPrefab(fooPrefab); +Container.Bind().To().FromComponentInNewPrefab(fooPrefab); ///////////// Identifiers @@ -290,15 +286,15 @@ Container.BindInstance(foo2).When(c => c.ParentContexts.Where(x => x.MemberType // This will result in IBar, IFoo, and Foo, all being bound to the same instance of // Foo which is assume to exist somewhere on the given prefab GameObject fooPrefab; -Container.Bind().FromPrefab(fooPrefab).AsSingle(); +Container.Bind().FromComponentInNewPrefab(fooPrefab).AsSingle(); Container.Bind().To().FromResolve(); Container.Bind().To().FromResolve(); // This will result in the same behaviour as the above GameObject fooPrefab = null; -Container.Bind().FromPrefab(fooPrefab).AsSingle(); -Container.Bind().To().FromPrefab(fooPrefab).AsSingle(); -Container.Bind().To().FromPrefab(fooPrefab).AsSingle(); +Container.Bind().FromComponentInNewPrefab(fooPrefab).AsSingle(); +Container.Bind().To().FromComponentInNewPrefab(fooPrefab).AsSingle(); +Container.Bind().To().FromComponentInNewPrefab(fooPrefab).AsSingle(); ///////////// Rebind diff --git a/Documentation/Factories.md b/Documentation/Factories.md index fb39753d1..5e0d721c6 100644 --- a/Documentation/Factories.md +++ b/Documentation/Factories.md @@ -69,7 +69,7 @@ public class EnemySpawner } ``` -This will not work however, since in our case the Enemy class requires a reference to the Player class in its constructor. We could add a dependency to the Player class to the EnemySpawner class, but then we have the problem described above. The EnemySpawner class doesn't care about filling in the dependencies for the Enemy class. All the EnemySpawner class cares about is getting a new Enemy instance. +This will not work however, since in our case the Enemy class requires a reference to the Player class in its constructor. We could add a dependency to the Player class to the EnemySpawner class, but then we have the problem described above. The EnemySpawner class doesn't care about filling in the dependencies for the Enemy class. All the EnemySpawner class cares about is getting a new Enemy instance. The recommended way to do this in Zenject is the following: @@ -209,7 +209,7 @@ public class TestInstaller : MonoInstaller { Container.BindInterfacesTo().AsSingle(); Container.Bind().AsSingle(); - Container.BindFactory().FromPrefab(EnemyPrefab); + Container.BindFactory().FromComponentInNewPrefab(EnemyPrefab); } } @@ -293,7 +293,7 @@ public class GameInstaller : MonoInstaller *Ok, but what if I don't know what type I want to create until after the application has started? Or what if I have special requirements for constructing instances of the Enemy class that are not covered by any of the construction methods?* -In these cases you can create a custom factory, and directly call `new Enemy` or directly use the `DiContainer` class to create your object. For example, continuing the previous factory example, let's say that you wanted to be able to change a runtime value (difficulty) that determines what kinds of enemies get created. +In these cases you can create a custom factory, and directly call `new Enemy` or directly use the methods on DiContainer to create your object. For example, continuing the previous factory example, let's say that you wanted to be able to change a runtime value (difficulty) that determines what kinds of enemies get created. ```csharp public enum Difficulties diff --git a/Documentation/MemoryPools.md b/Documentation/MemoryPools.md index 15bba50f1..e52f85e6b 100644 --- a/Documentation/MemoryPools.md +++ b/Documentation/MemoryPools.md @@ -286,7 +286,7 @@ public class Foo public class Pool : MemoryPool { - protected override void Reinitialize(Foo foo, Vector3 velocity) + protected override void Reinitialize(Vector3 velocity, Foo foo) { foo.Reset(); foo._velocity = velocity; @@ -350,7 +350,7 @@ public class Foo : MonoBehaviour public class Pool : MonoMemoryPool { - protected override void Reinitialize(Foo foo, Vector3 velocity) + protected override void Reinitialize(Vector3 velocity, Foo foo) { foo.Reset(); foo._velocity = velocity; diff --git a/Documentation/Signals.md b/Documentation/Signals.md index a02ddf6a6..da0a14894 100644 --- a/Documentation/Signals.md +++ b/Documentation/Signals.md @@ -21,7 +21,7 @@ public class UserJoinedSignal : Signal { } -public class Greeter1 +public class Greeter { public void SayHello(string userName) { @@ -29,43 +29,63 @@ public class Greeter1 } } -public class Greeter2 : IInitializable, IDisposable +public class GameInitializer : IInitializable { - UserJoinedSignal _userJoinedSignal; + readonly UserJoinedSignal _userJoinedSignal; - public Greeter2(UserJoinedSignal userJoinedSignal) + public GameInitializer(UserJoinedSignal userJoinedSignal) { _userJoinedSignal = userJoinedSignal; } public void Initialize() { - _userJoinedSignal += OnUserJoined; + _userJoinedSignal.Fire("Bob"); } +} - public void Dispose() +public class GameInstaller : MonoInstaller +{ + public override void InstallBindings() { - _userJoinedSignal -= OnUserJoined; - } + Container.Bind().AsSingle(); + Container.DeclareSignal(); - void OnUserJoined(string username) - { - Debug.Log("Hello again " + username + "!"); + Container.BindSignal() + .To(x => x.SayHello).AsSingle(); + + Container.BindInterfacesTo().AsSingle(); } } +``` -public class GameInitializer : IInitializable +To run, just create copy and paste the code above into a new file named GameInstaller then create an empty scene with a new scene context and attach the new installer. + +There are several ways of creating signal handlers. Another approach would be the following + +```csharp +public class Greeter : IInitializable, IDisposable { - readonly UserJoinedSignal _userJoinedSignal; + UserJoinedSignal _userJoinedSignal; - public GameInitializer(UserJoinedSignal userJoinedSignal) + public Greeter(UserJoinedSignal userJoinedSignal) { _userJoinedSignal = userJoinedSignal; } public void Initialize() { - _userJoinedSignal.Fire("Bob"); + _userJoinedSignal += OnUserJoined; + } + + public void Dispose() + { + _userJoinedSignal -= OnUserJoined; + } + + void OnUserJoined(string username) + { + Debug.Log("Hello again " + username + "!"); } } @@ -76,19 +96,13 @@ public class GameInstaller : MonoInstaller Container.Bind().AsSingle(); Container.DeclareSignal(); - Container.BindInterfacesTo().AsSingle(); - - Container.BindSignal() - .To(x => x.SayHello).AsSingle(); - Container.BindInterfacesTo().AsSingle(); + Container.BindInterfacesTo().AsSingle(); } } ``` -To run, just create copy and paste the code above into a new file named GameInstaller then create an empty scene with a new scene context and attach the new installer. - -As you can see in the the above example, there are two ways of creating signal handlers. You can either directly bind a handler method to a signal in an installer (Greeter1) or you can have your signal handler attach and detach itself to the signal (Greeter2). +As you can see in the the above examples, you can either directly bind a handler method to a signal in an installer (first example) or you can have your signal handler attach and detach itself to the signal (second example). For more details on what's going on above see the following sections. @@ -131,6 +145,7 @@ The format of the DeclareSignal statement is the following:
 Container.DeclareSignal<SignalType>()
+    .WithId(Identifier)
     .RequireHandler()
     .When(Condition);
 
@@ -139,7 +154,9 @@ The When Condition can be any Zenject condition just like any other binding (see The `RequireHandler()` method is optional. If not included, then the signal will be allowed to fire with zero handlers attached. If `RequireHandler()` is added to the binding, then an exception will be thrown if the signal is fired and there isn't any handlers attached. -Then in the firing class: +## Signal Firing + +Firing the signal is as simple as just adding a reference to it and calling Fire ```csharp public class Bar : ITickable @@ -312,7 +329,7 @@ Or, you could add signal handlers in the ProjectContext and then declare the sig For example, You might use this to implement your GUI entirely in its own scene, loaded alongside the main backend scene. Then you could have the GUI scene strictly fire Signals, which would then have method bindings in the game scene. -Something else you'll have noticed in the ExitGameSignal example above is that we also needed to install the SignalManager class: +Something else you'll have noticed in the examples above is that we also needed to install the SignalManager class: ```csharp Container.Bind().AsSingle(); diff --git a/Documentation/SubContainers.md b/Documentation/SubContainers.md index ee38e49db..54f7d513d 100644 --- a/Documentation/SubContainers.md +++ b/Documentation/SubContainers.md @@ -5,7 +5,7 @@ In some cases it can be very useful to use multiple containers in the same appli Another example might be if you are designing an open-world space ship game, you might want each space ship to have it's own container that contains all the class instances responsible for running that specific spaceship. -This is actually how global bindings work. There is one global container for the entire application, and when a unity scene starts up, it creates a new sub-container "underneath" the global container. All the bindings that you add in your scene MonoInstaller are bound to your sub-container. This allows the dependencies in your scene to automatically get injected with global bindings, because sub-containers automatically inherit all the bindings in its parent (and grandparent, etc.). +This is actually how ProjectContext bindings work. There is one container for the entire project, and when a unity scene starts up, it container within each SceneContext is created "underneath" the ProjectContext container. All the bindings that you add in your scene MonoInstaller are bound to your SceneContext container. This allows the dependencies in your scene to automatically get injected with ProjectContext bindings, because sub-containers automatically inherit all the bindings in their parent (and grandparent, etc.). A common design pattern that we like to use in relation to sub-containers is the Facade pattern. This pattern is used to abstract away a related group of dependencies so that it can be used at a higher level when used by other modules in the code base. This is relevant here because often when you are defining sub-containers in your application it is very useful to also define a Facade class that is used to interact with this sub-container as a whole. So, to apply it to the spaceship example above, you might have a SpaceshipFacade class that represents very high-level operations on a spaceship such as "Start Engine", "Take Damage", "Fly to destination", etc. And then internally, the SpaceshipFacade class can delegate the specific handling of all the parts of these requests to the relevant single-responsibility dependencies that exist within the sub-container. @@ -62,9 +62,9 @@ public class TestInstaller : MonoInstaller The important thing to understand here is that any bindings that we add inside the `InstallGreeter` method will only be visible to objects within this sub-container. The only exception is the Facade class (in this case, Greeter) since it is bound to the parent container using the FromSubContainerResolve binding. In other words, in this example, the string "Hello World" is only visible by the Greeter class. -Note that you should always add a bind statement for whatever class is given to FromSubContainerResolve, otherwise this will fail. +Note that you should always add a bind statement for whatever class is given to FromSubContainerResolve within the sub-container install method - otherwise you'll get exceptions and validation will fail. -Note also that it is often better to use `ByInstaller` instead of `ByMethod`. This is because when you use `ByMethod` it is easy to accidentally reference the Container instead of the subContainer. Also, by using `ByInstaller` you can pass arguments into the Installer itself. +Note also that unlike the above example, it is often better to use `ByInstaller` instead of `ByMethod`. This is because when you use `ByMethod` it is easy to accidentally reference the Container instead of the subContainer. Also, by using `ByInstaller` you can pass arguments into the Installer itself. ## Using IInitializable / ITickable / IDisposable within Sub-Containers @@ -164,7 +164,7 @@ The reason this works is because we are now binding IInitializable, IDisposable, ## Creating Sub-Containers on GameObject's by using Game Object Context -Another issue with the sub-container hello world example above is that it does not work very well for MonoBehaviour classes. There is nothing preventing us from adding MonoBehaviour bindings such as FromPrefab, FromGameObject, etc. to our sub-container, however these will cause these new game objects to be added to the root of the scene heirarchy, so we'll have to manually track the lifetime of these objects ourselves by calling GameObject.Destroy on them when the Facade is destroyed. Also, there is no way to have GameObject's that exist in our scene at the start but also exist within our sub-container. These problems can be solved by using Game Object Context. +Another issue with the sub-container hello world example above is that it does not work very well for MonoBehaviour classes. There is nothing preventing us from adding MonoBehaviour bindings such as FromComponentInNewPrefab, FromNewComponentOnNewGameObject, etc. to our sub-container, however these will cause these new game objects to be added to the root of the scene heirarchy, so we'll have to manually track the lifetime of these objects ourselves by calling GameObject.Destroy on them when the Facade is destroyed. Also, there is no way to have GameObject's that exist in our scene at the start but also exist within our sub-container. These problems can be solved by using Game Object Context. For this example, let's try to actually implement something similar to the open world space ship game described in the sub-container introduction: @@ -303,7 +303,7 @@ Also note that we can add installers to our ship sub-container in the same way t Continuing with the ship example above, let's pretend that we now want to create ships dynamically, after the game has started. * First, create a prefab for the entire `Ship` GameObject that we created above and then delete it from the Scene. -* Then just change +* Then just add the following changes ```csharp public class GameRunner : ITickable @@ -340,7 +340,7 @@ public class GameInstaller : MonoInstaller { Container.BindInterfacesTo().AsSingle(); - Container.BindFactory().FromSubContainerResolve().ByPrefab(ShipPrefab); + Container.BindFactory().FromSubContainerResolve().ByNewPrefab(ShipPrefab); } } ``` @@ -389,7 +389,7 @@ public class GameInstaller : MonoInstaller { Container.BindInterfacesTo().AsSingle(); - Container.BindFactory().FromSubContainerResolve().ByPrefab(ShipPrefab); + Container.BindFactory().FromSubContainerResolve().ByNewPrefab(ShipPrefab); } } ``` @@ -494,5 +494,5 @@ public class ShipInstaller : MonoInstaller This way, you can drop the Ship prefab into the scene and control the speed in the inspector, but you can also create them dynamically and pass the speed into the factory as a parameter. -For a more real-world example see the "Sample2" demo project which makes heavy use of Game Object Contexts. +For a more real-world example see the SpaceFighter sample project which makes heavy use of Game Object Contexts. diff --git a/UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Zenject.Signals.csproj.meta similarity index 64% rename from UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta rename to UnityProject/Assets/Zenject/OptionalExtras/Signals/Zenject.Signals.csproj.meta index daad463e2..3d9d3286e 100644 --- a/UnityProject/Assets/Zenject/Source/Zenject.csproj.user.meta +++ b/UnityProject/Assets/Zenject/OptionalExtras/Signals/Zenject.Signals.csproj.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: ed8c2ea47adf5544d838e58584d5175c -timeCreated: 1484719217 +guid: e18e0b85ea6a78144907309cfb3ba341 +timeCreated: 1486960494 licenseType: Free DefaultImporter: userData: From 132ff0f952feb49a8b2680f2b53e6b6d2973548f Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 13 Feb 2017 12:04:22 -0400 Subject: [PATCH 60/62] Updated the html docs --- Build/CreateHtmlDocs.bat | 17 +- .../Zenject/Documentation/AutoMocking.html | 12 +- .../Zenject/Documentation/CheatSheet.html | 248 ++-- .../Zenject/Documentation/Factories.html | 142 +- .../Zenject/Documentation/MemoryPools.html | 615 ++++++++ .../Documentation/MemoryPools.html.meta | 8 + .../Assets/Zenject/Documentation/ReadMe.html | 1269 ++++++++++++----- .../Zenject/Documentation/ReleaseNotes.html | 282 +++- .../Assets/Zenject/Documentation/Signals.html | 488 +++++++ .../Zenject/Documentation/Signals.html.meta | 8 + .../Zenject/Documentation/SubContainers.html | 154 +- .../Documentation/WritingAutomatedTests.html | 40 +- 12 files changed, 2538 insertions(+), 745 deletions(-) create mode 100644 UnityProject/Assets/Zenject/Documentation/MemoryPools.html create mode 100644 UnityProject/Assets/Zenject/Documentation/MemoryPools.html.meta create mode 100644 UnityProject/Assets/Zenject/Documentation/Signals.html create mode 100644 UnityProject/Assets/Zenject/Documentation/Signals.html.meta diff --git a/Build/CreateHtmlDocs.bat b/Build/CreateHtmlDocs.bat index ae9c054a7..a878b801e 100644 --- a/Build/CreateHtmlDocs.bat +++ b/Build/CreateHtmlDocs.bat @@ -1,10 +1,11 @@ @echo off -grip %~dp0\..\README.md --export .\UnityProject\Assets\Zenject\Documentation\README.html -grip %~dp0\..\Documentation\AutoMocking.md --export .\UnityProject\Assets\Zenject\Documentation\AutoMocking.html -grip %~dp0\..\Documentation\CheatSheet.md --export .\UnityProject\Assets\Zenject\Documentation\CheatSheet.html -grip %~dp0\..\Documentation\CommandsAndSignals.md --export .\UnityProject\Assets\Zenject\Documentation\CommandsAndSignals.html -grip %~dp0\..\Documentation\Factories.md --export .\UnityProject\Assets\Zenject\Documentation\Factories.html -grip %~dp0\..\Documentation\ReleaseNotes.md --export .\UnityProject\Assets\Zenject\Documentation\ReleaseNotes.html -grip %~dp0\..\Documentation\SubContainers.md --export .\UnityProject\Assets\Zenject\Documentation\SubContainers.html -grip %~dp0\..\Documentation\WritingAutomatedTests.md --export .\UnityProject\Assets\Zenject\Documentation\WritingAutomatedTests.html +grip %~dp0\..\README.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\README.html +grip %~dp0\..\Documentation\AutoMocking.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\AutoMocking.html +grip %~dp0\..\Documentation\CheatSheet.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\CheatSheet.html +grip %~dp0\..\Documentation\Signals.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\Signals.html +grip %~dp0\..\Documentation\Factories.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\Factories.html +grip %~dp0\..\Documentation\MemoryPools.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\MemoryPools.html +grip %~dp0\..\Documentation\ReleaseNotes.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\ReleaseNotes.html +grip %~dp0\..\Documentation\SubContainers.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\SubContainers.html +grip %~dp0\..\Documentation\WritingAutomatedTests.md --export %~dp0\..\UnityProject\Assets\Zenject\Documentation\WritingAutomatedTests.html diff --git a/UnityProject/Assets/Zenject/Documentation/AutoMocking.html b/UnityProject/Assets/Zenject/Documentation/AutoMocking.html index 26c8b54c1..6e018791a 100644 --- a/UnityProject/Assets/Zenject/Documentation/AutoMocking.html +++ b/UnityProject/Assets/Zenject/Documentation/AutoMocking.html @@ -56,9 +56,9 @@

public class Foo
 {
-    IWebServer _webServer;
+    IWebServer _webServer;
 
-    public Foo(IWebServer webServer)
+    public Foo(IWebServer webServer)
     {
         _webServer = webServer;
     }
@@ -66,7 +66,7 @@ 

public void Initialize() { ... - var x = _webServer.GetSomething(); + var x = _webServer.GetSomething(); ... } }

@@ -82,14 +82,14 @@

However, if we create a mock class for IWebServer then we can address all these problems:

-
public class MockWebServer : IWebServer
+
public class MockWebServer : IWebServer
 {
     ...
 }

Then hook it up in our installer:

-
Container.Bind<IWebServer>().To<MockWebServer>().AsSingle();
+
Container.Bind<IWebServer>().To<MockWebServer>().AsSingle();

Then you can implement the fields of the IWebServer interface and configure them based on what you want to test on Foo. Hopefully You can see how this can make life when writing tests much easier.

@@ -99,7 +99,7 @@

After extracting the auto mocking package it is just a matter of using the following syntax to mock out various parts of your project:

-
Container.Bind<IFoo>().ToMock();
+
Container.Bind<IFoo>().ToMock();

However, this approach will not allow you to take advantage of the advanced features of Moq. For more advanced usages, see the documentation for Moq

diff --git a/UnityProject/Assets/Zenject/Documentation/CheatSheet.html b/UnityProject/Assets/Zenject/Documentation/CheatSheet.html index 3719dc7ee..66a2d5161 100644 --- a/UnityProject/Assets/Zenject/Documentation/CheatSheet.html +++ b/UnityProject/Assets/Zenject/Documentation/CheatSheet.html @@ -58,95 +58,91 @@

 // Create a new instance of Foo for every class that asks for it
-Container.Bind<Foo>().AsTransient();
-
-// This is equivalent since AsTransient is the default
-Container.Bind<Foo>();
+Container.Bind<Foo>().AsTransient();
 
 // Create a new instance of Foo for every class that asks for an IFoo
-Container.Bind<IFoo>().To<Foo>().AsTransient();
-
-// This is equivalent since Transient is the default
-Container.Bind<IFoo>().To<Foo>();
+Container.Bind<IFoo>().To<Foo>().AsTransient();
 
-// Non generic versions
-Container.Bind(typeof(IFoo)).AsTransient();
-Container.Bind(typeof(IFoo)).To(typeof(Foo)).AsTransient();
+// Non generic version
+Container.Bind(typeof(IFoo)).To(typeof(Foo)).AsTransient();
 
-///////////// AsSingle
+///////////// AsSingle
 
 // Create one definitive instance of Foo and re-use that for every class that asks for it
-Container.Bind<Foo>().AsSingle();
+Container.Bind<Foo>().AsSingle();
 
 // Create one definitive instance of Foo and re-use that for every class that asks for IFoo
-Container.Bind<IFoo>().To<Foo>().AsSingle();
+Container.Bind<IFoo>().To<Foo>().AsSingle();
 
 // In this example, the same instance of Foo will be used for all three cases
-Container.Bind<Foo>().AsSingle();
-Container.Bind<IFoo>().To<Foo>().AsSingle();
-Container.Bind<IFoo2>().To<Foo>().AsSingle();
+Container.Bind<Foo>().AsSingle();
+Container.Bind<IFoo>().To<Foo>().AsSingle();
+Container.Bind<IFoo2>().To<Foo>().AsSingle();
 
 // Non generic versions
-Container.Bind(typeof(Foo)).AsSingle();
-Container.Bind(typeof(IFoo)).AsSingle(typeof(Foo));
+Container.Bind(typeof(Foo)).AsSingle();
+Container.Bind(typeof(IFoo)).To(typeof(Foo)).AsSingle();
+
+// Or, as one bind statement
+Container.Bind(typeof(Foo), typeof(IFoo)).To(typeof(Foo)).AsSingle();
 
-///////////// BindAllInterfaces
+///////////// BindInterfaces
 
 // Bind all interfaces that Foo implements to a new singleton of type Foo
-Container.BindAllInterfaces<Foo>().To<Foo>().AsSingle();
+Container.BindInterfacesTo<Foo>().AsSingle();
 
 // So for example if Foo implements ITickable and IInitializable then the above
 // line is equivalent to this:
-Container.Bind<ITickable>().To<Foo>().AsSingle();
-Container.Bind<IInitializable>().To<Foo>().AsSingle();
+Container.Bind<ITickable>().To<Foo>().AsSingle();
+Container.Bind<IInitializable>().To<Foo>().AsSingle();
 
-///////////// FromInstance
+///////////// FromInstance
 
 // Use the given instance everywhere that Foo is used
-Container.Bind<Foo>().FromInstance(new Foo());
+Container.Bind<Foo>().FromInstance(new Foo());
 
 // This is simply a shortcut for the above binding
 // This can be a bit nicer since the type argument can be deduced from the parameter
-Container.BindInstance(new Foo());
+Container.BindInstance(new Foo());
 
 // Note that FromInstance is different from AsSingle because it does allow multiple bindings
 // and you can't re-use the same instance in multiple bindings like you can with AsSingle
 // For example, the following is allowed and will match any constructor parameters of type List<Foo>
 // (and throw an exception for parameters that ask for a single Foo)
-Container.Bind<Foo>().FromInstance(new Foo());
-Container.Bind<Foo>().FromInstance(new Foo());
+Container.Bind<Foo>().FromInstance(new Foo());
+Container.Bind<Foo>().FromInstance(new Foo());
 
-///////////// Binding primitive types
+///////////// Binding primitive types
 
 // Use the number 10 every time an int is requested
 // You'd never really want to do this, you should almost always use a When condition for primitive values (see conditions section below)
-Container.Bind<int>().FromInstance(10);
-Container.Bind<bool>().FromInstance(false);
+Container.Bind<int>().FromInstance(10);
+Container.Bind<bool>().FromInstance(false);
 
 // These are the same as above
 // This can be a bit nicer though since the type argument can be deduced from the parameter
 // Again though, be careful to use conditions to limit the scope of usage for values
 // or consider using a Settings object as described above
-Container.BindInstance(10);
-Container.BindInstance(false);
+Container.BindInstance(10);
+Container.BindInstance(false);
 
-///////////// FromMethod
+///////////// FromMethod
 
 // Create instance of Foo when requested, using the given method
 // Note that for more complex construction scenarios, you might consider using a factory
 // instead
-Container.Bind<Foo>().FromMethod(GetFoo);
+Container.Bind<Foo>().FromMethod(GetFoo);
 
-Foo GetFoo(InjectContext ctx)
+Foo GetFoo(InjectContext ctx)
 {
-    return new Foo();
+    return new Foo();
 }
 
 // Randomly return one of several different implementations of IFoo
 // We use Instantiate here instead of just new so that Foo1 gets its members injected
-Container.Bind<IFoo>().FromMethod(GetFoo);
+Container.Bind<IFoo>().FromMethod(GetFoo);
 
-IFoo GetFoo(InjectContext ctx)
+IFoo GetFoo(InjectContext ctx)
 {
     switch (UnityEngine.Random.Range(0, 3))
     {
@@ -161,45 +157,45 @@ 

} // Using lambda syntax -Container.Bind<Foo>().FromMethod((ctx) => new Foo()); +Container.Bind<Foo>().FromMethod((ctx) => new Foo()); // This is equivalent to AsTransient -Container.Bind<Foo>().FromMethod((ctx) => ctx.Container.Instantiate<Foo>()); +Container.Bind<Foo>().FromMethod((ctx) => ctx.Container.Instantiate<Foo>()); -///////////// FromResolveGetter +///////////// FromResolveGetter // Bind to a property on another dependency // This can be helpful to reduce coupling between classes -Container.Bind<Foo>().AsSingle(); +Container.Bind<Foo>().AsSingle(); -Container.Bind<Bar>().FromResolveGetter<Foo>(foo => foo.GetBar()); +Container.Bind<Bar>().FromResolveGetter<Foo>(foo => foo.GetBar()); // Another example using values -Container.Bind<string>().FromResolveGetter<Foo>(foo => foo.GetTitle()); +Container.Bind<string>().FromResolveGetter<Foo>(foo => foo.GetTitle()); -///////////// FromGameObject (singleton) +///////////// FromNewComponentOnNewGameObject (singleton) // Create a new game object at the root of the scene, add the Foo MonoBehaviour to it, and name it "Foo" -Container.Bind<Foo>().FromGameObject().AsSingle(); +Container.Bind<Foo>().FromNewComponentOnNewGameObject().AsSingle(); // You can also specify the game object name to use using WithGameObjectName -Container.Bind<Foo>().FromGameObject().WithGameObjectName("Foo1").AsSingle(); +Container.Bind<Foo>().FromNewComponentOnNewGameObject().WithGameObjectName("Foo1").AsSingle(); // Bind to an interface instead -Container.Bind<IFoo>().To<Foo>().FromGameObject().AsSingle(); +Container.Bind<IFoo>().To<Foo>().FromNewComponentOnNewGameObject().AsSingle(); -///////////// FromPrefab (singleton) +///////////// FromComponentInNewPrefab (singleton) // Create a new game object at the root of the scene using the given prefab // It is assumed that the Foo is a MonoBehaviour here and that Foo has been // previously added to the prefab // After zenject creates a new GameObject from the given prefab, it will // search the prefab for a component of type 'Foo' and return that -GameObject fooPrefab; -Container.Bind<Foo>().FromPrefab(fooPrefab).AsSingle(); +GameObject fooPrefab; +Container.Bind<Foo>().FromComponentInNewPrefab(fooPrefab).AsSingle(); // Bind to interface instead -Container.Bind<IFoo>().To<Foo>().FromPrefab(fooPrefab).AsSingle(); +Container.Bind<IFoo>().To<Foo>().FromComponentInNewPrefab(fooPrefab).AsSingle(); // In this example we use AsSingle but with different components // Note here that only one instance of the given prefab will be @@ -207,54 +203,54 @@

// the type that is being returned from the prefab. // For this to work, there must be both a Foo MonoBehaviour and // a Bar MonoBehaviour somewhere on the prefab -GameObject prefab; -Container.Bind<Foo>().FromPrefab(prefab).AsSingle(); -Container.Bind<Bar>().FromPrefab(prefab).AsSingle(); +GameObject prefab; +Container.Bind<Foo>().FromComponentInNewPrefab(prefab).AsSingle(); +Container.Bind<Bar>().FromComponentInNewPrefab(prefab).AsSingle(); -///////////// FromPrefab (Transient) +///////////// FromComponentInNewPrefab (Transient) // Instantiate a new copy of 'fooPrefab' every time an instance of Foo is // requested by a constructor parameter, injected field, etc. -GameObject fooPrefab = null; -Container.Bind<Foo>().FromPrefab(fooPrefab); +GameObject fooPrefab = null; +Container.Bind<Foo>().FromComponentInNewPrefab(fooPrefab); // Again, this is equivalent since AsTransient is the default -Container.Bind<Foo>().FromPrefab(fooPrefab).AsTransient(); +Container.Bind<Foo>().FromComponentInNewPrefab(fooPrefab).AsTransient(); // Bind to interface instead -Container.Bind<IFoo>().To<Foo>().FromPrefab(fooPrefab); +Container.Bind<IFoo>().To<Foo>().FromComponentInNewPrefab(fooPrefab); -///////////// Identifiers +///////////// Identifiers // Bind a globally accessible string with the name 'PlayerName' // Note however that a better option might be to create a Settings object and bind // that instead -Container.Bind<string>().WithId("PlayerName").FromInstance("name of the player"); +Container.Bind<string>().WithId("PlayerName").FromInstance("name of the player"); // This is the equivalent of the line above, and is a bit more readable -Container.BindInstance("name of the player").WithId("PlayerName"); +Container.BindInstance("name of the player").WithId("PlayerName"); // We can also use IDs to bind multiple instances of the same type: -Container.Bind<string>().WithId("FooA").FromInstance("foo"); -Container.Bind<string>().WithId("FooB").FromInstance("asdf"); +Container.Bind<string>().WithId("FooA").FromInstance("foo"); +Container.Bind<string>().WithId("FooB").FromInstance("asdf"); // Then when we inject these dependencies we have to use the same ID: public class Norf { [Inject(Id = "FooA")] - string _foo; + string _foo; } public class Qux { [Inject(Id = "FooB")] - string _foo; + string _foo; } // In this example, we bind three instances of Foo, including one without an ID -Container.Bind<Foo>().AsCached(); -Container.Bind<Foo>().WithId("FooA").AsCached(); -Container.Bind<Foo>().WithId("FooA").AsCached(); +Container.Bind<Foo>().AsCached(); +Container.Bind<Foo>().WithId("FooA").AsCached(); +Container.Bind<Foo>().WithId("FooA").AsCached(); // When an ID is unspecified in an [Inject] field, it will use the first // instance @@ -263,7 +259,7 @@

public class Norf { [Inject] - Foo _foo; + Foo _foo; } // Qux._foo will be the same instance as Norf._foo @@ -273,84 +269,84 @@

public class Qux { [Inject] - Foo _foo; + Foo _foo; [Inject(Id = "FooA")] - Foo _foo2; + Foo _foo2; } -///////////// Conditions +///////////// Conditions // This will only allow Bar to depend on Foo // If we add Foo to the constructor of any other class it won't find it -Container.Bind<Foo>().AsSingle().WhenInjectedInto<Bar>(); +Container.Bind<Foo>().AsSingle().WhenInjectedInto<Bar>(); // Use different implementations of IFoo dependending on which // class is being injected -Container.Bind<IFoo>().To<Foo1>().AsSingle().WhenInjectedInto<Bar>(); -Container.Bind<IFoo>().To<Foo2>().AsSingle().WhenInjectedInto<Qux>(); +Container.Bind<IFoo>().To<Foo1>().AsSingle().WhenInjectedInto<Bar>(); +Container.Bind<IFoo>().To<Foo2>().AsSingle().WhenInjectedInto<Qux>(); // Use "Foo1" as the default implementation except when injecting into // class Qux, in which case use Foo2 -Container.Bind<IFoo>().To<Foo1>().AsSingle(); -Container.Bind<IFoo>().To<Foo2>().AsSingle().WhenInjectedInto<Qux>(); +Container.Bind<IFoo>().To<Foo1>().AsSingle(); +Container.Bind<IFoo>().To<Foo2>().AsSingle().WhenInjectedInto<Qux>(); // Allow depending on Foo in only a few select classes -Container.Bind<Foo>().AsSingle().WhenInjectedInto(typeof(Bar), typeof(Qux), typeof(Baz)); +Container.Bind<Foo>().AsSingle().WhenInjectedInto(typeof(Bar), typeof(Qux), typeof(Baz)); // Supply "my game" for any strings that are injected into the Gui class with the identifier "Title" -Container.BindInstance("my game").WithId("Title").WhenInjectedInto<Gui>(); +Container.BindInstance("my game").WithId("Title").WhenInjectedInto<Gui>(); // Supply 5 for all ints that are injected into the Gui class -Container.BindInstance(5).WhenInjectedInto<Gui>(); +Container.BindInstance(5).WhenInjectedInto<Gui>(); // Supply 5 for all ints that are injected into a parameter or field // inside type Gui that is named 'width' // This is usually not a good idea since the name of a field can change // easily and break the binding but shown here as an example :) -Container.BindInstance(5.0f).When(ctx => - ctx.ObjectType == typeof(Gui) && ctx.MemberName == "width"); +Container.BindInstance(5.0f).When(ctx => + ctx.ObjectType == typeof(Gui) && ctx.MemberName == "width"); // Create a new 'Foo' for every class that is created as part of the // construction of the 'Bar' class // So if Bar has a constructor parameter of type Qux, and Qux has // a constructor parameter of type IFoo, a new Foo will be created // for that case -Container.Bind<IFoo>().To<Foo>().AsTransient().When( - ctx => ctx.AllObjectTypes.Contains(typeof(Bar))); +Container.Bind<IFoo>().To<Foo>().AsTransient().When( + ctx => ctx.AllObjectTypes.Contains(typeof(Bar))); -///////////// Complex conditions example +///////////// Complex conditions example -var foo1 = new Foo(); -var foo2 = new Foo(); +var foo1 = new Foo(); +var foo2 = new Foo(); -Container.Bind<Bar>().WithId("Bar1").AsTransient(); -Container.Bind<Bar>().WithId("Bar2").AsTransient(); +Container.Bind<Bar>().WithId("Bar1").AsTransient(); +Container.Bind<Bar>().WithId("Bar2").AsTransient(); // Here we use the 'ParentContexts' property of inject context to sync multiple corresponding identifiers -Container.BindInstance(foo1).When(c => c.ParentContexts.Where(x => x.MemberType == typeof(Bar) && x.Identifier == "Bar1").Any()); -Container.BindInstance(foo2).When(c => c.ParentContexts.Where(x => x.MemberType == typeof(Bar) && x.Identifier == "Bar2").Any()); +Container.BindInstance(foo1).When(c => c.ParentContexts.Where(x => x.MemberType == typeof(Bar) && x.Identifier == "Bar1").Any()); +Container.BindInstance(foo2).When(c => c.ParentContexts.Where(x => x.MemberType == typeof(Bar) && x.Identifier == "Bar2").Any()); // This results in: // Container.Resolve<Bar>("Bar1").Foo == foo1 // Container.Resolve<Bar>("Bar2").Foo == foo2 -///////////// FromResolve +///////////// FromResolve // This will result in IBar, IFoo, and Foo, all being bound to the same instance of // Foo which is assume to exist somewhere on the given prefab -GameObject fooPrefab; -Container.Bind<Foo>().FromPrefab(fooPrefab).AsSingle(); -Container.Bind<IBar>().To<Foo>().FromResolve(); -Container.Bind<IFoo>().To<IBar>().FromResolve(); +GameObject fooPrefab; +Container.Bind<Foo>().FromComponentInNewPrefab(fooPrefab).AsSingle(); +Container.Bind<IBar>().To<Foo>().FromResolve(); +Container.Bind<IFoo>().To<IBar>().FromResolve(); // This will result in the same behaviour as the above -GameObject fooPrefab = null; -Container.Bind<Foo>().FromPrefab(fooPrefab).AsSingle(); -Container.Bind<IBar>().To<Foo>().FromPrefab(fooPrefab).AsSingle(); -Container.Bind<IFoo>().To<Foo>().FromPrefab(fooPrefab).AsSingle(); +GameObject fooPrefab = null; +Container.Bind<Foo>().FromComponentInNewPrefab(fooPrefab).AsSingle(); +Container.Bind<IBar>().To<Foo>().FromComponentInNewPrefab(fooPrefab).AsSingle(); +Container.Bind<IFoo>().To<Foo>().FromComponentInNewPrefab(fooPrefab).AsSingle(); -///////////// Rebind +///////////// Rebind // Rebind can be used to override previous bindings // This will result in IFoo being bound to only Bar @@ -358,59 +354,59 @@

// Normally the order that the bindings occur in doesn't // matter at all, but Rebind does create an order-dependency // so use with caution -Container.Bind<IFoo>().To<Foo>().AsSingle(); -Container.Rebind<IFoo>().To<Bar>().AsSingle(); +Container.Bind<IFoo>().To<Foo>().AsSingle(); +Container.Rebind<IFoo>().To<Bar>().AsSingle(); -///////////// Installing Other Installers +///////////// Installing Other Installers // Immediately call InstallBindings() on FooInstaller -FooInstaller.Install(Container); +FooInstaller.Install(Container); // Before calling FooInstaller, configure a property of it -Container.BindInstance("foo").WhenInjectedInto<FooInstaller>(); -FooInstaller.Install(Container); +Container.BindInstance("foo").WhenInjectedInto<FooInstaller>(); +FooInstaller.Install(Container); // We can also pass arguments directly // This line is equivalent to the above two lines -FooInstaller.Install(Container, new object[] { "foo" }); +FooInstaller.Install(Container, new object[] { "foo" }); // After calling FooInstaller, override one of its bindings // We assume here that FooInstaller binds IFoo to something -FooInstaller.Install(Container); -Container.Rebind<IFoo>().To<Bar>().AsSingle(); +FooInstaller.Install(Container); +Container.Rebind<IFoo>().To<Bar>().AsSingle(); -///////////// Manual Use of Container +///////////// Manual Use of Container // This will fill in any parameters marked as [Inject] and also call any [Inject] methods -var foo = new Foo(); -Container.Inject(foo); +var foo = new Foo(); +Container.Inject(foo); // Return an instance for IFoo, using the bindings that have been added previously // Internally it is what is triggered when you fill in a constructor parameter of type IFoo // Note: It will throw an exception if it cannot find a match -Container.Resolve<IFoo>(); +Container.Resolve<IFoo>(); // Same as the above except returns null when it can't find the given type -Container.TryResolve<IFoo>(); +Container.TryResolve<IFoo>(); // Return a list of 2 instances of type Foo -Container.BindInstance(new Foo()); -Container.BindInstance(new Foo()); -var foos = Container.ResolveAll<IFoo>(); +Container.BindInstance(new Foo()); +Container.BindInstance(new Foo()); +var foos = Container.ResolveAll<IFoo>(); // Create a new instance of Foo and inject on any of its members // And fill in any constructor parameters Foo might have -Container.Instantiate<Foo>(); +Container.Instantiate<Foo>(); -GameObject prefab = null; +GameObject prefab = null; // Instantiate a new prefab and have any injectables filled in on the prefab -GameObject go = Container.InstantiatePrefab(prefab); +GameObject go = Container.InstantiatePrefab(prefab); // Instantiate a new prefab and return a specific monobehaviour -Foo foo2 = Container.InstantiatePrefabForComponent<Foo>(prefab); +Foo foo2 = Container.InstantiatePrefabForComponent<Foo>(prefab); // Add a new component to an existing game object -Foo foo3 = Container.InstantiateComponent<Foo>(gameObject); +Foo foo3 = Container.InstantiateComponent<Foo>(gameObject);

diff --git a/UnityProject/Assets/Zenject/Documentation/Factories.html b/UnityProject/Assets/Zenject/Documentation/Factories.html index 9df1fa665..ad5f192df 100644 --- a/UnityProject/Assets/Zenject/Documentation/Factories.html +++ b/UnityProject/Assets/Zenject/Documentation/Factories.html @@ -58,9 +58,9 @@

public class Enemy
 {
-    DiContainer Container;
+    DiContainer Container;
 
-    public Enemy(DiContainer container)
+    public Enemy(DiContainer container)
     {
         Container = container;
     }
@@ -68,7 +68,7 @@ 

public void Update() { ... - var player = Container.Resolve<Player>(); + var player = Container.Resolve<Player>(); WalkTowards(player.Position); ... etc. @@ -81,9 +81,9 @@

public class Enemy
 {
-    Player _player;
+    Player _player;
 
-    public Enemy(Player player)
+    public Enemy(Player player)
     {
         _player = player;
     }
@@ -102,19 +102,19 @@ 

public class EnemySpawner
 {
-    List<Enemy> _enemies = new List<Enemy>();
+    List<Enemy> _enemies = new List<Enemy>();
 
     public void Update()
     {
         if (ShouldSpawnNewEnemy())
         {
-            var enemy = new Enemy();
+            var enemy = new Enemy();
             _enemies.Add(enemy);
         }
     }
 }
-

This will not work however, since in our case the Enemy class requires a reference to the Player class in its constructor. We could add a dependency to the Player class to the EnemySpawner class, but then we have the problem described above. The EnemySpawner class doesn't care about filling in the dependencies for the Enemy class. All the EnemySpawner class cares about is getting a new Enemy instance.

+

This will not work however, since in our case the Enemy class requires a reference to the Player class in its constructor. We could add a dependency to the Player class to the EnemySpawner class, but then we have the problem described above. The EnemySpawner class doesn't care about filling in the dependencies for the Enemy class. All the EnemySpawner class cares about is getting a new Enemy instance.

The recommended way to do this in Zenject is the following:

@@ -124,23 +124,23 @@

public class Enemy { - readonly Player _player; + readonly Player _player; - public Enemy(Player player) + public Enemy(Player player) { _player = player; } - public class Factory : Factory<Enemy> + public class Factory : Factory<Enemy> { } } -public class EnemySpawner : ITickable +public class EnemySpawner : ITickable { - readonly Enemy.Factory _enemyFactory; + readonly Enemy.Factory _enemyFactory; - public EnemySpawner(Enemy.Factory enemyFactory) + public EnemySpawner(Enemy.Factory enemyFactory) { _enemyFactory = enemyFactory; } @@ -149,17 +149,17 @@

{ if (ShouldSpawnNewEnemy()) { - var enemy = _enemyFactory.Create(); + var enemy = _enemyFactory.Create(); // ... } } } -public class TestInstaller : MonoInstaller +public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces<EnemySpawner>().To<EnemySpawner>().AsSingle(); + Container.BindInterfacesTo<EnemySpawner>().AsSingle(); Container.Bind<Player>().AsSingle(); Container.BindFactory<Enemy, Enemy.Factory>(); } @@ -169,25 +169,25 @@

public class Enemy
 {
-    readonly Player _player;
-    readonly float _speed;
+    readonly Player _player;
+    readonly float _speed;
 
-    public Enemy(float speed, Player player)
+    public Enemy(float speed, Player player)
     {
         _player = player;
         _speed = speed;
     }
 
-    public class Factory : Factory<float, Enemy>
+    public class Factory : Factory<float, Enemy>
     {
     }
 }
 
-public class EnemySpawner : ITickable
+public class EnemySpawner : ITickable
 {
-    readonly Enemy.Factory _enemyFactory;
+    readonly Enemy.Factory _enemyFactory;
 
-    public EnemySpawner(Enemy.Factory enemyFactory)
+    public EnemySpawner(Enemy.Factory enemyFactory)
     {
         _enemyFactory = enemyFactory;
     }
@@ -196,18 +196,18 @@ 

{ if (ShouldSpawnNewEnemy()) { - var newSpeed = Random.Range(MIN_ENEMY_SPEED, MAX_ENEMY_SPEED); - var enemy = _enemyFactory.Create(newSpeed); + var newSpeed = Random.Range(MIN_ENEMY_SPEED, MAX_ENEMY_SPEED); + var enemy = _enemyFactory.Create(newSpeed); // ... } } } -public class TestInstaller : MonoInstaller +public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces<EnemySpawner>().To<EnemySpawner>().AsSingle(); + Container.BindInterfacesTo<EnemySpawner>().AsSingle(); Container.Bind<Player>().AsSingle(); Container.BindFactory<float, Enemy, Enemy.Factory>(); } @@ -225,31 +225,31 @@

These cases are handled very similar to how they are handled when not using a factory. When you bind the factory to the container using BindFactory, you have access to the same bind methods that are given by the Bind method (see binding section for full details). For example, if we wanted to instantiate the Enemy class from a prefab, our code would become:

-
public class Enemy : MonoBehaviour
+
public class Enemy : MonoBehaviour
 {
-    Player _player;
+    Player _player;
 
     // Note that we can't use a constructor anymore since we are a MonoBehaviour now
     [Inject]
-    public void Construct(Player player)
+    public void Construct(Player player)
     {
         _player = player;
     }
 
-    public class Factory : Factory<Enemy>
+    public class Factory : Factory<Enemy>
     {
     }
 }
 
-public class TestInstaller : MonoInstaller
+public class TestInstaller : MonoInstaller
 {
-    public GameObject EnemyPrefab;
+    public GameObject EnemyPrefab;
 
     public override void InstallBindings()
     {
-        Container.BindAllInterfaces<EnemySpawner>().To<EnemySpawner>().AsSingle();
+        Container.BindInterfacesTo<EnemySpawner>().AsSingle();
         Container.Bind<Player>().AsSingle();
-        Container.BindFactory<Enemy, Enemy.Factory>().FromPrefab(EnemyPrefab);
+        Container.BindFactory<Enemy, Enemy.Factory>().FromComponentInNewPrefab(EnemyPrefab);
     }
 }
 
@@ -271,12 +271,12 @@

... } -public class AStarPathFindingStrategy : IPathFindingStrategy +public class AStarPathFindingStrategy : IPathFindingStrategy { ... } -public class RandomPathFindingStrategy : IPathFindingStrategy +public class RandomPathFindingStrategy : IPathFindingStrategy { ... }

@@ -285,16 +285,16 @@

This is done in a very similar way that non-Abstract factories work. One difference is that we can't include the factory as a nested class inside the interface (not allowed in C#) but otherwise it's no different:

-
public class PathFindingStrategyFactory : Factory<IPathFindingStrategy>
+
public class PathFindingStrategyFactory : Factory<IPathFindingStrategy>
 {
 }
 
-public class GameController : IInitializable
+public class GameController : IInitializable
 {
-    PathFindingStrategyFactory _strategyFactory;
-    IPathFindingStrategy _strategy;
+    PathFindingStrategyFactory _strategyFactory;
+    IPathFindingStrategy _strategy;
 
-    public GameController(PathFindingStrategyFactory strategyFactory)
+    public GameController(PathFindingStrategyFactory strategyFactory)
     {
         _strategyFactory = strategyFactory;
     }
@@ -306,15 +306,15 @@ 

} } -public class GameInstaller : MonoInstaller +public class GameInstaller : MonoInstaller { - public bool UseAStar; + public bool UseAStar; public override void InstallBindings() { - Container.BindAllInterfaces<GameController>().To<GameController>().AsSingle(); + Container.BindInterfacesTo<GameController>().AsSingle(); - if (UseAStar) + if (UseAStar) { Container.BindFactory<IPathFindingStrategy, PathFindingStrategyFactory>().To<AStarPathFindingStrategy>(); } @@ -330,51 +330,51 @@

Ok, but what if I don't know what type I want to create until after the application has started? Or what if I have special requirements for constructing instances of the Enemy class that are not covered by any of the construction methods?

-

In these cases you can create a custom factory, and directly call new Enemy or directly use the DiContainer class to create your object. For example, continuing the previous factory example, let's say that you wanted to be able to change a runtime value (difficulty) that determines what kinds of enemies get created.

+

In these cases you can create a custom factory, and directly call new Enemy or directly use the methods on DiContainer to create your object. For example, continuing the previous factory example, let's say that you wanted to be able to change a runtime value (difficulty) that determines what kinds of enemies get created.

-
public enum Difficulties
+
public enum Difficulties
 {
-    Easy,
-    Hard,
+    Easy,
+    Hard,
 }
 
 public interface IEnemy
 {
 }
 
-public class EnemyFactory : Factory<IEnemy>
+public class EnemyFactory : Factory<IEnemy>
 {
 }
 
-public class Demon : IEnemy
+public class Demon : IEnemy
 {
 }
 
-public class Dog : IEnemy
+public class Dog : IEnemy
 {
 }
 
 public class DifficultyManager
 {
-    public Difficulties Difficulty
+    public Difficulties Difficulty
     {
         get;
         set;
     }
 }
 
-public class CustomEnemyFactory : IFactory<IEnemy>
+public class CustomEnemyFactory : IFactory<IEnemy>
 {
-    DiContainer _container;
-    DifficultyManager _difficultyManager;
+    DiContainer _container;
+    DifficultyManager _difficultyManager;
 
-    public CustomEnemyFactory(DiContainer container, DifficultyManager difficultyManager)
+    public CustomEnemyFactory(DiContainer container, DifficultyManager difficultyManager)
     {
         _container = container;
         _difficultyManager = difficultyManager;
     }
 
-    public IEnemy Create()
+    public IEnemy Create()
     {
         if (_difficultyManager.Difficulty == Difficulties.Hard)
         {
@@ -385,27 +385,27 @@ 

} } -public class GameController : IInitializable +public class GameController : IInitializable { - readonly EnemyFactory _enemyFactory; + readonly EnemyFactory _enemyFactory; - public GameController(EnemyFactory enemyFactory) + public GameController(EnemyFactory enemyFactory) { _enemyFactory = enemyFactory; } public void Initialize() { - var enemy = _enemyFactory.Create(); + var enemy = _enemyFactory.Create(); // ... } } -public class TestInstaller : MonoInstaller +public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces<GameController>().To<GameController>().AsSingle(); + Container.BindInterfacesTo<GameController>().AsSingle(); Container.Bind<DifficultyManager>().AsSingle(); Container.BindFactory<IEnemy, EnemyFactory>().FromFactory<CustomEnemyFactory>(); } @@ -417,18 +417,18 @@

If you want to properly validate your custom factories, you can do that by just making a small modification to it:

-
public class CustomEnemyFactory : IFactory<IEnemy>, IValidatable
+
public class CustomEnemyFactory : IFactory<IEnemy>, IValidatable
 {
-    DiContainer _container;
-    DifficultyManager _difficultyManager;
+    DiContainer _container;
+    DifficultyManager _difficultyManager;
 
-    public CustomEnemyFactory(DiContainer container, DifficultyManager difficultyManager)
+    public CustomEnemyFactory(DiContainer container, DifficultyManager difficultyManager)
     {
         _container = container;
         _difficultyManager = difficultyManager;
     }
 
-    public IEnemy Create()
+    public IEnemy Create()
     {
         if (_difficultyManager.Difficulty == Difficulties.Hard)
         {
diff --git a/UnityProject/Assets/Zenject/Documentation/MemoryPools.html b/UnityProject/Assets/Zenject/Documentation/MemoryPools.html
new file mode 100644
index 000000000..1c3efce5b
--- /dev/null
+++ b/UnityProject/Assets/Zenject/Documentation/MemoryPools.html
@@ -0,0 +1,615 @@
+
+
+
+  
+  MemoryPools.md - Grip
+  
+  
+  
+  
+
+
+  
+
+ + + +
+
+
+
+ +

+ + MemoryPools.md +

+ +
+

+Memory Pools

+ +

+Introduction

+ +

Before understanding memory pools it would be helpful to understand factories, so please read the docs on factories first.

+ +

It doesn't take long when developing games in Unity before you realize that proper memory management is very important if you want your game to run smoothly (especially on mobile). Depending on the constraints of the platform and the type of game you are working on, it might be very important to avoid unnecessary heap allocations as much as possible. One very effective way to do this is to use memory pools.

+ +

As an example let's look at at a case where we are dynamically creating a class:

+ +
public class Foo
+{
+    public class Factory : Factory<Foo>
+    {
+    }
+}
+
+public class Bar
+{
+    readonly Foo.Factory _fooFactory;
+    readonly List<Foo> _foos = new List<Foo>();
+
+    public Bar(Foo.Factory fooFactory)
+    {
+        _fooFactory = fooFactory;
+    }
+
+    public void AddFoo()
+    {
+        _foos.Add(_fooFactory.Create());
+    }
+
+    public void RemoveFoo()
+    {
+        _foos.RemoveAt(0);
+    }
+}
+
+public class TestInstaller : MonoInstaller<TestInstaller>
+{
+    public override void InstallBindings()
+    {
+        Container.Bind<Bar>().AsSingle();
+        Container.BindFactory<Foo, Foo.Factory>();
+    }
+}
+ +

Here, every time we call Bar.AddFoo it will always allocate new heap memory. And every time we call Bar.RemoveFoo, the Bar class will stop referencing one of the instances of Foo, and therefore the memory for that instance will be marked for garbage collection. If this happens enough times, then eventually the garbage collector will kick in and you will get a (sometimes very noticeable) spike in your game.

+ +

We can fix this spike by using memory pools instead:

+ +
public class Foo
+{
+    public class Pool : MemoryPool<Foo>
+    {
+    }
+}
+
+public class Bar
+{
+    readonly Foo.Pool _fooPool;
+    readonly List<Foo> _foos = new List<Foo>();
+
+    public Bar(Foo.Pool fooPool)
+    {
+        _fooPool = fooPool;
+    }
+
+    public void AddFoo()
+    {
+        _foos.Add(_fooPool.Spawn());
+    }
+
+    public void RemoveFoo()
+    {
+        var foo = _foos[0];
+        _fooPool.Despawn(foo);
+        _foos.Remove(foo);
+    }
+}
+
+public class TestInstaller : MonoInstaller<TestInstaller>
+{
+    public override void InstallBindings()
+    {
+        Container.Bind<Bar>().AsSingle();
+        Container.BindMemoryPool<Foo, Foo.Pool>();
+    }
+}
+ +

As you can see, this works very similarly to factories, except that the terminology is a bit different (Pool instead of Factory, Spawn instead of Create) and unlike factories, you have to return the instance to the pool rather than just stop referencing it.

+ +

With this new implementation above, there will be some initial heap allocation with every call to AddFoo(), but if you call RemoveFoo() then AddFoo() in sequence this will re-use the previous instance and therefore save you a heap allocation.

+ +

This is better, but we might still want to avoid the spikes from the initial heap allocations as well. One way to do this is to do all the heap allocations all at once as your game is starting up:

+ +
public class TestInstaller : MonoInstaller<TestInstaller>
+{
+    public override void InstallBindings()
+    {
+        Container.Bind<Bar>().AsSingle();
+        Container.BindMemoryPool<Foo, Foo.Pool>().WithInitialSize(10);
+    }
+}
+ +

When we use WithInitialSize like this in the Bind statement for our pool, 10 instances of Foo will be created immediately on startup to seed the pool.

+ +

+Syntax

+ +

The syntax for memory pools are almost identical to factories. The recommended convention is to use a public nested class named Pool (though this is just a convention).

+ +
public class Foo
+{
+    public class Pool : MemoryPool<Foo>
+    {
+    }
+}
+ +

Parameters are added by adding generic arguments:

+ +
public class Foo
+{
+    public class Pool : MemoryPool<string, int, Foo>
+    {
+    }
+}
+ +

The full format of the binding is the following:

+ +
+Container.BindMemoryPool<Param1Type, Param2Type, etc..., ObjectType, MemoryPoolType>()
+    .With(InitialSize|FixedSize)()
+    .ExpandBy(OneAtATime|Doubling)()
+    .To<ResultType>()
+    .WithId(Identifier)
+    .FromConstructionMethod()
+    .WithArguments(Arguments)
+    .When(Condition)
+    .CopyIntoAllSubContainers()
+    .NonLazy();
+
+ +

Where:

+ +
    +
  • +

    With = Determines the number of instances that the pool is seeded with. When not specified, the pool starts with zero instances. The options are:

    + +
      +
    • WithInitializeSize(x) - Create x instances immediately when the pool is created. The pool is also allowed to grow as necessary if it exceeds that amount
    • +
    • WithFixedSize(x) - Create x instances immediately when the pool is created. If the pool size is exceeded then an exception is thrown.
    • +
    +
  • +
  • +

    ExpandBy = Determines the behaviour to invoke when the pool reaches its maximum size. Note that when specifying WithFixedSize, this option is not available. The options are:

    + +
      +
    • ExpandByOneAtATime - Only allocate new instances one at a time as necessary
    • +
    • ExpandByDoubling - When the pool is full and a new instance is requested, the pool will double in size before returning the requested instance. This approach can be useful if you prefer having large infrequent allocations to many small frequent allocations
    • +
    +
  • +
+ +

The rest of the bind methods behave the same as the normal bind methods documented here

+ +

+Resetting

+ +

One very important thing to be aware of when using memory pools instead of factories is that you must make sure to completely "refresh" the given instance. This is necessary otherwise you might have state a previous "life" of the instance bleeding in to the behaviour of the new instance.

+ +

You can refresh the object by implementing any of the following methods in your memory pool derived class:

+ +
public class Foo
+{
+    public class Pool : MemoryPool<Foo>
+    {
+        protected override void OnCreated(Foo item)
+        {
+            // Called immediately after the item is first added to the pool
+        }
+
+        protected override void OnSpawned(Foo item)
+        {
+            // Called immediately after the item is removed from the pool
+        }
+
+        protected override void OnDespawned(Foo item)
+        {
+            // Called immediately after the item is returned to the pool
+        }
+
+        protected override void Reinitialize(Foo foo)
+        {
+            // Similar to OnSpawned
+            // Called immediately after the item is removed from the pool
+            // This method will also contain any parameters that are passed along
+            // to the memory pool from the spawning code
+        }
+    }
+}
+ +

In most cases, you will probably only have to implement the Reinitialize method. For example, let's introduce some state to our first example by adding a Position value to Foo:

+ +
public class Foo
+{
+    Vector3 _position = Vector3.zero;
+
+    public void Move(Vector3 delta)
+    {
+        _position += delta;
+    }
+
+    public class Pool : MemoryPool<Foo>
+    {
+        protected override void Reinitialize(Foo foo)
+        {
+            foo._position = Vector3.zero;
+        }
+    }
+}
+ +

Note that our pool class is free to access private variables inside Foo because of the fact that it is a nested class.

+ +

Or, if we wanted to avoid the duplication in Foo and Foo.Pool, we could do it this way:

+ +
public class Foo
+{
+    Vector3 _position;
+
+    public Foo()
+    {
+        Reset();
+    }
+
+    public void Move(Vector3 delta)
+    {
+        _position += delta;
+    }
+
+    void Reset()
+    {
+        _position = Vector3.zero;
+    }
+
+    public class Pool : MemoryPool<Foo>
+    {
+        protected override void Reinitialize(Foo foo)
+        {
+            foo.Reset();
+        }
+    }
+}
+ +

+Parameters

+ +

Just like Factories, you can also pass runtime parameters when spawning new instances of your pooled classes. The difference is, instead of the parameters being injected into the class, they are passed to the Reinitialize method:

+ +
public class Foo
+{
+    Vector3 _position;
+    Vector3 _velocity;
+
+    public Foo()
+    {
+        Reset();
+    }
+
+    public void Tick()
+    {
+        _position += _velocity * Time.deltaTime;
+    }
+
+    void Reset()
+    {
+        _position = Vector3.zero;
+        _velocity = Vector3.zero;
+    }
+
+    public class Pool : MemoryPool<Vector3, Foo>
+    {
+        protected override void Reinitialize(Vector3 velocity, Foo foo)
+        {
+            foo.Reset();
+            foo._velocity = velocity;
+        }
+    }
+}
+
+public class Bar
+{
+    readonly Foo.Pool _fooPool;
+    readonly List<Foo> _foos = new List<Foo>();
+
+    public Bar(Foo.Pool fooPool)
+    {
+        _fooPool = fooPool;
+    }
+
+    public void AddFoo()
+    {
+        float maxSpeed = 10.0f;
+        float minSpeed = 1.0f;
+
+        _foos.Add(_fooPool.Spawn(
+            Random.onUnitSphere * Random.Range(minSpeed, maxSpeed)));
+    }
+
+    public void RemoveFoo()
+    {
+        var foo = _foos[0];
+        _fooPool.Despawn(foo);
+        _foos.Remove(foo);
+    }
+}
+ +

+Memory Pools for MonoBehaviours

+ +

Memory pools for GameObjects works similarly. For example:

+ +
public class Foo : MonoBehaviour
+{
+    Vector3 _velocity;
+
+    [Inject]
+    public void Construct()
+    {
+        Reset();
+    }
+
+    public void Update()
+    {
+        transform.position += _velocity * Time.deltaTime;
+    }
+
+    void Reset()
+    {
+        transform.position = Vector3.zero;
+        _velocity = Vector3.zero;
+    }
+
+    public class Pool : MonoMemoryPool<Vector3, Foo>
+    {
+        protected override void Reinitialize(Vector3 velocity, Foo foo)
+        {
+            foo.Reset();
+            foo._velocity = velocity;
+        }
+    }
+}
+
+public class Bar
+{
+    readonly Foo.Pool _fooPool;
+    readonly List<Foo> _foos = new List<Foo>();
+
+    public Bar(Foo.Pool fooPool)
+    {
+        _fooPool = fooPool;
+    }
+
+    public void AddFoo()
+    {
+        float maxSpeed = 10.0f;
+        float minSpeed = 1.0f;
+
+        _foos.Add(_fooPool.Spawn(
+            Random.onUnitSphere * Random.Range(minSpeed, maxSpeed)));
+    }
+
+    public void RemoveFoo()
+    {
+        var foo = _foos[0];
+        _fooPool.Despawn(foo);
+        _foos.Remove(foo);
+    }
+}
+
+public class TestInstaller : MonoInstaller<TestInstaller>
+{
+    public GameObject FooPrefab;
+
+    public override void InstallBindings()
+    {
+        Container.Bind<Bar>().AsSingle();
+
+        Container.BindMemoryPool<Foo, Foo.Pool>()
+            .WithInitialSize(2)
+            .FromComponentInNewPrefab(FooPrefab)
+            .UnderTransformGroup("Foos");
+    }
+}
+ +

The main difference here is that Foo.Pool now derives from MonoMemoryPool instead of MemoryPool. MonoMemoryPool is a helper class that will automatically enable and disable the game object for us when it is added/removed from the pool. The implementation for MonoMemoryPool is simply this:

+ +
public abstract class MonoMemoryPool<TParam1, TValue> : MemoryPool<TParam1, TValue>
+    where TValue : Component
+{
+    protected override void OnCreated(TValue item)
+    {
+        item.gameObject.SetActive(false);
+    }
+
+    protected override void OnSpawned(TValue item)
+    {
+        item.gameObject.SetActive(true);
+    }
+
+    protected override void OnDespawned(TValue item)
+    {
+        item.gameObject.SetActive(false);
+    }
+}
+ +

Therefore, if you override one of these methods you will have to make sure to call the base version as well.

+ +

Also, worth noting is the fact that for this logic to work, our MonoBehaviour must be at the root of the prefab, since otherwise only the transform associated with Foo and any children will be disabled.

+ +

+Abstract Memory Pools

+ +

Just like abstract factories, sometimes you might want to create a memory pool that returns an interface, with the concrete type decided inside an installer. This works very similarly to abstract factories. For example:

+ +
public interface IFoo
+{
+}
+
+public class Foo1 : IFoo
+{
+}
+
+public class Foo2 : IFoo
+{
+}
+
+public class FooPool : MemoryPool<IFoo>
+{
+}
+
+public class Bar
+{
+    readonly FooPool _fooPool;
+    readonly List<IFoo> _foos = new List<IFoo>();
+
+    public Bar(FooPool fooPool)
+    {
+        _fooPool = fooPool;
+    }
+
+    public void AddFoo()
+    {
+        _foos.Add(_fooPool.Spawn());
+    }
+
+    public void RemoveFoo()
+    {
+        var foo = _foos[0];
+        _fooPool.Despawn(foo);
+        _foos.Remove(foo);
+    }
+}
+
+public class TestInstaller : MonoInstaller<TestInstaller>
+{
+    public bool Use1;
+
+    public override void InstallBindings()
+    {
+        Container.Bind<Bar>().AsSingle();
+
+        if (Use1)
+        {
+            Container.BindMemoryPool<IFoo, FooPool>().WithInitialSize(10).To<Foo1>();
+        }
+        else
+        {
+            Container.BindMemoryPool<IFoo, FooPool>().WithInitialSize(10).To<Foo2>();
+        }
+    }
+}
+ +

We might also want to add a Reset() method to the IFoo interface as well here, and call that on Reinitialize()

+ +
+
+
+
+
+ + + +
+
 
+
+ + \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Documentation/MemoryPools.html.meta b/UnityProject/Assets/Zenject/Documentation/MemoryPools.html.meta new file mode 100644 index 000000000..35c70f20e --- /dev/null +++ b/UnityProject/Assets/Zenject/Documentation/MemoryPools.html.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d2b9d0ae77ceb5409b2fb56e298eb49 +timeCreated: 1487002135 +licenseType: Free +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Documentation/ReadMe.html b/UnityProject/Assets/Zenject/Documentation/ReadMe.html index 2ee481692..997247a96 100644 --- a/UnityProject/Assets/Zenject/Documentation/ReadMe.html +++ b/UnityProject/Assets/Zenject/Documentation/ReadMe.html @@ -36,18 +36,18 @@
- +
- +

README.md

- +

Zenject

@@ -109,9 +109,10 @@

  • Support for global, project-wide bindings to add dependencies for all scenes
  • Convention based binding, based on class name, namespace, or any other criteria
  • Ability to validate object graphs at editor time (including dynamic object graphs created via factories)
  • -
  • Commands and Signals
  • Automatic binding on components in the scene using the ZenjectBinding component
  • Auto-Mocking using the Moq library
  • +
  • Built-in support for memory pools
  • +
  • Just-in-time resolving using the Lazy<> construct
  • @@ -201,9 +202,10 @@

  • ITickable
  • IInitializable
  • IDisposable
  • +
  • BindInterfacesTo and BindInterfacesAndSelfTo
  • +
  • Using the Unity Inspector To Configure Settings
  • -
  • Using the Unity Inspector To Configure Settings
  • Object Graph Validation
  • Scene Bindings
  • General Guidelines / Recommendations / Gotchas / Tips and Tricks
  • @@ -225,21 +227,35 @@

  • Identifiers
  • Non Generic bindings
  • Convention Based Binding
  • -
  • Unbind / Rebind
  • Singleton Identifiers
  • Scriptable Object Installer
  • Runtime Parameters For Installers
  • Creating Objects Dynamically Using Factories
  • +
  • Memory Pools
  • Update / Initialization Order
  • Zenject Order Of Operations
  • Injecting data across scenes
  • Scene Parenting Using Contract Names
  • +
  • Just-In-Time Resolving Using Lazy<>
  • +
  • +DiContainer Methods + + +
  • Scene Decorators
  • Sub-Containers And Facades
  • Writing Automated Unit Tests / Integration Tests
  • -
  • Commands And Signals
  • +
  • Signals
  • Auto-Mocking using Moq
  • Creating Unity EditorWindow's with Zenject
  • @@ -274,11 +290,11 @@

    public class Foo
     {
    -    ISomeService _service;
    +    ISomeService _service;
     
         public Foo()
         {
    -        _service = new SomeService();
    +        _service = new SomeService();
         }
     
         public void DoSomething()
    @@ -294,9 +310,9 @@ 

    public class Foo
     {
    -    ISomeService _service;
    +    ISomeService _service;
     
    -    public Foo(ISomeService service)
    +    public Foo(ISomeService service)
         {
             _service = service;
         }
    @@ -314,7 +330,7 @@ 

    { public void DoSomething() { - var foo = new Foo(new SomeService()); + var foo = new Foo(new SomeService()); foo.DoSomething(); ... } @@ -324,16 +340,16 @@

    public class Bar
     {
    -    ISomeService _service;
    +    ISomeService _service;
     
    -    public Bar(ISomeService service)
    +    public Bar(ISomeService service)
         {
             _service = service;
         }
     
         public void DoSomething()
         {
    -        var foo = new Foo(_service);
    +        var foo = new Foo(_service);
             foo.DoSomething();
             ...
         }
    @@ -341,9 +357,10 @@ 

    So we find that it is useful to push the responsibility of deciding which specific implementations of which classes to use further and further up in the 'object graph' of the application. Taking this to an extreme, we arrive at the entry point of the application, at which point all dependencies must be satisfied before things start. The dependency injection lingo for this part of the application is called the 'composition root'. It would normally look like this:

    -
    var service = new SomeService();
    -var foo = new Foo(service);
    -var bar = new Bar(foo);
    +
    var service = new SomeService();
    +var foo = new Foo(service);
    +var bar = new Bar(service);
    +var qux = new Qux(bar);
     
     .. etc.
    @@ -377,18 +394,18 @@

    using UnityEngine; using System.Collections; -public class TestInstaller : MonoInstaller +public class TestInstaller : MonoInstaller { public override void InstallBindings() { Container.Bind<string>().FromInstance("Hello World!"); - Container.Bind<TestRunner>().NonLazy(); + Container.Bind<Greeter>().NonLazy(); } } -public class TestRunner +public class Greeter { - public TestRunner(string message) + public Greeter(string message) { Debug.Log(message); } @@ -400,7 +417,7 @@

  • Create a new scene in Unity
  • Right Click inside the Hierarchy tab and select Zenject -> Scene Context
  • -
  • Right Click in a folder within the Scene Heirarchy and Choose Create -> Zenject -> MonoInstaller. Name it TestInstaller.cs. (Note that you can also just directly create this file too without using this template).
  • +
  • Right Click in a folder within the Project Tab and Choose Create -> Zenject -> MonoInstaller. Name it TestInstaller.cs. (Note that you can also just directly create this file too without using this template).
  • Add your TestInstaller script to the scene (as its own GameObject or on the same GameObject as the SceneContext, it doesn't matter)
  • Add a reference to your TestInstaller to the properties of the SceneContext by adding a new row in the inspector of the "Installers" property (press the + button) and then dragging the TestInstaller GameObject to it
  • Open up TestInstaller and paste the above code into it
  • @@ -410,20 +427,20 @@

  • Observe unity console for output
  • -

    The SceneContext MonoBehaviour is the entry point of the application, where Zenject sets up all the various dependencies before kicking off your scene. To add content to your Zenject scene, you need to write what is referred to in Zenject as an 'Installer', which declares all the dependencies used in your scene and their relationships with each other. All dependencies that are marked as "NonLazy" are automatically created at this point, as well as any dependencies that implement the standard Zenject interfaces such as IInitializable, ITickable, etc. If the above doesn't make sense to you yet, keep reading!

    +

    The SceneContext MonoBehaviour is the entry point of the application, where Zenject sets up all the various dependencies before kicking off your scene. To add content to your Zenject scene, you need to write what is referred to in Zenject as an 'Installer', which declares all the dependencies used in your scene and their relationships with each other. All dependencies that are marked as "NonLazy" are automatically created at this point, which is why the Greeter class that we added above gets created on startup. If the above doesn't make sense to you yet, keep reading!

    Injection

    -

    There are many different ways of binding types on the container, which are documented in the next section. There are also several ways of having these dependencies injected into your classes. These are:

    +

    There are many different ways of declaring dependencies on the container, which are documented in the next section. There are also several ways of having these dependencies injected into your classes. These are:

    1 - Constructor Injection

    public class Foo
     {
    -    IBar _bar;
    +    IBar _bar;
     
    -    public Foo(IBar bar)
    +    public Foo(IBar bar)
         {
             _bar = bar;
         }
    @@ -434,7 +451,7 @@ 

    public class Foo
     {
         [Inject]
    -    IBar _bar;
    +    IBar _bar;
     }

    Field injection occurs immediately after the constructor is called. All fields that are marked with the [Inject] attribute are looked up in the container and given a value. Note that these fields can be private or public and injection will still occur.

    @@ -444,10 +461,10 @@

    public class Foo
     {
         [Inject]
    -    public IBar Bar
    +    public IBar Bar
         {
             get;
    -        private set;
    +        private set;
         }
     }
    @@ -457,11 +474,11 @@

    public class Foo
     {
    -    IBar _bar;
    -    Qux _qux;
    +    IBar _bar;
    +    Qux _qux;
     
         [Inject]
    -    public Init(IBar bar, Qux qux)
    +    public Init(IBar bar, Qux qux)
         {
             _bar = bar;
             _qux = qux;
    @@ -470,26 +487,23 @@ 

    Method Inject injection works very similarly to constructor injection.

    -

    Note that these methods are called after all other injection types. It is designed this way so that these methods can be used to execute initialization logic which might make use of one of these dependencies. Note also that you can leave the parameter list empty if you just want to do some initialization logic only.

    +

    Note that inject methods are called after all other injection types. It is designed this way so that these methods can be used to execute initialization logic which might make use of one of these dependencies. Note also that you can leave the parameter list empty if you just want to do some initialization logic only.

    Note that there can be any number of inject methods. In this case, they are called in the order of Base class to Derived class. This can be useful to avoid the need to forward many dependencies from derived classes to the base class via constructor parameters, while also guaranteeing that the base class inject methods complete first, just like how constructors work.

    -

    Note that the dependencies that you receive via inject methods should themselves have already been injected. This can be important if you use inject methods to perform some basic initialization, since you may need the given dependencies to themselves be initialized via their Inject methods.

    +

    Note that the dependencies that you receive via inject methods should themselves have already been injected (the only exception to this is in the case where you have circular dependencies). This can be important if you use inject methods to perform some basic initialization, since you may need the given dependencies to themselves be initialized via their Inject methods.

    Using [Inject] methods to inject dependencies is the recommended approach for MonoBehaviours, since MonoBehaviours cannot have constructors.

    Recommendations

    -
      -
    • Best practice is to prefer constructor injection or method injection to field or property injection. +

      Best practice is to prefer constructor injection or method injection to field or property injection.

      • Constructor injection forces the dependency to only be resolved once, at class creation, which is usually what you want. In most cases you don't want to expose a public property for your initial dependencies because this suggests that it's open to changing.
      • Constructor injection guarantees no circular dependencies between classes, which is generally a bad thing to do. You can do this however using method injection or field injection if necessary.
      • Constructor/Method injection is more portable for cases where you decide to re-use the code without a DI framework such as Zenject. You can do the same with public properties but it's more error prone (it's easier to forget to initialize one field and leave the object in an invalid state)
      • -
      • Finally, Constructor/Method injection makes it clear what all the dependencies of a class are when another programmer is reading the code. They can simply look at the parameter list of the method. This is also good because it will be more obvious when a class has too many dependencies and should therefore be split up (since it's constructor parameter list will be too long)
      • -
      -
    • +
    • Finally, Constructor/Method injection makes it clear what all the dependencies of a class are when another programmer is reading the code. They can simply look at the parameter list of the method. This is also good because it will be more obvious when a class has too many dependencies and should therefore be split up (since it's constructor parameter list will start to seem long)

    @@ -505,9 +519,9 @@

    public class Foo
     {
    -    IBar _bar;
    +    IBar _bar;
     
    -    public Foo(IBar bar)
    +    public Foo(IBar bar)
         {
             _bar = bar;
         }
    @@ -515,8 +529,8 @@ 

    You can wire up the dependencies for this class with the following:

    -
    Container.Bind<Foo>().AsSingle();
    -Container.Bind<IBar>().To<Bar>().AsSingle();
    +
    Container.Bind<Foo>().AsSingle();
    +Container.Bind<IBar>().To<Bar>().AsSingle();

    This tells Zenject that every class that requires a dependency of type Foo should use the same instance, which it will automatically create when needed. And similarly, any class that requires the IBar interface (like Foo) will be given the same instance of type Bar.

    @@ -530,7 +544,7 @@

    .AsScope() .WithArguments(Arguments) .When(Condition) - .InheritInSubContainers() + .CopyIntoAllSubContainers() .NonLazy();

    @@ -559,7 +573,7 @@

    • Default: FromNew()
    • -
    • Examples: eg. FromGetter, FromMethod, FromPrefab, FromResolve, FromSubContainerResolve, FromInstance, etc.
    • +
    • Examples: eg. FromGetter, FromMethod, FromResolve, FromComponentInNewPrefab, FromSubContainerResolve, FromInstance, etc.
  • @@ -577,7 +591,7 @@

  • AsCached - Will re-use the same instance of ResultType every time ContractType is requested, which it will lazily generate upon first use
  • -AsSingle - Will re-use the same instance of ResultType across the entire DiContainer, which it will lazily generate upon first use. It can be thought of as a stronger version of AsCached, because it allows you to bind to the same instance across multiple bind commands. It will also ensure that there is only ever exactly one instance of ResultType in the DiContainer (ie. it will enforce ResultType to be a 'Singleton' hence the name).
  • +AsSingle - Will re-use the same instance of ResultType across the entire DiContainer, which it will lazily generate upon first use. It can be thought of as a stronger version of AsCached, because it allows you to bind to the same instance across multiple bind commands. It will also ensure that there is only ever exactly one instance of ResultType in the DiContainer (ie. it will enforce ResultType to be a 'Singleton' hence the name). Note however that it will only guarantee that there is only one instance across the given container, which means that using AsSingle with the same binding in a sub-container could generate a second instance.

  • In most cases, you will likely want to just use AsSingle, however AsTransient and AsCached have their uses too.

  • @@ -588,26 +602,26 @@

    { } -public class Bar : IBar +public class Bar : IBar { } public class Foo() { - public Foo(Bar bar) + public Foo(Bar bar) { } }

    // This will cause every instance of Foo to be given a brand new instance of Bar
    -Container.Bind<Bar>().AsTransient();
    +Container.Bind<Bar>().AsTransient();

    // This will cause every instance of Foo to be given the same instance of Bar
    -Container.Bind<Bar>().AsCached();
    +Container.Bind<Bar>().AsCached();
    public class Qux()
     {
    -    public Qux(IBar bar)
    +    public Qux(IBar bar)
         {
         }
     }
    @@ -615,20 +629,20 @@

    // This will cause both Foo and Qux to get different instances of type Bar
     // However, every instance of Foo will be given the the same instance of type Bar
     // and similarly for Qux
    -Container.Bind<Bar>().AsCached();
    -Container.Bind<IBar>().To<Bar>().AsCached();
    +Container.Bind<Bar>().AsCached(); +Container.Bind<IBar>().To<Bar>().AsCached();

    // This will cause both Foo and Qux to get the same instance of type Bar
    -Container.Bind<Bar>().AsSingle();
    -Container.Bind<IBar>().To<Bar>().AsSingle();
    +Container.Bind<Bar>().AsSingle(); +Container.Bind<IBar>().To<Bar>().AsSingle();

    -
  • Arguments = A list of objects to use when constructing the new instance of type ResultType. This can be useful as an alternative to Container.BindInstance(arg).WhenInjectedInto<ResultType>()

  • +
  • Arguments = A list of objects to use when constructing the new instance of type ResultType. This can be useful as an alternative to adding other bindings for the arguments in the form Container.BindInstance(arg).WhenInjectedInto<ResultType>()

  • Condition = The condition that must be true for this binding to be chosen. See here for more details.
  • -InheritInSubContainers = If supplied, then this binding will automatically be inherited from any subcontainers that are created from it. In other words, the result will be equivalent to copying and pasting the Container.Bind statement into the installer for every sub-container.
  • +CopyIntoAllSubContainers = If supplied, then this binding will automatically be inherited from any subcontainers that are created from it. In other words, the result will be equivalent to copying and pasting the Container.Bind statement into the installer for every sub-container.
  • NonLazy = Normally, the ResultType is only ever instantiated when the binding is first used (aka "lazily"). However, when NonLazy is used, ResultType will immediately by created on startup.
  • @@ -641,65 +655,157 @@

    FromNew - Create via the C# new operator. This is the default if no construction method is specified.

    // These are both the same
    -Container.Bind<Foo>();
    -Container.Bind<Foo>().FromNew();
    +Container.Bind<Foo>(); +Container.Bind<Foo>().FromNew();

  • -

    FromInstance - Use a given instance

    +

    FromInstance - Add a given instance to the container. Note that the given instance will not be injected in this case. If you also want your instance to be injected at startup, see QueueForInject

    -
    Container.Bind<Foo>().FromInstance(new Foo());
    +
    Container.Bind<Foo>().FromInstance(new Foo());
     
     // You can also use this short hand which just takes ContractType from the parameter type
    -Container.BindInstance(new Foo());
    +Container.BindInstance(new Foo());
     
     // This is also what you would typically use for primitive types
    -Container.BindInstance(5.13f);
    -Container.BindInstance("foo");
    +Container.BindInstance(5.13f); +Container.BindInstance("foo"); + +// Or, if you have many instances, you can use BindInstances +Container.BindInstances(5.13f, "foo", new Foo());
  • FromMethod - Create via a custom method

    -
    Container.Bind<Foo>().FromMethod(SomeMethod);
    +
    Container.Bind<Foo>().FromMethod(SomeMethod);
     
    -Foo SomeMethod(InjectContext context)
    +Foo SomeMethod(InjectContext context)
     {
         ...
    -    return new Foo();
    +    return new Foo();
     }
  • -

    FromComponent - Create as a new component on an existing game object. ResultType must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +

    FromMethodMultiple - Same as FromMethod except allows returning multiple instances at once.

    + +
    Container.Bind<Foo>().FromMethodMultiple(GetFoos);
    +
    +IEnumerable<Foo> GetFoos(InjectContext context)
    +{
    +    ...
    +    return new Foo[]
    +    {
    +        new Foo(),
    +        new Foo(),
    +        new Foo(),
    +    }
    +}
    +
  • +
  • +

    FromFactory - Create instance using a custom factory class. This construction method is similar to FromMethod except can be cleaner in cases where the logic is more complicated or requires dependencies (since the factory itself can have dependencies injected)

    + +
    class FooFactory : IFactory<Foo>
    +{
    +    public Foo Create()
    +    {
    +        // ...
    +        return new Foo();
    +    }
    +}
    +
    +Container.Bind<Foo>().FromFactory<FooFactory>()
    +
  • +
  • +

    FromComponentInNewPrefab - Instantiate the given prefab as a new game object, inject any MonoBehaviour's on it, and then search the result for type ResultType.

    + +
    Container.Bind<Foo>().FromComponentInNewPrefab(somePrefab);
    + +

    ResultType must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +
  • +
  • +

    FromComponentInNewPrefabResource - Instantiate the given prefab (found at the given resource path) as a new game object, inject any MonoBehaviour's on it, and then search the result for type ResultType.

    + +
    Container.Bind<Foo>().FromComponentInNewPrefabResource("Some/Path/Foo");
    + +

    ResultType must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +
  • +
  • +

    FromNewComponentOnNewGameObject - Create a new empty game object and then instantiate a new component of the given type on it.

    + +
    Container.Bind<Foo>().FromNewComponentOnNewGameObject();
    + +

    ResultType must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +
  • +
  • +

    FromNewComponentOn - Instantiate a new component of the given type on the given game object

    + +
    Container.Bind<Foo>().FromComponent(someGameObject);
    + +

    ResultType must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +
  • +
  • +

    FromNewComponentSibling - Instantiate a new component of the given on the current transform. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type.

    + +
    Container.Bind<Foo>().FromNewComponentSibling();
    + +

    ResultType must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    + +

    Also note that if a non-MonoBehaviour requests the given type, an exception will be thrown, since there is no current transform in that case.

    +
  • +
  • +

    FromComponentInHierarchy - Look up the component within the scene hierarchy associated with the current context, as well as the hierarchy associated with any parent contexts.

    -
    Container.Bind<Foo>().FromComponent(someGameObject);
    +
    Container.Bind<Foo>().FromComponentInHierarchy();
    + +

    ResultType must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    + +

    In the most common case where the context is a SceneContext, this will search the entire scene hierarchy (except any sub-contexts such as GameObjectContext). In other words, when the current context is a scene context, it will behave similar to GameObject.FindObjectsOfType. Note that since this could be a big search, it should be used with caution, just like GameObject.FindObjectsOfType should be used with caution.

    + +

    In the case where the context is GameObjectContext, it will only search within and underneath the game object root (and any parent contexts).

    + +

    In the case where the context is ProjectContext, it will only search within the project context prefab

  • -

    FromSiblingComponent - Create as a new component on the same game object where the component is being injected into. ResultType must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +

    FromComponentSibling - Look up the given component type by searching over the components that are attached to the current transform. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type.

    -
    Container.Bind<Foo>().FromSiblingComponent(someGameObject);
    +
    Container.Bind<Foo>().FromComponentSibling();
    + +

    ResultType must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    + +

    Note that if a non-MonoBehaviour requests the given type, an exception will be thrown, since there is no current transform in that case.

  • -

    FromGameObject - Create as a new component on a new game object. ResultType must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +

    FromComponentInParents - Look up the component by searching the current transform or any parent for the given component type. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type.

    + +
    Container.Bind<Foo>().FromComponentInParents();
    -
    Container.Bind<Foo>().FromGameObject();
    +

    ResultType must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    + +

    Note that if a non-MonoBehaviour requests the given type, an exception will be thrown, since there is no current transform in that case.

  • -

    FromPrefab - Create by instantiating the given prefab and then searching it for type ResultType. ResultType must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +

    FromComponentInChildren - Look up the component by searching the current transform or any child transform for the given component type. The current transform here is taken from the object being injected, which must therefore be a MonoBehaviour derived type.

    + +
    Container.Bind<Foo>().FromComponentInChildren();
    -
    Container.Bind<Foo>().FromPrefab(somePrefab);
    +

    ResultType must either be an interface or derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    + +

    Note that if a non-MonoBehaviour requests the given type, an exception will be thrown, since there is no current transform in that case.

  • -

    FromPrefabResource - Create by instantiating the prefab at the given resource path and then searching it for type ResultType. ResultType must derive from UnityEngine.MonoBehaviour / UnityEngine.Component in this case

    +

    FromResource - Create by calling the Unity3d function Resources.Load for ResultType. This can be used to load any type that Resources.Load can load, such as textures, sounds, prefabs, etc.

    -
    Container.Bind<Foo>().FromPrefabResource("Some/Path/Foo");
    +
    Container.Bind<Texture>().WithId("Glass").FromResource("Some/Path/Glass");
  • -

    FromResource - Create by calling the Unity3d function Resources.Load for ResultType. This can be used to load any type that Resources.Load can load, such as textures, sounds, prefabs, custom classes deriving from ScriptableObject, etc.

    +

    FromScriptableObjectResource - Create a new ScriptableObject class by cloning a previously created instance saved to the resources folder.

    -
    public class Foo : ScriptableObject
    +
    public class Foo : ScriptableObject
     {
     }
     
    -Container.Bind<Foo>().FromResource("Some/Path/Foo");
    +Container.Bind<Foo>().FromScriptableObjectResource("Some/Path/Foo");
    + +

    Note that unlike FromResource, the value returned from Resources.Load in this case will be cloned by calling ScriptableObject.Instantiate. This is necessary to allow multiple instances of the same scriptable object resource.

  • FromResolve - Get instance by doing another lookup on the container (in other words, calling DiContainer.Resolve<ResultType>()). Note that for this to work, ResultType must be bound in a separate bind statement. This construction method can be especially useful when you want to bind an interface to another interface, as shown in the below example

    @@ -708,33 +814,19 @@

    { } -public interface IBar : IFoo +public interface IBar : IFoo { } -public class Foo : IBar +public class Foo : IBar { } -Container.Bind<IFoo>().To<IBar>().FromResolve(); -Container.Bind<IBar>().To<Foo>();

  • +Container.Bind<IFoo>().To<IBar>().FromResolve(); +Container.Bind<IBar>().To<Foo>();
  • -

    FromFactory - Create instance using a custom factory class. This construction method is similar to FromMethod except can be cleaner in cases where the logic is more complicated or requires dependencies (the factory itself can have dependencies injected)

    - -
    class FooFactory : IFactory<Foo>
    -{
    -    public Foo Create()
    -    {
    -        // ...
    -        return new Foo();
    -    }
    -}
    -
    -Container.Bind<Foo>().FromFactory<FooFactory>()
    -
  • -
  • -

    FromResolveGetter - Get instance from the property of another dependency which is obtained by doing another lookup on the container (in other words, calling DiContainer.Resolve<ObjectType>() and then accessing a value on the returned instance of type ResultType). Note that for this to work, ObjectType must be bound in a separate bind statement.

    +

    FromResolveGetter<ObjectType> - Get instance from the property of another dependency which is obtained by doing another lookup on the container (in other words, calling DiContainer.Resolve<ObjectType>() and then accessing a value on the returned instance of type ResultType). Note that for this to work, ObjectType must be bound in a separate bind statement.

    public class Bar
     {
    @@ -742,14 +834,14 @@ 

    public class Foo { - public Bar GetBar() + public Bar GetBar() { - return new Bar(); + return new Bar(); } } -Container.Bind<Foo>(); -Container.Bind<Bar>().FromResolveGetter<Foo>(x => x.GetBar());

    +Container.Bind<Foo>(); +Container.Bind<Bar>().FromResolveGetter<Foo>(x => x.GetBar());
  • FromSubContainerResolve - Get ResultType by doing a lookup on a subcontainer. Note that for this to work, the sub-container must have a binding for ResultType. This approach can be very powerful, because it allows you to group related dependencies together inside a mini-container, and then expose only certain classes (aka "Facades") to operate on this group of dependencies at a higher level. For more details on using sub-containers, see this section. There are 4 different ways to define the subcontainer:

    @@ -758,19 +850,19 @@

  • ByMethod - Initialize the subcontainer by using a method.

    -
    Container.Bind<Foo>().FromSubContainerResolve().ByMethod(InstallFooFacade);
    +
    Container.Bind<Foo>().FromSubContainerResolve().ByMethod(InstallFooFacade);
     
    -void InstallFooFacade(DiContainer subContainer)
    +void InstallFooFacade(DiContainer subContainer)
     {
         subContainer.Bind<Foo>();
     }
  • -

    ByInstaller - Initialize the subcontainer by using a class derived from Installer. This can be a cleaner and less error-prone alternative than using ByMethod, especially if you need to inject data into the installer itself. Less error prone because when using ByMethod it is common to accidentally use Container instead of subContainer in your method.

    +

    ByInstaller - Initialize the subcontainer by using a class derived from Installer. This can be a cleaner and less error-prone alternative than ByMethod, especially if you need to inject data into the installer itself. Less error prone because when using ByMethod it is common to accidentally use Container instead of subContainer in your method.

    -
    Container.Bind<Foo>().FromSubContainerResolve().ByInstaller<FooFacadeInstaller>();
    +
    Container.Bind<Foo>().FromSubContainerResolve().ByInstaller<FooFacadeInstaller>();
     
    -class FooFacadeInstaller : Installer
    +class FooFacadeInstaller : Installer
     {
         public override void InstallBindings()
         {
    @@ -779,13 +871,13 @@ 

    }

  • -

    ByPrefab - Initialize subcontainer using a prefab. Note that the prefab must contain a GameObjectContext component attached to the root game object. For details on GameObjectContext see this section.

    +

    ByNewPrefab - Initialize subcontainer by instantiating a new prefab. Note that the prefab must contain a GameObjectContext component attached to the root game object. For details on GameObjectContext see this section.

    -
    Container.Bind<Foo>().FromSubContainerResolve().ByPrefab(MyPrefab);
    +
    Container.Bind<Foo>().FromSubContainerResolve().ByNewPrefab(MyPrefab);
     
     // Assuming here that this installer is added to the GameObjectContext at the root
     // of the prefab.  You could also use a ZenjectBinding in the case where Foo is a MonoBehaviour
    -class FooFacadeInstaller : MonoInstaller
    +class FooFacadeInstaller : MonoInstaller
     {
         public override void InstallBindings()
         {
    @@ -794,9 +886,9 @@ 

    }

  • -

    ByPrefabResource - Initialize subcontainer using a prefab obtained via Resources.Load. Note that the prefab must contain a GameObjectContext component attached to the root game object.

    +

    ByNewPrefabResource - Initialize subcontainer instantiating a new prefab obtained via Resources.Load. Note that the prefab must contain a GameObjectContext component attached to the root game object.

    -
    Container.Bind<Foo>().FromSubContainerResolve().ByPrefabResource("Path/To/MyPrefab");
    +
    Container.Bind<Foo>().FromSubContainerResolve().ByNewPrefabResource("Path/To/MyPrefab");
  • @@ -807,12 +899,12 @@

    Often, there is some collections of related bindings for each sub-system and so it makes sense to group those bindings into a re-usable object. In Zenject this re-usable object is called an 'installer'. You can define a new installer as follows:

    -
    public class FooInstaller : MonoInstaller
    +
    public class FooInstaller : MonoInstaller
     {
         public override void InstallBindings()
         {
    -        Container.BindAllInterfaces<Foo>().To<Foo>().AsSingle();
             Container.Bind<Bar>().AsSingle();
    +        Container.BindInterfacesTo<Foo>().AsSingle();
             // etc...
         }
     }
    @@ -825,7 +917,7 @@

    You can also call an installer from another installer. For example:

    -
    public class BarInstaller : Installer<BarInstaller>
    +
    public class BarInstaller : Installer<BarInstaller>
     {
         public override void InstallBindings()
         {
    @@ -833,7 +925,7 @@ 

    } } -public class FooInstaller : MonoInstaller +public class FooInstaller : MonoInstaller { public override void InstallBindings() { @@ -841,9 +933,9 @@

    } }

    -

    Note that in this case BarInstaller is of type Installer and not MonoInstaller, which is why we can simply call BarInstaller.Install(Container) and don't require that BarInstaller be added to our scene already. Any calls to BarInstaller.Install will immediately create a temporary instance of BarInstaller and then call InstallBindings on it. This will repeat for any installers that this installer installs. Note also that when using the Installer base class, we always must pass in ourself as the generic argument to Installer<>. This is necessary so that the Installer<> base class can define the static method BarInstaller.Install. It is also designed this way to support runtime parameters (described below).

    +

    Note that in this case BarInstaller is of type Installer<> (note the generic arguments) and not MonoInstaller, which is why we can simply call BarInstaller.Install(Container) and don't require that BarInstaller be added to our scene already. Any calls to BarInstaller.Install will immediately create a temporary instance of BarInstaller and then call InstallBindings on it. This will repeat for any installers that this installer installs. Note also that when using the Installer<> base class, we always must pass in ourself as the generic argument to Installer<>. This is necessary so that the Installer<> base class can define the static method BarInstaller.Install. It is also designed this way to support runtime parameters (described below).

    -

    One of the main reasons we use installers as opposed to just having all our bindings declared all at once for each scene, is to make them re-usable. This is not a problem for installers of type Installer because you can simply call FooInstaller.Install as described above for every scene you wish to use it in, but then how would we re-use a MonoInstaller in multiple scenes?

    +

    One of the main reasons we use installers as opposed to just having all our bindings declared all at once for each scene, is to make them re-usable. This is not a problem for installers of type Installer<> because you can simply call FooInstaller.Install as described above for every scene you wish to use it in, but then how would we re-use a MonoInstaller in multiple scenes?

    There are three ways to do this.

    @@ -853,18 +945,18 @@

  • Prefabs within Resources folder. You can also place your installer prefabs underneath a Resoures folder and install them directly from code by using the Resources path. For details on usage see here.

  • -

    Another option in addition to MonoInstaller and Installer is to use ScriptableObjectInstaller which has some advantages (especially for settings) - for details see here.

    +

    Another option in addition to MonoInstaller and Installer<> is to use ScriptableObjectInstaller which has some advantages (especially for settings) - for details see here.

    When calling installers from other installers it is common to want to pass parameters into it. See here for details on how that is done.

    ITickable

    -

    In many cases it is preferable to avoid the extra weight of MonoBehaviours in favour of just normal C# classes. Zenject allows you to do this much more easily by providing interfaces that mirror functionality that you would normally need to use a MonoBehaviour for.

    +

    In some cases it is preferable to avoid the extra weight of MonoBehaviours in favour of just normal C# classes. Zenject allows you to do this much more easily by providing interfaces that mirror functionality that you would normally need to use a MonoBehaviour for.

    For example, if you have code that needs to run per frame, then you can implement the ITickable interface:

    -
    public class Ship : ITickable
    +
    public class Ship : ITickable
     {
         public void Tick()
         {
    @@ -872,15 +964,13 @@ 

    } }

    -

    Then it's just a matter of including the following in one of your installers:

    - -
    Container.Bind<ITickable>().To<Ship>().AsSingle();
    +

    Then, to hook it up in an installer:

    -

    Or if you don't want to have to remember which interfaces Ship implements:

    +
    Container.Bind<ITickable>().To<Ship>().AsSingle();
    -
    Container.BindAllInterfaces<Ship>().To<Ship>().AsSingle();
    +

    Or if you don't want to have to always remember which interfaces your class implements, you can use the shortcut described here

    -

    Note that the order that Tick() is called on all ITickables is also configurable, as outlined here.

    +

    Note that the order that the Tick() is called in for all ITickables is also configurable, as outlined here.

    Also note that there are interfaces ILateTickable and IFixedTickable which work similarly for the other unity update methods.

    @@ -889,13 +979,21 @@

    If you have some initialization that needs to occur on a given object, you could include this code in the constructor. However, this means that the initialization logic would occur in the middle of the object graph being constructed, so it may not be ideal.

    -

    One alternative is to implement IInitializable, and then perform initialization logic in an Initialize() method. This Initialize method would then be called after the entire object graph is constructed and all constructors have been called.

    +

    A better alternative is to implement IInitializable, and then perform initialization logic in an Initialize() method.

    -

    Note that the constructors for the initial object graph are called during Unity's Awake event, and that the IInitializable.Initialize methods are called immediately on Unity's Start event. Using IInitializable as opposed to a constructor is therefore more in line with Unity's own recommendations, which suggest that the Awake phase be used to set up object references, and the Start phase should be used for more involved initialization logic.

    +

    Then, to hook it up in an installer:

    + +
    Container.Bind<IInitializable>().To<Foo>().AsSingle();
    + +

    Or if you don't want to have to always remember which interfaces your class implements, you can use the shortcut described here

    + +

    The Foo.Initialize method would then be called after the entire object graph is constructed and all constructors have been called.

    + +

    Note that the constructors for the initial object graph are called during Unity's Awake event, and that the IInitializable.Initialize methods are called immediately on Unity's Start event. Using IInitializable as opposed to a constructor is therefore more in line with Unity's own recommendations, which suggest that the Awake phase be used to set up object references, and the Start phase be used for more involved initialization logic.

    This can also be better than using constructors or [Inject] methods because the initialization order is customizable in a similar way to ITickable, as explained here.

    -
    public class Ship : IInitializable
    +
    public class Ship : IInitializable
     {
         public void Initialize()
         {
    @@ -908,7 +1006,7 @@ 

    public class Foo
     {
         [Inject]
    -    IBar _bar;
    +    IBar _bar;
     
         [Inject]
         public void Initialize()
    @@ -922,11 +1020,11 @@ 

    IDisposable

    -

    If you have external resources that you want to clean up when the app closes, the scene changes, or for whatever reason the context object is destroyed, you can simply declare your class as IDisposable like below:

    +

    If you have external resources that you want to clean up when the app closes, the scene changes, or for whatever reason the context object is destroyed, you can declare your class as IDisposable like below:

    -
    public class Logger : IInitializable, IDisposable
    +
    public class Logger : IInitializable, IDisposable
     {
    -    FileStream _outStream;
    +    FileStream _outStream;
     
         public void Initialize()
         {
    @@ -946,48 +1044,108 @@ 

    Then in your installer you can include:

    -
    Container.Bind<Logger>().AsSingle();
    -Container.Bind<IInitializable>().To<Logger>().AsSingle();
    -Container.Bind<IDisposable>().To<Logger>().AsSingle();
    +
    Container.Bind<Logger>().AsSingle();
    +Container.Bind<IInitializable>().To<Logger>().AsSingle();
    +Container.Bind<IDisposable>().To<Logger>().AsSingle();
    -

    Or you can use the following shortcut:

    +

    Or you can use the BindInterfaces shortcut:

    -
    Container.BindAllInterfacesAndSelf<Logger>().To<Logger>().AsSingle();
    +
    Container.BindInterfacesAndSelfTo<Logger>().AsSingle();

    This works because when the scene changes or your unity application is closed, the unity event OnDestroy() is called on all MonoBehaviours, including the SceneContext class, which then triggers Dispose() on all objects that are bound to IDisposable

    -

    Note that this example may or may not be a good idea (for example, the file will be left open if your app crashes), but illustrates the point :)

    +

    +BindInterfacesTo and BindInterfacesAndSelfTo

    + +

    If you end up using the ITickable, IInitializable, and IDisposable interfaces as described above, you will often end up with code like this:

    + +
    Container.Bind<Foo>().AsSingle();
    +Container.Bind<IInitializable>().To<Foo>().AsSingle();
    +Container.Bind<IDisposable>().To<Foo>().AsSingle();
    + +

    You can simplify this a bit by using the non generic bind method:

    + +
    Container.Bind(typeof(Foo), typeof(IInitializable), typeof(IDisposable)).To<Foo>().AsSingle();
    + +

    This is better but it could still be more readable. Also, this is still not ideal because if I later on decide that Foo doesn't need a Tick() or a Dispose() then I have to keep the installer in sync.

    + +

    A better idea would be to just always use the interfaces like this:

    + +
    Container.Bind(new[] { typeof(Foo) }.Concat(typeof(Foo).GetInterfaces())).To<Foo>().AsSingle();
    + +

    This pattern is useful enough that Zenject includes a custom bind method for it. The above code is equivalent to:

    + +
    Container.BindInterfacesAndSelfTo<Foo>().AsSingle();
    + +

    Now, we can add and remove interfaces to/from Foo and the installer remains the same.

    + +

    In some cases you might only want to bind the interfaces, and keep Foo hidden from other classes. In that case you would use the BindInterfacesTo method instead:

    + +
    Container.BindInterfacesTo<Foo>().AsSingle()
    + +

    Which, in this case, would expand to:

    + +
    Container.Bind(typeof(IInitializable), typeof(IDisposable)).To<Foo>().AsSingle();
    + +

    Or, equivalently:

    + +
    Container.Bind<IInitializable>().To<Foo>().AsSingle();
    +Container.Bind<IDisposable>().To<Foo>().AsSingle();

    Using the Unity Inspector To Configure Settings

    -

    One implication of writing most of your code as normal C# classes instead of MonoBehaviour's is that you lose the ability to configure data on them using the inspector. You can however still take advantage of this in Zenject by using the following pattern, as seen in the sample project:

    +

    One implication of writing most of your code as normal C# classes instead of MonoBehaviour's is that you lose the ability to configure data on them using the inspector. You can however still take advantage of this in Zenject by using the following pattern:

    -
    public class AsteroidsInstaller : MonoInstaller
    +
    public class Foo : ITickable
     {
    -    public Settings SceneSettings;
    +    readonly Settings _settings;
     
    -    public override void InstallBindings()
    +    public Foo(Settings settings)
         {
    -        ...
    -        Container.BindInstance(SceneSettings.StateMoving);
    -        ...
    +        _settings = settings;
    +    }
    +
    +    public void Tick()
    +    {
    +        Debug.Log("Speed: " + _settings.Speed);
         }
     
         [Serializable]
         public class Settings
         {
    -        ...
    -        public ShipStateMoving.Settings StateMoving;
    -        ...
    +        public float Speed;
    +    }
    +}
    + +

    Then, in an installer:

    + +
    public class TestInstaller : MonoInstaller<TestInstaller>
    +{
    +    public Foo.Settings FooSettings;
    +
    +    public override void InstallBindings()
    +    {
    +        Container.BindInstance(FooSettings);
    +        Container.BindInterfacesTo<Foo>().AsSingle();
         }
     }
    -

    Note that if you follow this method, you will have to make sure to always include the [Serializable] attribute on your settings wrappers, otherwise they won't show up in the Unity inspector.

    +

    Or, equivalently:

    + +
    public class TestInstaller : MonoInstaller<TestInstaller>
    +{
    +    public Foo.Settings FooSettings;
    +
    +    public override void InstallBindings()
    +    {
    +        Container.BindInterfacesTo<Foo>().AsSingle().WithArguments(FooSettings);
    +    }
    +}
    -

    To see this in action, start the asteroids scene and try adjusting Ship -> State Moving -> Move Speed setting and watch live as your ship changes speed.

    +

    Now, if we run our scene we can change the speed value to tune the Foo class in real time.

    -

    Another way to do this is to use ScriptableObjectInstaller to store settings, which have the added advantage that you can change your settings at runtime and have those changes automatically persist when play mode is stopped. See here for details.

    +

    Another (arguably better) way to do this is to use ScriptableObjectInstaller instead of MonoInstaller, which have the added advantage that you can change your settings at runtime and have those changes automatically persist when play mode is stopped. See here for details.

    Object Graph Validation

    @@ -1077,13 +1235,13 @@

    This is equivalent to the first example where we did this:

    -
    Container.Bind<Foo>().FromInstance(_foo);
    +
    Container.Bind<Foo>().FromInstance(_foo);
    -

    Which is also the same as this:

    +

    Or, equivalently:

    -
    Container.BindInstance(_foo);
    +
    Container.BindInstance(_foo);
    -

    So if we duplicate this game object to have multiple game objects with Foo on them (and its ZenjectBinding), they will all be bound to the Container this way. So after doing this, we would have to change GameRunner above to take a List<Foo> otherwise we would get Zenject exceptions (see here for info on list bindings).

    +

    So if we duplicate this game object to have multiple game objects with Foo on them (as well as the ZenjectBinding), they will all be bound to the Container this way. So after doing this, we would have to change GameRunner above to take a List<Foo> otherwise we would get Zenject exceptions (see here for info on list bindings).

    1. AllInterfaces
    2. @@ -1091,9 +1249,9 @@

      This bind type is equivalent to the following:

      -
      Container.BindAllInterfaces(_foo.GetType()).FromInstance(_foo);
      +
      Container.BindInterfacesTo(_foo.GetType()).FromInstance(_foo);
      -

      Note however, in this case, that GameRunner must ask for type IFoo in its constructor. If we left GameRunner asking for type Foo then Zenject would throw exceptions, since the BindAllInterfaces method only binds the interfaces, not the concrete type. If you want the concrete type as well then you can use:

      +

      Note however, in this case, that GameRunner must ask for type IFoo in its constructor. If we left GameRunner asking for type Foo then Zenject would throw exceptions, since the BindInterfaces method only binds the interfaces, not the concrete type. If you want the concrete type as well then you can use:

      1. AllInterfacesAndSelf
      2. @@ -1101,7 +1259,7 @@

        This bind type is equivalent to the following:

        -
        Container.BindAllInterfacesAndSelf(_foo.GetType()).FromInstance(_foo);
        +
        Container.BindInterfacesAndSelfTo(_foo.GetType()).FromInstance(_foo);

        This is the same as AllInterfaces except we can directly access Foo using type Foo instead of needing an interface.

        @@ -1111,14 +1269,14 @@

        This bind type is equivalent to the following:

        -
        Container.BindAllInterfacesAndSelf(_foo.GetType().BaseType()).FromInstance(_foo);
        +
        Container.BindAllInterfacesAndSelf(_foo.GetType().BaseType()).FromInstance(_foo);
      3. Identifier - This value can be left empty most of the time. It will determine what is used as the identifier for the binding. For example, when set to "Foo1", it is equivalent to doing the following:

        -
        Container.BindInstance(_foo).WithId("Foo1");
        +
        Container.BindInstance(_foo).WithId("Foo1");
      4. -
      5. Context - This is completely optional and in most cases should be left unset. This will determine which Context to apply the binding to. If left unset, it will use whatever context the GameObject is in. In most cases this will be SceneContext, but if it's inside a GameObjectContext it will be bound into that container instead. One important use case for this field is to allow dragging the SceneContext into this field, for cases where the component is inside a GameObjectContext. This allows you to treat this MonoBehaviour as a Facade for the entire sub-container given by the GameObjectContext.

      6. +
      7. Context - This is completely optional and in most cases should be left unset. This will determine which Context to apply the binding to. If left unset, it will use whatever context the GameObject is in. In most cases this will be SceneContext, but if it's inside a GameObjectContext it will be bound into the GameObjectContext container instead. One important use case for this field is to allow dragging the SceneContext into this field, for cases where the component is inside a GameObjectContext. This allows you to treat this MonoBehaviour as a Facade for the entire sub-container given by the GameObjectContext.

      8. @@ -1129,7 +1287,7 @@

        Do not use GameObject.Instantiate if you want your objects to have their dependencies injected

          -
        • If you want to instantiate a prefab at runtime and have any MonoBehaviour's automatically injected, we recommend using a factory. You can also instantiate a prefab by directly using the DiContainer by calling any of the InstantiatePrefab methods. Using these ways as opposed to GameObject.Instantiate will ensure any fields that are marked with the [Inject] attribute are filled in properly, and all [Inject] methods within the prefab are called.
        • +
        • If you want to instantiate a prefab at runtime and have any MonoBehaviour's automatically injected, we recommend using a factory. You can also instantiate a prefab by directly using the DiContainer by calling any of the InstantiatePrefab methods. Using these ways as opposed to GameObject.Instantiate will ensure any fields that are marked with the [Inject] attribute are filled in properly, and all [Inject] methods within the prefab are called.
      9. @@ -1191,54 +1349,52 @@

      10. Another common mistake is to leave out the call which defines the scope (eg. AsSingle, AsTransient, or AsCached) and therefore unintentionally use the default (AsTransient). For example:
      11. -

        Container.BindAllInterfacesAndSelf<Foo>().To<Foo>();

        +
        
        +* The above binding is almost certainly not what you want to do, because it will create an instance of Foo for every interface that Foo has.  Instead, you almost certainly want to use either `AsCached` or `AsSingle` in this case
         
        -
          -
        • The above binding is almost certainly not what you want to do, because it will create an instance of Foo for every interface that Foo has. Instead, you almost certainly want to use either AsCached or AsSingle in this case
        • -
        -

      12. - +Please feel free to submit any other sources of confusion to sfvermeulen@gmail.com and I will add it here. -

        Please feel free to submit any other sources of confusion to sfvermeulen@gmail.com and I will add it here.

        +## <a id="game-object-bind-methods"></a>Game Object Bind Methods -

        -Game Object Bind Methods

        +For bindings that create new game objects (eg. FromComponentInNewPrefab or FromGameObject) there are also two extra bind methods. + +* **WithGameObjectName** = The name to give the new Game Object associated with this binding. -

        For bindings that create new game objects (eg. FromPrefab or FromGameObject) there are also two extra bind methods

        +```csharp +Container.Bind<Foo>().FromComponentInNewPrefabResource("Some/Path/Foo").WithGameObjectName("Foo1"); +Container.Bind<Foo>().FromNewComponentOnNewGameObject().WithGameObjectName("Foo1"); +

    • -

      WithGameObjectName = The name to give the new Game Object associated with this binding.

      +UnderTransformGroup(string) = The name of the transform group to place the new game object under. This is especially useful for factories, which can be used to create many copies of a prefab, so it can be nice to have them automatically grouped together within the scene heirarchy.
    • +
    -
    Container.Bind<Foo>().FromPrefabResource("Some/Path/Foo").WithGameObjectName("Foo1");
    -Container.Bind<Foo>().FromGameObject().WithGameObjectName("Foo2");
    - -
  • -

    UnderTransformGroup(string) = The name of the transform group to place the new game object under. This is especially useful for factories, which can be used to create many copies of a prefab, so it can be nice to have them automatically grouped together within the scene heirarchy.

    +
    Container.BindFactory<Bullet, Bullet.Factory>()
    +    .FromComponentInNewPrefab(BulletPrefab)
    +    .UnderTransformGroup("Bullets");
    -
    Container.BindFactory<Bullet, Bullet.Factory>()
    -    .FromPrefab(BulletPrefab)
    -    .UnderTransformGroup("Bullets");
    -
  • +
    • -

      UnderTransform(Transform) = The actual transform to place the new game object under.

      - -
      Container.BindFactory<Bullet, Bullet.Factory>()
      -    .FromPrefab(BulletPrefab)
      -    .UnderTransform(BulletTransform);
      -
    • +UnderTransform(Transform) = The actual transform to place the new game object under.
    +
    Container.BindFactory<Bullet, Bullet.Factory>()
    +    .FromComponentInNewPrefab(BulletPrefab)
    +    .UnderTransform(BulletTransform);
    +

    Optional Binding

    You can declare some dependencies as optional as follows:

    + +
    public class Bar
     {
         public Bar(
             [InjectOptional]
    -        IFoo foo)
    +        IFoo foo)
         {
             ...
         }
    @@ -1246,7 +1402,7 @@ 

    ... // You can comment this out and it will still work -Container.Bind<IFoo>().AsSingle();

    +Container.Bind<IFoo>().AsSingle();

    If an optional dependency is not bound in any installers, then it will be injected as null.

    @@ -1256,7 +1412,7 @@

    public class Bar
     {
    -    public Bar(int foo = 5)
    +    public Bar(int foo = 5)
         {
             ...
         }
    @@ -1264,7 +1420,7 @@ 

    ... // Can comment this out and 5 will be used instead -Container.BindInstance(1);

    +Container.BindInstance(1);

    Note also that the [InjectOptional] is not necessary in this case, since it's already implied by the default value.

    @@ -1272,7 +1428,7 @@

    public class Bar
     {
    -    int _foo;
    +    int _foo;
     
         public Bar(
             [InjectOptional]
    @@ -1293,19 +1449,19 @@ 

    ... // Can comment this out and it will use 5 instead -Container.BindInstance(1);

    +Container.BindInstance(1);

    Conditional Bindings

    In many cases you will want to restrict where a given dependency is injected. You can do this using the following syntax:

    -
    Container.Bind<IFoo>().To<Foo1>().AsSingle().WhenInjectedInto<Bar1>();
    -Container.Bind<IFoo>().To<Foo2>().AsSingle().WhenInjectedInto<Bar2>();
    +
    Container.Bind<IFoo>().To<Foo1>().AsSingle().WhenInjectedInto<Bar1>();
    +Container.Bind<IFoo>().To<Foo2>().AsSingle().WhenInjectedInto<Bar2>();

    Note that WhenInjectedInto is simple shorthand for the following, which uses the more general When() method:

    -
    Container.Bind<IFoo>().To<Foo>().AsSingle().When(context => context.ObjectType == typeof(Bar));
    +
    Container.Bind<IFoo>().To<Foo>().AsSingle().When(context => context.ObjectType == typeof(Bar));

    The InjectContext class (which is passed as the context parameter above) contains the following information that you can use in your conditional:

    @@ -1336,29 +1492,20 @@

    When Zenject finds multiple bindings for the same type, it interprets that to be a list. So, in the example code below, Bar would get a list containing a new instance of Foo1, Foo2, and Foo3:

    // In an installer somewhere
    -Container.Bind<IFoo>().To<Foo1>().AsSingle();
    -Container.Bind<IFoo>().To<Foo2>().AsSingle();
    -Container.Bind<IFoo>().To<Foo3>().AsSingle();
    +Container.Bind<IFoo>().To<Foo1>().AsSingle();
    +Container.Bind<IFoo>().To<Foo2>().AsSingle();
    +Container.Bind<IFoo>().To<Foo3>().AsSingle();
     
     ...
     
    -public class Bar
    +public class Bar
     {
    -    public Bar(List<IFoo> foos)
    +    public Bar(List<IFoo> foos)
         {
         }
     }
    -

    Also worth noting is that if you try and declare a single dependency of IFoo (like Bar below) and there are multiple bindings for it, then Zenject will throw an exception, since Zenject doesn't know which instance of IFoo to use.

    - -
    public class Bar
    -{
    -    public Bar(IFoo foo)
    -    {
    -    }
    -}
    - -

    Also, if the empty list is valid, then you should mark your List constructor parameter (or [Inject] field) as optional (see here for details).

    +

    The order of the list will be the same as the order in which they were added with a Bind method. The only exception is when you use subcontainers, since in that case the list will be ordered first by the associated subcontainer, with the first set of instances taken from the bottom most subcontainer, and then the parent, then the grandparent, etc.

    Global Bindings Using Project Context

    @@ -1375,28 +1522,28 @@

    The reason that all the bindings you add to a global installer are available for any classes within each individual scene, is because the Container in each scene uses the ProjectContext Container as it's "parent". For more information on nested containers see here.

    -

    ProjectContext is a very convenient place to put objects that you want to persist across scenes. However, the fact that it's completely global to every scene can lead to some unintended behaviour. For example, this means that even if you write a simple test scene that uses Zenject, it will load the ProjectContext, which may not be what you want. To address these problems it is sometimes better to use Scene Parenting instead, since that approach allows you to be selective in terms of which scenes inherit the same common bindings. See here for more details on that approach.

    +

    ProjectContext is a very convenient place to put objects that you want to persist across scenes. However, the fact that it's completely global to every scene can lead to some unintended behaviour. For example, this means that even if you write a simple test scene that uses Zenject, it will load the ProjectContext, which may not be what you want. To address these problems it is often better to use Scene Parenting instead, since that approach allows you to be selective in terms of which scenes inherit the same common bindings. See here for more details on that approach.

    Identifiers

    You can also give an ID to your binding if you need to have distinct bindings for the same type, and you don't want it to just result in a List<>. For example:

    -
    Container.Bind<IFoo>().WithId("foo").To<Foo1>().AsSingle();
    -Container.Bind<IFoo>().To<Foo2>().AsSingle();
    +
    Container.Bind<IFoo>().WithId("foo").To<Foo1>().AsSingle();
    +Container.Bind<IFoo>().To<Foo2>().AsSingle();
     
     ...
     
    -public class Bar1
    +public class Bar1
     {
         [Inject(Id = "foo")]
    -    IFoo _foo;
    +    IFoo _foo;
     }
     
     public class Bar2
     {
         [Inject]
    -    IFoo _foo;
    +    IFoo _foo;
     }

    In this example, the Bar1 class will be given an instance of Foo1, and the Bar2 class will use the default version of IFoo which is bound to Foo2.

    @@ -1405,10 +1552,10 @@

    public class Bar
     {
    -    Foo _foo;
    +    Foo _foo;
     
         public Bar(
    -        [Inject(Id = "foo")] 
    +        [Inject(Id = "foo")] 
             Foo foo)
         {
         }
    @@ -1416,14 +1563,14 @@ 

    In many cases, the ID is created as a string, however you can actually use any type you like for this. For example, it's sometimes useful to use an enum instead:

    -
    enum Cameras
    +
    enum Cameras
     {
    -    Main,
    -    Player,
    +    Main,
    +    Player,
     }
     
    -Container.Bind<Camera>().WithId(Cameras.Main).FromInstance(MyMainCamera);
    -Container.Bind<Camera>().WithId(Cameras.Player).FromInstance(MyPlayerCamera);
    +Container.Bind<Camera>().WithId(Cameras.Main).FromInstance(MyMainCamera); +Container.Bind<Camera>().WithId(Cameras.Player).FromInstance(MyPlayerCamera);

    You can also use custom types, as long as they implement the Equals operator.

    @@ -1450,26 +1597,24 @@

  • Following the approach to settings outlined here, you might then replace it with the following:
  • -
    public class GameSettings : ScriptableObjectInstaller
    +
    public class GameSettings : ScriptableObjectInstaller
     {
    -    public Player.Settings Player;
    -    public SomethingElse.Settings SomethingElse;
    +    public Player.Settings Player;
    +    public SomethingElse.Settings SomethingElse;
         // ... etc.
     
         public override void InstallBindings()
         {
    -        Container.BindInstance(Player);
    -        Container.BindInstance(SomethingElse);
    -        // ... etc.
    +        Container.BindInstances(Player, SomethingElse, etc.);
         }
     }
     
    -public class Player : ITickable
    +public class Player : ITickable
     {
    -    readonly Settings _settings;
    -    Vector3 _position;
    +    readonly Settings _settings;
    +    Vector3 _position;
     
    -    public Player(Settings settings)
    +    public Player(Settings settings)
         {
             _settings = settings;
         }
    @@ -1482,7 +1627,7 @@ 

    [Serializable] public class Settings { - public float Speed; + public float Speed; } }

    @@ -1495,11 +1640,11 @@

    Often when calling installers from other installers it is desirable to be able to pass parameters. You can do this by adding generic arguments to whichever installer base class you are using with the types for the runtime parameters. For example, when using a non-MonoBehaviour Installer:

    -
    public class FooInstaller : Installer<string, FooInstaller>
    +
    public class FooInstaller : Installer<string, FooInstaller>
     {
    -    string _value;
    +    string _value;
     
    -    public FooInstaller(string value)
    +    public FooInstaller(string value)
         {
             _value = value;
         }
    @@ -1512,7 +1657,7 @@ 

    } } -public class MainInstaller : MonoInstaller +public class MainInstaller : MonoInstaller { public override void InstallBindings() { @@ -1523,9 +1668,9 @@

    Or when using a MonoInstaller prefab:

    -
    public class FooInstaller : MonoInstaller<string, FooInstaller>
    +
    public class FooInstaller : MonoInstaller<string, FooInstaller>
     {
    -    string _value;
    +    string _value;
     
         // Note that in this case we can't use a constructor
         [Inject]
    @@ -1542,63 +1687,38 @@ 

    } } -public class MainInstaller : MonoInstaller +public class MainInstaller : MonoInstaller { public override void InstallBindings() { // For this to work, there must be a prefab with FooInstaller attached to it at // Resources/My/Custom/ResourcePath.prefab - FooInstaller.InstallFromResource("My/Custom/ResourcePath", Container, "asdf"); + FooInstaller.InstallFromResource("My/Custom/ResourcePath", Container, new object[] { "asdf" }); - // In this case the prefab will be assumed to exist at 'Resources/Installers/FooInstaller' - // FooInstaller.InstallFromResource(Container, "asdf"); + // If a resource path is not provided then it is assumed to exist at resource path + // 'Resources/Installers/FooInstaller' + // For example: + // FooInstaller.InstallFromResource(Container, new object[] { "asdf" }); } }

    -

    Or, by using a ScriptableObjectInstaller:

    - -
    public class FooInstaller : ScriptableObjectInstaller<string, FooInstaller>
    -{
    -    string _value;
    -
    -    // Note that in this case we can't use a constructor
    -    [Inject]
    -    public void Construct(string value)
    -    {
    -        _value = value;
    -    }
    -
    -    public override void InstallBindings()
    -    {
    -        ...
    -
    -        Container.BindInstance(_value).WhenInjectedInto<Foo>();
    -    }
    -}
    -
    -public class MainInstaller : MonoInstaller
    -{
    -    public override void InstallBindings()
    -    {
    -        // For this to work, there must be an instance of FooInstaller added at
    -        // Resources/My/Custom/ResourcePath.asset
    -        FooInstaller.InstallFromResource("My/Custom/ResourcePath", Container, "asdf");
    -
    -        // In this case the FooInstaller asset will be assumed to exist at 'Resources/Installers/FooInstaller'
    -        // FooInstaller.InstallFromResource(Container, "asdf");
    -    }
    -}
    +

    ScriptableObjectInstaller works the same as MonoInstaller in this regard.

    -Commands And Signals

    +Signals

    -

    See here.

    +

    See here.

    Creating Objects Dynamically Using Factories

    See here.

    +

    +Memory Pools

    + +

    See here.

    +

    Update / Initialization Order

    @@ -1606,11 +1726,11 @@

    In Zenject, by default, ITickables and IInitializables are called in the order that they are added, however for cases where the update or initialization order does matter, there is a much better way: By specifying their priorities explicitly in the installer. For example, in the sample project you can find this code in the scene installer:

    -
    public class AsteroidsInstaller : MonoInstaller
    +
    public class AsteroidsInstaller : MonoInstaller
     {
         ...
     
    -    void InitExecutionOrder()
    +    void InitExecutionOrder()
         {
             // In many cases you don't need to worry about execution order,
             // however sometimes it can be important
    @@ -1625,7 +1745,7 @@ 

    ... - public override void InstallBindings() + public override void InstallBindings() { ... InitExecutionOrder(); @@ -1640,31 +1760,44 @@

    You can also assign priorities for each specific interface separately like this:

    -
    Container.BindInitializableExecutionOrder<Foo>(-10);
    -Container.BindInitializableExecutionOrder<Bar>(-20);
    +
    Container.BindInitializableExecutionOrder<Foo>(-10);
    +Container.BindInitializableExecutionOrder<Bar>(-20);
     
    -Container.BindTickableExecutionOrder<Foo>(10);
    -Container.BindTickableExecutionOrder<Bar>(-80);
    +Container.BindTickableExecutionOrder<Foo>(10); +Container.BindTickableExecutionOrder<Bar>(-80);

    Any ITickables, IInitializables, or IDisposable's that are not assigned a priority are automatically given the priority of zero. This allows you to have classes with explicit priorities executed either before or after the unspecified classes. For example, the above code would result in 'Foo.Initialize' being called before 'Bar.Initialize'.

    Zenject Order Of Operations

    -

    A Zenject driven application is executed by the following steps:

    +

    What follows below is a more detailed view of what happens when running a scene that uses Zenject. This can be useful to know to fully understand exactly how Zenject works.

    • Unity Awake() phase begins
      • SceneContext.Awake() method is called. This should always be the first thing executed in your scene. It should work this way by default (see here if you are noticing otherwise).
      • -
      • If this is the first scene to be loaded during this play session, SceneContext will create the ProjectContext prefab. If ProjectContext has already been created by a previous scene, we skip this step and directly initialize the SceneContext
      • -
      • ProjectContext iterates through all the Installers that have been added to its prefab via the Unity Inspector, updates them to point to its DiContainer, then calls InstallBindings() on each. Each Installer calls some number of Bind<> methods on the DiContainer.
      • -
      • ProjectContext then injects all MonoBehaviours attached to its game object as well as its children
      • +
      • Project Context is initialized. Note that this only happens once per play session. If a previous scene already initialized the ProjectContext, then this step is skipped + +
          +
        • All injectable MonoBehaviour's on the ProjectContext prefab are passed to the container via DiContainer.QueueForInject +
        • +
        • ProjectContext iterates through all the Installers that have been added to its prefab via the Unity Inspector, updates them to point to its DiContainer, then calls InstallBindings() on each. Each Installer calls some number of Bind methods on the DiContainer.
        • +
        • All instances that were added via DiContainer.QueueForInject are injected
        • ProjectContext then constructs all the non-lazy root objects, which includes any classes that derive from ITickable / IInitializable or IDisposable, as well as those classes that are added with a NonLazy() binding.
        • +
        +
      • +
      • Scene Context is initialized. + +
          +
        • All injectable MonoBehaviour's in the entire scene are passed to the SceneContext container via DiContainer.QueueForInject +
        • SceneContext iterates through all the Installers that have been added to it via the Unity Inspector, updates them to point to its DiContainer, then calls InstallBindings() on each. Each Installer calls some number of Bind<> methods on the DiContainer.
        • -
        • SceneContext then injects all objects in the scene (except those objects that are parented to the ProjectContext)
        • +
        • All instances that were added via DiContainer.QueueForInject are injected
        • SceneContext then constructs all the non-lazy root objects, which includes any classes that derive from ITickable / IInitializable or IDisposable, as well as those classes that are added with a NonLazy() binding.
        • +
        +
      • If any required dependencies cannot be resolved, a ZenjectResolveException is thrown
      • All other MonoBehaviour's in the scene have their Awake() method called
      @@ -1690,6 +1823,7 @@

    • Unity scene is unloaded
        +
      • Dispose() is called on all objects mapped to IDisposable within all the GameObjectContext's (see here for details)
      • Dispose() is called on all objects mapped to IDisposable within the SceneContext installers (see here for details)
    • @@ -1708,13 +1842,13 @@

      Let's pretend you want to specify a 'level' string to the next scene. You have the following class that requires the input:

      -
      public class LevelHandler : IInitializable
      +
      public class LevelHandler : IInitializable
       {
      -    readonly string _startLevel;
      +    readonly string _startLevel;
       
           public LevelHandler(
               [InjectOptional]
      -        string startLevel)
      +        string startLevel)
           {
               if (startLevel == null)
               {
      @@ -1739,16 +1873,16 @@ 

       public class Foo
       {
      -    readonly ZenjectSceneLoader _sceneLoader;
      +    readonly ZenjectSceneLoader _sceneLoader;
       
      -    public Foo(ZenjectSceneLoader sceneLoader)
      +    public Foo(ZenjectSceneLoader sceneLoader)
           {
               _sceneLoader = sceneLoader;
           }
       
           public void AdvanceScene()
           {
      -        _sceneLoader.LoadScene("NameOfSceneToLoad", LoadSceneMode.Single, (container) =>
      +        _sceneLoader.LoadScene("NameOfSceneToLoad", LoadSceneMode.Single, (container) =>
                   {
                       container.BindInstance("custom_level").WhenInjectedInto<LevelHandler>();
                   });
      @@ -1761,11 +1895,11 @@ 

      An alternative and arguably cleaner way to do this would be to customize the installer itself rather than the LevelHandler class. In this case we can write our LevelHandler class like this (without the [InjectOptional] flag).

      -
      public class LevelHandler : IInitializable
      +
      public class LevelHandler : IInitializable
       {
      -    readonly string _startLevel;
      +    readonly string _startLevel;
       
      -    public LevelHandler(string startLevel)
      +    public LevelHandler(string startLevel)
           {
               _startLevel = startLevel;
           }
      @@ -1780,14 +1914,14 @@ 

      Then, in the installer for our scene we can include the following:

      -
      public class GameInstaller : Installer
      +
      public class GameInstaller : Installer
       {
           [InjectOptional]
      -    public string LevelName = "default_level";
      +    public string LevelName = "default_level";
       
           ...
       
      -    public override void InstallBindings()
      +    public override void InstallBindings()
           {
               ...
               Container.BindInstance(LevelName).WhenInjectedInto<LevelHandler>();
      @@ -1800,16 +1934,16 @@ 

       public class Foo
       {
      -    readonly ZenjectSceneLoader _sceneLoader;
      +    readonly ZenjectSceneLoader _sceneLoader;
       
      -    public Foo(ZenjectSceneLoader sceneLoader)
      +    public Foo(ZenjectSceneLoader sceneLoader)
           {
               _sceneLoader = sceneLoader;
           }
       
           public void AdvanceScene()
           {
      -        _sceneLoader.LoadScene("NameOfSceneToLoad", (container) =>
      +        _sceneLoader.LoadScene("NameOfSceneToLoad", (container) =>
                   {
                       container.BindInstance("custom_level").WhenInjectedInto<GameInstaller>();
                   });
      @@ -1833,7 +1967,7 @@ 

      Note that you do not need to load the environment scene and the ship scene at the same time for this to work. For example, you might want to have a menu embedded inside the environment to allow the user to choose their ship before starting. So you could create a menu scene and load that after the environment scene. Then once the user chooses their ship, you could load the associated ship scene by calling the unity method SceneManager.LoadScene (making sure to use LoadSceneMode.Additive).

      -

      Also note that the Validate command can be used to quickly verify the different multi-scene setups.

      +

      Also note that the Validate command can be used to quickly verify the different multi-scene setups. If you find that scenes are unloaded when you do this see here.

      Also, I should mention that Unity currently doesn't have a built-in way to save and restore multi-scene setups. We use a simple editor script for this that you can find here if interested.

      @@ -1860,7 +1994,7 @@

    -
    public class ExampleDecoratorInstaller : MonoInstaller
    +
    public class ExampleDecoratorInstaller : MonoInstaller
     {
         public override void InstallBindings()
         {
    @@ -1868,7 +2002,7 @@ 

    } } -public class TestHotKeysAdder : ITickable +public class TestHotKeysAdder : ITickable { public void Tick() { @@ -1881,7 +2015,7 @@

    If you run your scene it should now behave exactly like the main scene except with the added functionality in your decorator installer. Also note that while not shown here, both scenes can access each other's bindings as if everything was in the same scene.

    -

    Also note that the Validate command (CTRL+SHIFT+V) can be used to quickly verify the different multi-scene setups.

    +

    Also note that the Validate command (CTRL+SHIFT+V) can be used to quickly verify the different multi-scene setups. If you find that scenes are unloaded when you do this see here.

    Also, note that decorator scenes must be loaded before the scenes that they are decorating.

    @@ -1897,49 +2031,410 @@

    See here.

    +

    +Just-In-Time Resolving Using Lazy<>

    + +

    In some cases it can be useful to delay the creation of certain dependencies until after startup. You can use the Lazy<> construct for this.

    + +

    For example, let's imagine a scenario like this:

    + +
    public class Foo
    +{
    +    public void Run()
    +    {
    +        ...
    +    }
    +}
    +
    +public class Bar
    +{
    +    Foo _foo;
    +
    +    public Bar(Foo foo)
    +    {
    +        _foo = foo;
    +    }
    +
    +    public void Run()
    +    {
    +        _foo.Run();
    +    }
    +}
    +
    +public class TestInstaller : MonoInstaller<TestInstaller>
    +{
    +    public override void InstallBindings()
    +    {
    +        Container.Bind<Foo>().AsSingle();
    +        Container.Bind<Bar>().AsSingle();
    +    }
    +}
    + +

    Let's also imagine that we would only like to create an instance of Foo if it's actually used (that is, when the Bar.Run method is called). As it stands above, Foo would always be created every time that Bar is created, even if Bar.Run is never called. We can fix this by changing Bar to the following:

    + +
    public class Bar
    +{
    +    Lazy<Foo> _foo;
    +
    +    public Bar(Lazy<Foo> foo)
    +    {
    +        _foo = foo;
    +    }
    +
    +    public void Run()
    +    {
    +        _foo.Value.Run();
    +    }
    +}
    + +

    Now, by using Lazy<> instead, the Foo class will not be created until Bar.Run is first called. After that, it will use the same instance of Foo.

    + +

    Note that the installers remain the same in both cases. Any injected dependency can be made lazy by simply wrapping it in Lazy<>.

    + +

    +DiContainer Methods

    + +

    In addition to the bind methods documented above, there are also some other methods you might want to occasionally use on DiContainer. For example, if you are writing a custom factory, you might want to directly call one of the DiContainer.Instantiate methods. Or you might have a situation where another library is creating instances of your classes (for example, a networking library) and you need to manually call DiContainer.Inject.

    + +

    DiContainer is always added to itself, so you can always get it injected into any class. However, note that injecting the DiContainer is usually a sign of bad practice, since there is almost always a better way to design your code such that you don't need to reference DiContainer directly (the exception being custom factories). Once again, best practice with dependency injection is to only reference the DiContainer in the "composition root layer" which includes any custom factories you might have as well as the installers. However there are exceptions to this rule.

    + +

    +DiContainer.Instantiate

    + +

    These instantiate methods might be useful for example inside a custom factory. Note however that in most cases, you can probably get away with using a normal Factory instead without needing to directly reference DiContainer.

    + +

    When instantiating objects directly, you can either use DiContainer or you can use IInstantiator, which DiContainer inherits from. IInstantiator exists because often, in custom factories, you are only interested in the instantiate operation so you don't need the Bind, Resolve, etc. methods

    + +
      +
    1. +

      Instantiate<T> - Create the given class using the new operator and then inject it. Note that this method should not be used for Components/MonoBehaviours. However, it can be used for ScriptableObject derived classes (in which case Zenject will automatically call ScriptableObject.CreateInstance).

      + +
      Foo foo = Container.Instantiate<Foo>();
      + +

      You can also pass extra arguments to it like this:

      + +
      Foo foo = Container.Instantiate<Foo>(new object[] { "foo", 5 });
      + +

      There is also non-generic versions:

      + +
      Foo foo = (Foo)Container.Instantiate(typeof(Foo));
      +Foo foo = (Foo)Container.Instantiate(typeof(Foo), new object[] { "foo", 5 });
      +
    2. +
    3. +

      InstantiatePrefab - Instantiate the given prefab and then inject into any MonoBehaviour's that are on it.

      + +
      GameObject gameObject = Container.InstantiatePrefab(MyPrefab);
      + +

      This method is equivalent to calling var gameObject = GameObject.Instantiate(MyPrefab) yourself and then calling DiContainer.Inject(gameObject). Note that MyPrefab above can either be a GameObject or it can be a direct reference to a component on the prefab.

      + +

      Similar to GameObject.Instantiate, you can also pass an initial parent transform to use:

      + +
      GameObject gameObject = Container.InstantiatePrefab(MyPrefab, MyParentTransform);
      +
    4. +
    5. +

      InstantiatePrefabResource - Same as InstantiatePrefab except instead of passing a prefab, you pass a path within the unity Resources folder where the prefab exists.

      + +
      GameObject gameObject = Container.InstantiatePrefabResource("path/to/myprefab");
      + +

      This method is simply a shortcut to calling Container.InstantiatePrefab(Resources.Load("path/to/myprefab"));

      +
    6. +
    7. +

      InstantiatePrefabForComponent<T> - Instantiates the given prefab, injects on the prefab, and then returns the given component which is assumed to exist somewhere in the heirarchy of the prefab.

      + +
      var foo = Container.InstantiatePrefabForComponent<Foo>(FooPrefab)
      + +

      Unlike the InstantiatePrefab methods above, this method also allows passing parameters to the given component:

      + +
      var foo = Container.InstantiatePrefabForComponent<Foo>(FooPrefab, new object[] { "asdf", 6.0f })
      +
    8. +
    9. +

      InstantiatePrefabResourceForComponent<T> - Same as InstantiatePrefabForComponent, except the prefab is provided as a resource path instead of as a direct reference

      + +
      var foo = Container.InstantiatePrefabResourceForComponent<Foo>("path/to/fooprefab")
      +var foo = Container.InstantiatePrefabResourceForComponent<Foo>("path/to/fooprefab", new object[] { "asdf", 6.0f })
      +
    10. +
    11. +

      InstantiateComponent<T> - Add the given component to a given game object.

      + +
      var foo = Container.InstantiateComponent<Foo>(gameObject);
      +var foo = Container.InstantiateComponent<Foo>(gameObject, new object[] { "asdf", 6.0f });
      + +

      Note that this is equivalent to calling GameObject.AddComponent yourself then immediatly calling DiContainer.Inject on the new component instance.

      +
    12. +
    13. +

      InstantiateComponentOnNewGameObject<T> - Create a new empty game object then instantiate a new component of the given type on it

      + +
      var foo = Container.InstantiateComponentOnNewGameObject<Foo>();
      +var foo = Container.InstantiateComponentOnNewGameObject<Foo>(new object[] { "zxcv" });
      + +

      This is similar to calling new GameObject(), then call DiContainer.InstantiateComponent on the result.

      +
    14. +
    15. +

      InstantiateScriptableObjectResource<T> - Instantiate the given ScriptableObject type which is assumed to exist at the given resource path. Note that if you want to create an entirely new ScriptableObject, you can just use DiContainer.Instantiate.

      + +
      var foo = Container.InstantiateScriptableObjectResource<Foo>("path/to/fooscriptableobject")
      +var foo = Container.InstantiateScriptableObjectResource<Foo>("path/to/fooscriptableobject", new object[] { "asdf", 6.0f })
      +
    16. +
    + +

    +DiContainer.Bind

    + +

    See here

    + +

    +DiContainer.Resolve

    + +
      +
    1. +

      DiContainer.Resolve - Get instance to match the given type. This may involve creating a new instance or it might return an existing instance, depending on how the given type was bound.

      + +
      Container.Bind<Foo>().AsSingle();
      +...
      +var foo = Container.Resolve<Foo>();
      + +

      An exception will be thrown if no bindings were found for the given type or if multiple bindings were found. See TryResolve / ResolveAll for those cases.

      +
    2. +
    3. +

      DiContainer.ResolveId - Same as resolve except includes an identifier

      + +
      Container.Bind<Foo>().WithId("foo1").AsSingle();
      +...
      +var foo = Container.ResolveId<Foo>("foo1");
      +
    4. +
    5. +

      DiContainer.TryResolve - Same as DiContainer.Resolve except instead of throwing an exception when a match is not found, a null value is returned.

      + +
      var foo = Container.TryResolve<Foo>();
      +
      +if (foo != null)
      +{
      +    ...
      +}
      +
    6. +
    7. DiContainer.TryResolveId - Same as DiContainer.TryResolve except also takes an identifier

    8. +
    9. +

      DiContainer.ResolveAll - Same as DiContainer.Resolve except it will return all matches instead of assuming just one.

      + +
      List<Foo> foos = Container.ResolveAll<Foo>();
      +
    10. +
    11. DiContainer.ResolveIdAll - Same as DiContainer.ResolveAll except also takes an identifier

    12. +
    13. +

      DiContainer.ResolveType - Returns the type that would be retrieved/instantiated if Resolve is called with the same type/identifier.

      + +
      if (Container.ResolveType<IFoo>() == typeof(Foo))
      +{
      +    ...
      +}
      + +

      This is safe to call during install phase since nothing will be instantiated by calling this. Note also that if there are multiple matches found or zero matches then an exception will be thrown.

      +
    14. +
    15. DiContainer.ResolveTypeAll - Same as ResolveType except returns all matches instead of assuming a single match.

    16. +
    + +

    +DiContainer.Inject

    + +
      +
    1. +

      DiContainer.Inject - Inject on the given instance.

      + +
      Container.Inject(foo);
      + +

      Note that you can also pass extra arguments to inject:

      + +
      Container.Inject(foo, new object[] { "asdf", 6 });
      + +

      This will inject in the following order:

      + +
        +
      1. Fields
      2. +
      3. Properties
      4. +
      5. Inject methods
      6. +
      +
    2. +
    3. +

      DiContainer.InjectGameObject - Inject into all MonoBehaviour's attached to the given game object as well as any children.

      + +
      Container.InjectGameObject(gameObject);
      + +

      Note that it will inject in a bottom-up fashion. So the root transforms in the given game object will always be injected last.

      +
    4. +
    5. +

      DiContainer.InjectGameObjectForComponent - Same as InjectGameObject except it will return the given component after injection completes.

      + +
      var foo = Container.InjectGameObjectForComponent<Foo>(gameObject);
      + +

      Also, unlike InjectGameObject, this method supports passing extra arguments to the given component:

      + +
      var foo = Container.InjectGameObjectForComponent<Foo>(gameObject, new object[] { "asdf", 5.1f });
      + +

      Note however that it is assumed here that there is only one match for the given component. Multiple matches (or zero matches) will generate an exception.

      +
    6. +
    + +

    +DiContainer.QueueForInject

    + +

    DiContainer.QueueForInject will queue the given instance for injection once the initial object graph is constructed.

    + +

    Sometimes, there are instances that are not created by Zenject and which exist at startup, and which you want to be injected. In these cases you will often add them to the container like this:

    + +
    var foo = new Foo();
    +...
    +Container.Bind<Foo>().FromInstance(foo);
    + +

    Or, equivalently, using this shortcut:

    + +
    Container.BindInstance(foo);
    + +

    However, using FromInstance will not cause the given instance to be injected.

    + +

    One approach would be to inject on the instance immediately like this:

    + +
    Container.BindInstance(foo);
    +Container.Inject(foo);
    + +

    However, this is bad practice. You do not ever want to instantiate or inject during the install phase, because the objects that you are injecting could require bindings that have not yet been added.

    + +

    Therefore the correct way to handle these cases is to use QueueForInject:

    + +
    Container.BindInstance(foo);
    +Container.QueueForInject(foo);
    + +

    This way, our foo object will be injected at the same time the initial object graph is constructed, immediately after the install phase.

    + +

    Another important advantage of using QueueForInject is that Zenject will guarantee that your instances are injected in the correct order. In other words, if you have the following classes:

    + +
    class A
    +{
    +    [Inject]
    +    public void Init()
    +    {
    +        ...
    +    }
    +}
    +
    +class B
    +{
    +    [Inject]
    +    public void Init(A a)
    +    {
    +        ...
    +    }
    +}
    + +

    And they are added to the container this way:

    + +
    var a = new A();
    +var b = new B();
    +
    +Container.BindInstance(a);
    +Container.BindInstance(b);
    +
    +Container.QueueForInject(a);
    +Container.QueueForInject(b);
    + +

    Then, you can assume that A will have its inject method called before B, regardless of the order that they were added to the container. This is nice in the case where you have some initialization logic that occurs in the [Inject] method for B, and which requires that A has been initialized.

    + +

    This is also precisely how the initial MonoBehaviour's in the scene are injected. They are all simply added to the container with the QueueForInject method.

    + +

    +DiContainer Unbind / Rebind

    + +

    It is possible to remove or replace bindings that were added in a previous bind statement.

    + +
      +
    1. +

      Unbind - Remove all bindings matching the given type/id from container.

      + +
      Container.Bind<IFoo>().To<Foo>();
      +
      +// This will nullify the above statement
      +Container.Unbind<IFoo>();
      +
    2. +
    3. +

      Rebind - Override existing bindings with a new one. This is equivalent to calling unbind with the given type and then immediately calling bind afterwards.

      + +
      Container.Bind<IFoo>().To<Foo>();
      +
      +Container.Rebind<IFoo>().To<Bar>();
      +
    4. +
    + +

    +Other DiContainer methods

    + +
      +
    1. DiContainer.ParentContainer - The parent container for the given DiContainer. For example, for the DiContainer associated with SceneContext, this will usually be the DiContainer associated with the ProjectContext (unless you're using Scene Parenting in which case it will be another SceneContext)
    2. +
    3. DiContainer.IsValidating - Returns true if the container is being run for validation. This can be useful in some edge cases where special logic needs to be added during the validation step only.
    4. +
    5. +

      DiContainer.CreateSubContainer - Creates a new container as a child of the current container. This might be useful for custom factories that involve creating objects with complex inter-dependencies. For example:

      + +
      var subContainer = Container.CreateSubContainer();
      +
      +subContainer.Bind<Foo>();
      +subContainer.Bind<Bar>();
      +subContainer.Bind<Qux>();
      +
      +var foo = subContainer.Resolve<Foo>();
      + +

      Although in most cases you should probably use the FromSubContainerResolve methods rather than doing it this way.

      +
    6. +
    7. +

      DiContainer.HasBinding - Returns true if a binding that matches the given type/id has already been added. This can be useful if you want to avoid adding a duplicate binding that may have been added in a previous installer

      + +
      if (!Container.HasBinding<IFoo>())
      +{
      +    Container.Bind<IFoo>().To<Foo>().AsSingle();
      +}
      +
    8. +
    9. DiContainer.GetDependencyContracts - Returns a list of all the types that the given type depends on. This might be useful, for exmaple, if you wanted to do some static analysis of your project, or if you wanted to automatically generate a dependency diagram, etc.

    10. +
    +

    Non Generic bindings

    In some cases you may not know the exact type you want to bind at compile time. In these cases you can use the overload of the Bind method which takes a System.Type value instead of a generic parameter.

    // These two lines will result in the same behaviour
    -Container.Bind(typeof(Foo));
    -Container.Bind<Foo>();
    +Container.Bind(typeof(Foo)); +Container.Bind<Foo>();

    Note also that when using non generic bindings, you can pass multiple arguments:

    -
    Container.Bind(typeof(Foo), typeof(Bar), typeof(Qux)).AsSingle();
    +
    Container.Bind(typeof(Foo), typeof(Bar), typeof(Qux)).AsSingle();
     
     // The above line is equivalent to these three:
    -Container.Bind<Foo>().AsSingle();
    -Container.Bind<Bar>().AsSingle();
    -Container.Bind<Qux>().AsSingle();
    +Container.Bind<Foo>().AsSingle(); +Container.Bind<Bar>().AsSingle(); +Container.Bind<Qux>().AsSingle();

    The same goes for the To method:

    -
    Container.Bind<IFoo>().To(typeof(Foo), typeof(Bar)).AsSingle();
    +
    Container.Bind<IFoo>().To(typeof(Foo), typeof(Bar)).AsSingle();
     
     // The above line is equivalent to these two:
    -Container.Bind<IFoo>().To<Foo>().AsSingle();
    -Container.Bind<IFoo>().To<Bar>().AsSingle();
    +Container.Bind<IFoo>().To<Foo>().AsSingle(); +Container.Bind<IFoo>().To<Bar>().AsSingle();

    You can also do both:

    -
    Container.Bind(typeof(IFoo), typeof(IBar)).To(typeof(Foo1), typeof(Foo2)).AsSingle();
    +
    Container.Bind(typeof(IFoo), typeof(IBar)).To(typeof(Foo1), typeof(Foo2)).AsSingle();
     
     // The above line is equivalent to these:
    -Container.Bind<IFoo>().To<Foo>().AsSingle();
    -Container.Bind<IFoo>().To<Bar>().AsSingle();
    -Container.Bind<IBar>().To<Foo>().AsSingle();
    -Container.Bind<IBar>().To<Bar>().AsSingle();
    +Container.Bind<IFoo>().To<Foo>().AsSingle(); +Container.Bind<IFoo>().To<Bar>().AsSingle(); +Container.Bind<IBar>().To<Foo>().AsSingle(); +Container.Bind<IBar>().To<Bar>().AsSingle();

    This can be especially useful when you have a class that implements multiple interfaces:

    -
    Container.Bind(typeof(ITickable), typeof(IInitializable), typeof(IDisposable)).To<Foo>().AsSingle();
    +
    Container.Bind(typeof(ITickable), typeof(IInitializable), typeof(IDisposable)).To<Foo>().AsSingle();

    Though in this particular example there is already a built-in shortcut method for this:

    -
    Container.BindAllInterfaces<Foo>().To<Foo>().AsSingle();
    +
    Container.BindInterfacesTo<Foo>().AsSingle();

    Convention Based Binding

    @@ -1956,7 +2451,7 @@

    They are specified in a similar way to Non Generic bindings, except instead of giving a list of types to the Bind() and To() methods, you describe the convention using a Fluent API. For example, to bind IFoo to every class that implements it in the entire codebase:

    -
    Container.Bind<IFoo>().To(x => x.AllTypes().DerivingFrom<IFoo>());
    +
    Container.Bind<IFoo>().To(x => x.AllTypes().DerivingFrom<IFoo>());

    Note that you can use the same Fluent API in the Bind() method as well, and you can also use it in both Bind() and To() at the same time.

    @@ -2044,64 +2539,40 @@

  • Bind IFoo to every class that implements it in the entire codebase:

    -
    Container.Bind<IFoo>().To(x => x.AllTypes().DerivingFrom<IFoo>());
    +
    Container.Bind<IFoo>().To(x => x.AllTypes().DerivingFrom<IFoo>());

    Note that this will also have the same result:

    -
    Container.Bind<IFoo>().To(x => x.AllNonAbstractTypes());
    +
    Container.Bind<IFoo>().To(x => x.AllNonAbstractTypes());

    This is because Zenject will skip any bindings in which the concrete type does not actually derive from the base type. Also note that in this case we have to make sure we use AllNonAbstractTypes instead of just AllTypes, to ensure that we don't bind IFoo to itself

  • Bind an interface to all classes implementing it within a given namespace

    -
    Container.Bind<IFoo>().To(x => x.AllTypes().DerivingFrom<IFoo>().InNamespace("MyGame.Foos"));
    +
    Container.Bind<IFoo>().To(x => x.AllTypes().DerivingFrom<IFoo>().InNamespace("MyGame.Foos"));
  • Auto-bind IController every class that has the suffix "Controller" (as is done in ASP.NET MVC):

    -
    Container.Bind<IController>().To(x => x.AllNonAbstractTypes().WithSuffix("Controller"));
    +
    Container.Bind<IController>().To(x => x.AllNonAbstractTypes().WithSuffix("Controller"));

    You could also do this using MatchingRegex:

    -
    Container.Bind<IController>().To(x => x.AllNonAbstractTypes().MatchingRegex("Controller$"));
    +
    Container.Bind<IController>().To(x => x.AllNonAbstractTypes().MatchingRegex("Controller$"));
  • Bind all types with the prefix "Widget" and inject into Foo

    -
    Container.Bind<object>().To(x => x.AllNonAbstractTypes().WithPrefix("Widget")).WhenInjectedInto<Foo>();
    +
    Container.Bind<object>().To(x => x.AllNonAbstractTypes().WithPrefix("Widget")).WhenInjectedInto<Foo>();
  • Auto-bind the interfaces that are used by every type in a given namespace

    -
    Container.Bind(x => x.AllInterfaces())
    +
    Container.Bind(x => x.AllInterfaces())
         .To(x => x.AllNonAbstractClasses().InNamespace("MyGame.Things"));
    -

    This is equivalent to calling Container.BindAllInterfaces<T>().To<T>() for every type in the namespace "MyGame.Things". This works because, as touched on above, Zenject will skip any bindings in which the concrete type does not actually derive from the base type. So even though we are using AllInterfaces which matches every single interface in every single loaded assembly, this is ok because it will not try and bind an interface to a type that doesn't implement this interface.

    -
  • - - -

    -Unbind / Rebind

    - -

    It is also possible to remove or replace bindings that were added in another bind statement.

    - -
      -
    1. -

      Unbind - Remove binding from container.

      - -
      Container.Bind<IFoo>().To<Foo>();
      -
      -// This will nullify the above statement
      -Container.Unbind<IFoo>();
      -
    2. -
    3. -

      Rebind - Override an existing binding with a new one. This is equivalent to calling unbind with the given type and then immediately calling bind afterwards.

      - -
      Container.Bind<IFoo>().To<Foo>();
      -
      -// 
      -Container.Rebind<IFoo>().To<Bar>();
      +

      This is equivalent to calling Container.BindInterfacesTo<T>() for every type in the namespace "MyGame.Things". This works because, as touched on above, Zenject will skip any bindings in which the concrete type does not actually derive from the base type. So even though we are using AllInterfaces which matches every single interface in every single loaded assembly, this is ok because it will not try and bind an interface to a type that doesn't implement this interface.

    @@ -2112,26 +2583,26 @@

    This allows you to force Zenject to create multiple singletons instead of just one, since otherwise the singleton is uniquely identified based on the type given as generic argument to the To<> method. So for example:

    -
    Container.Bind<IFoo>().To<Foo>().AsSingle();
    -Container.Bind<IBar>().To<Foo>().AsSingle();
    -Container.Bind<IQux>().To<Qux>().AsSingle();
    +
    Container.Bind<IFoo>().To<Foo>().AsSingle();
    +Container.Bind<IBar>().To<Foo>().AsSingle();
    +Container.Bind<IQux>().To<Qux>().AsSingle();

    In the above code, both IFoo and IBar will be bound to the same instance. Only one instance of Foo will be created.

    -
    Container.Bind<IFoo>().To<Foo>().AsSingle("foo1");
    -Container.Bind<IBar>().To<Foo>().AsSingle("foo2");
    +
    Container.Bind<IFoo>().To<Foo>().AsSingle("foo1");
    +Container.Bind<IBar>().To<Foo>().AsSingle("foo2");

    In this case however, two instances will be created.

    Another use case for this is to allow creating multiple singletons from the same prefab. For example, Given the following:

    -
    Container.Bind<Foo>().FromPrefab(MyPrefab).AsSingle();
    -Container.Bind<Bar>().FromPrefab(MyPrefab).AsSingle();
    +
    Container.Bind<Foo>().FromComponentInNewPrefab(MyPrefab).AsSingle();
    +Container.Bind<Bar>().FromComponentInNewPrefab(MyPrefab).AsSingle();
    -

    It will only instantiate the prefab MyPrefab once, since the singleton is identified solely by the prefab when using FromPrefab. The concrete type given can be interpreted as "Search the instantiated prefab for this component". But, if instead you want Zenject to instantiate a new instance of the prefab for each FromPrefab binding, then you can do that as well by supplying an identifier to the AsSingle function like this:

    +

    It will only instantiate the prefab MyPrefab once, since the singleton is identified solely by the prefab when using FromComponentInNewPrefab. The concrete type given can be interpreted as "Search the instantiated prefab for this component". But, if instead you want Zenject to instantiate a new instance of the prefab for each FromComponentInNewPrefab binding, then you can do that as well by supplying an identifier to the AsSingle function like this:

    -
    Container.Bind<Foo>().FromPrefab(MyPrefab).AsSingle("foo");
    -Container.Bind<Bar>().FromPrefab(MyPrefab).AsSingle("bar");
    +
    Container.Bind<Foo>().FromComponentInNewPrefab(MyPrefab).AsSingle("foo");
    +Container.Bind<Bar>().FromComponentInNewPrefab(MyPrefab).AsSingle("bar");

    Now two instances of the prefab will be created.

    @@ -2151,30 +2622,30 @@

  • Right now it is empty, so let's add some content to it. Open it up and replace the contents with the following:
  • -
    public class TimerWindow : ZenjectEditorWindow
    +
    public class TimerWindow : ZenjectEditorWindow
     {
    -    TimerController.State _timerState = new TimerController.State();
    +    TimerController.State _timerState = new TimerController.State();
     
         [MenuItem("Window/TimerWindow")]
    -    public static TimerWindow GetOrCreateWindow()
    +    public static TimerWindow GetOrCreateWindow()
         {
    -        var window = EditorWindow.GetWindow<TimerWindow>();
    -        window.titleContent = new GUIContent("TimerWindow");
    +        var window = EditorWindow.GetWindow<TimerWindow>();
    +        window.titleContent = new GUIContent("TimerWindow");
             return window;
         }
     
         public override void InstallBindings()
         {
             Container.BindInstance(_timerState);
    -        Container.BindAllInterfaces<TimerController>().To<TimerController>().AsSingle();
    +        Container.BindInterfacesTo<TimerController>().AsSingle();
         }
     }
     
    -class TimerController : IGuiRenderable, ITickable, IInitializable
    +class TimerController : IGuiRenderable, ITickable, IInitializable
     {
    -    readonly State _state;
    +    readonly State _state;
     
    -    public TimerController(State state)
    +    public TimerController(State state)
         {
             _state = state;
         }
    @@ -2186,9 +2657,9 @@ 

    public void GuiRender() { - GUI.Label(new Rect(25, 25, 200, 200), "Tick Count: " + _state.TickCount); + GUI.Label(new Rect(25, 25, 200, 200), "Tick Count: " + _state.TickCount); - if (GUI.Button(new Rect(25, 50, 200, 50), "Restart")) + if (GUI.Button(new Rect(25, 50, 200, 50), "Restart")) { _state.TickCount = 0; } @@ -2202,7 +2673,7 @@

    [Serializable] public class State { - public int TickCount; + public int TickCount; } }

    @@ -2241,6 +2712,8 @@

    Zenject uses C# reflection which is typically slow, but in Zenject this work is cached so any performance hits only occur once for each class type. In other words, Zenject avoids costly reflection operations by making a trade-off between performance and memory to ensure good performance.

    +

    You can also force Zenject to populate this cache by calling Zenject.TypeAnalyzer.GetInfo for each type you want Zenject to cache the reflection information for.

    +

    For some benchmarks on Zenject versus other DI frameworks, see here.

    Zenject should also produce zero per-frame heap allocations.

    @@ -2299,11 +2772,6 @@

    Yet another option is to use a coroutine library that implements similar functionality to what Unity provides. See here for one example that we've used in the past at Modest Tree

  • -

    How do I use Zenject with pools to minimize memory allocations?

    - -

    Currently, Zenject does not support memory pooling. When you bind something to transient or use a factory, Zenject will always create a brand new instance from scratch. We realize that this can be inefficient in cases where you are creating many objects (especially on mobile) so it is something we want to address in future versions.

    -
  • -
  • What games/tools/libraries are using Zenject?

    If you know of other projects that are using Zenject, please add a comment here so that I can add it to this list.

    @@ -2320,6 +2788,15 @@

    Submarine (iOS and Android)

  • NOVA Black Holes (iOS)
  • +
  • +Farm Away! (iOS and Android)
  • +
  • +Build Away! (iOS and Android)
  • +
  • Stick Soccer 2 (iOS and Android)
  • +
  • +Untethered (Google VR)
  • +
  • +Toy Clash - (GearVR)
  • Libraries

    @@ -2329,15 +2806,17 @@

    EcsRx - A framework for Unity using the ECS pattern
  • Karma - An MVC framework for Unity
  • +
  • +View Controller - A view controller system
  • Tools

    • -Modest 3D (WebGL, WebPlayer, PC) - An IDE to allow users to quickly and easily create procedural training content
    • +Modest 3D (WebGL, WebPlayer, PC) - An IDE to allow users to quickly and easily create procedural training content
    • -Modest 3D Explorer (WebGL, WebPlayer, iOS, Android, PC, Windows Store) - A simple editor to quickly create a 3D presentation with some number of slides
    • +Modest 3D Explorer (WebGL, WebPlayer, iOS, Android, PC, Windows Store) - A simple editor to quickly create a 3D presentation with some number of slides
    @@ -2389,7 +2868,7 @@

    - +
     
    diff --git a/UnityProject/Assets/Zenject/Documentation/ReleaseNotes.html b/UnityProject/Assets/Zenject/Documentation/ReleaseNotes.html index 3645614e5..b7e3acce9 100644 --- a/UnityProject/Assets/Zenject/Documentation/ReleaseNotes.html +++ b/UnityProject/Assets/Zenject/Documentation/ReleaseNotes.html @@ -52,7 +52,82 @@

    Release Notes

    -

    4.7 (November 6, 2016)

    +

    +5.0 (February 11, 2017)

    + +

    New Features

    + +
      +
    • Added Lazy<> construct so that you can have the resolve occur upon first usage
    • +
    • Added menu option "Validate All Active Scenes"
    • +
    • Added support for memory pools. This includes a fluent interface similar to how factories work
    • +
    • Added DiContainer.QueueForInject method to support adding pre-made instances to the initial inject list
    • +
    • Added new construction methods + +
        +
      • FromMethodMultiple
      • +
      • FromComponentInHierarchy
      • +
      • FromComponentSibling
      • +
      • FromComponentInParents
      • +
      • FromComponentInChildren
      • +
      • FromScriptableObjectResource
      • +
      +
    • +
    + +

    Changes

    + +
      +
    • Updated sample projects to be easier to understand
    • +
    • Improved error messages to include full type names
    • +
    • Changed list bindings to default to optional so that you don't have to do this explicitly constantly
    • +
    + +

    Optimizations

    + +
      +
    • Fixed major performance issue for scenes that have a lot of transforms Re issue #188.
    • +
    • Fixed to avoid the extra performance costs of calling SetParent by directly passing the parent to the GameObject.Instantiate method issue #188
    • +
    + +

    Breaking changes

    + +
      +
    • Changed to require that the scope be explicitly set for some of the bind methods to avoid extremely common errors of accidentally leaving it as transient. Bind methods that are more like "look ups" (eg. FromMethod, FromComponentInParents, etc.) have it as optional, however bind methods that create new instances require that it be set explicitly
    • +
    • Moved commands and signals packages into a seperate repo
    • +
    • Renamed BindAllInterfaces to BindInterfacesTo and BindAllInterfacesAndSelf to BindInterfacesAndSelfTo to avoid the extremely common mistake of forgetting the To
    • +
    • Removed support for passing arguments to InjectGameObject and InstantiatePrefab methods (issue #125)
    • +
    • Removed UnityEventManager since it isn't core to keep things lightweight
    • +
    • Renamed the Resolve overload that included an ID to ResolveId to avoid the ambiguity with the non generic version of Resolve
    • +
    • Renamed the following construction methods. This was motivated by the fact that with the new construction methods it's unclear which ones are "look ups" versus creating new instances + +
        +
      • FromComponent => FromNewComponentOn
      • +
      • FromSiblingComponent => FromNewComponentSibling
      • +
      • FromGameObject => FromNewComponentOnNewGameObject
      • +
      • FromPrefab => FromComponentInNewPrefab
      • +
      • FromPrefabResource => FromComponentInNewPrefabResource
      • +
      • FromSubContainerResolve.ByPrefab => FromSubContainerResolve.ByNewPrefab
      • +
      +
    • +
    + +

    Bug fixes

    + +
      +
    • Fixed extremely rare bug that would cause an infinite loop when using complex subcontainer setups
    • +
    • Fixed to work with nunit test case attributes
    • +
    • Fixed to instantiate prefabs without always changing them to be active
    • +
    • Fixed WithArguments bind method to support passing null values
    • +
    • Fixed context menu to work properly when creating installers etc. issue #200
    • +
    • Fixed issue with ZenUtilInternal.InjectGameObjectForComponent method to support looking up non-monobehaviours.
    • +
    • Fixed NonLazy() bind method to work properly wtihin sub containers
    • +
    + +
    + +

    +4.7 (November 6, 2016)

    • Removed the concept of triggers in favour of just directly acting on the Signal to both subscribe and fire, since using Trigger was too much overhead for not enough gain
    • @@ -63,7 +138,10 @@

    • Improved validation of multi-scene setups using Contract Names to output better error messages
    -

    4.6 (October 23, 2016)

    +
    + +

    +4.6 (October 23, 2016)

    • Changed Validation to run at edit time rather than requiring that we enter play mode. This is significantly faster. Also added a hotkey to "validate then run" since it's fast enough to use as a pre-run check
    • @@ -83,7 +161,10 @@

    • Misc. bug fixes
    -

    4.5 (September 1, 2016)

    +
    + +

    +4.5 (September 1, 2016)

    • Fixed DiContainer.ResolveTypeAll() method to properly search in parent containers
    • @@ -92,7 +173,10 @@

    • Fixed exception that was occuring with FromMethod when using derived parameter types
    -

    4.4 (July 23, 2016)

    +
    + +

    +4.4 (July 23, 2016)

    • Changed the way installers are called from other installers, to allow strongly typed parameter passing
    • @@ -103,7 +187,10 @@

    • Bug fix - NonLazy method was not working properly when used with ByInstaller or ByMethod
    -

    4.3 (June 4, 2016)

    +
    + +

    +4.3 (June 4, 2016)

    • Changed to disallow using null with BindInstance by default, to catch these errors earlier
    • @@ -113,7 +200,10 @@

    • (bug fix) Custom factories were not validating in some cases
    -

    4.2 (May 30, 2016)

    +
    + +

    +4.2 (May 30, 2016)

    • Finally updated the documentation
    • @@ -126,7 +216,10 @@

    • (but) Fixed minor bug with validation
    -

    4.1 (May 15, 2016)

    +
    + +

    +4.1 (May 15, 2016)

    • Changed ResolveAll method to be optional by default, so it can return the empty list
    • @@ -148,7 +241,10 @@

    • Fix to non-unity build
    -

    4.0 (April 30, 2016)

    +
    + +

    +4.0 (April 30, 2016)

    • Added another property to CompositionRoot to specify installers as prefabs re #96
    • @@ -180,7 +276,10 @@

    • Removed support for binary version of Zenject. This was necessary since Zenject now needs to use some unity defines (eg. UNITY_EDITOR) which doesn't work in DLLs
    -

    3.11 (May 15, 2016)

    +
    + +

    +3.11 (May 15, 2016)

    • Bug fix - Calling Resolve<> or Instantiate<> inside an installer was causing the object to be injected twice
    • @@ -189,7 +288,10 @@

    • Fixed compiler errors with Unity 5.4
    -

    3.10 (March 26, 2016)

    +
    + +

    +3.10 (March 26, 2016)

    • Fixed to actually support Windows Store platform
    • @@ -197,7 +299,10 @@

    • Bug fix - OnlyInjectWhenActive flag did not work on root inactive game objects
    -

    3.9 (Feb 7, 2016)

    +
    + +

    +3.9 (Feb 7, 2016)

    • Added a lot more error checking when using the ToSingle bindings. It will no longer allow mixing different ToSingle types
    • @@ -209,13 +314,19 @@

    • Reorganized folder structure
    -

    3.8 (Feb 4, 2016)

    +
    + +

    +3.8 (Feb 4, 2016)

    • Changed back to only initializing the ProjectCompositionRoot when starting a scene with a SceneCompositionRoot rather than always starting it in every scene
    -

    3.7 (Jan 31, 2016)

    +
    + +

    +3.7 (Jan 31, 2016)

    • Changed to not bother parenting transforms to the CompositionRoot object by default (This is still optional with a checkbox however)
    • @@ -228,19 +339,28 @@

    • Fixed some unity-specific bind commands to play more nicely with interfaces
    -

    3.6 (Jan 24, 2016)

    +
    + +

    +3.6 (Jan 24, 2016)

    • Another change to signals to not require parameter types to the bind methods
    -

    3.5 (Jan 17, 2016)

    +
    + +

    +3.5 (Jan 17, 2016)

    • Made breaking change to require separate bind commands for signals and triggers, to allow adding different conditionals on each.
    -

    3.4 (Jan 7, 2016)

    +
    + +

    +3.4 (Jan 7, 2016)

    • Cleaned up directory structure
    • @@ -248,7 +368,10 @@

    • Fixes to the releases automation scripts
    -

    3.2 (December 20, 2015)

    +
    + +

    +3.2 (December 20, 2015)

    • Added the concept of "Commands" and "Signals". See documentation for details.
    • @@ -269,14 +392,20 @@

    • Fixed scene decorators to play more nicely with Unity's own way of handling LoadLevelAdditive. Decorated scenes are now organized in the scene heirarchy under scene headings just like when calling LoadLevelAdditive normally
    -

    3.1

    +
    + +

    +3.1

    • Changes related to upgrading to Unity 5.3
    • Fixed again to make zero heap allocations per frame
    -

    3.0

    +
    + +

    +3.0

    • Added much better support for nested containers. It now works more closely to what you might expect: Any parent dependencies are always inherited in sub-containers, even for optional injectables. Also removed BindScope and FallbackContainer since these were really just workarounds for this feature missing. Also added [InjectLocal] attribute for cases where you want to inject dependencies only from the local container.
    • @@ -287,20 +416,29 @@

    • Added automatic support for WebGL by marking constructors as [Inject]
    -

    2.8

    +
    + +

    +2.8

    • Fixed to properly use explicit default parameter values in Constructor/PostInject methods. For eg: public Foo(int bar = 5) should consider bar to be optional and use 5 if not resolved.
    -

    2.7

    +
    + +

    +2.7

    • Bug fix to ensure global composition root always gets initialized before the scene composition root
    • Changed scene decorators to use LoadLevelAdditive instead of LoadLevel to allow more complex setups involving potentially several decorators within decorators
    -

    2.6

    +
    + +

    +2.6

    • Added new bind methods: ToResource, ToTransientPrefabResource, ToSinglePrefabResource
    • @@ -315,7 +453,10 @@

    • Fixed bug with asteroids project which was causing exceptions to be thrown on the second run due to the use of tags
    -

    2.5

    +
    + +

    +2.5

    • Added support for circular dependencies in the PostInject method or as fields (just not constructor parameters)
    • @@ -325,13 +466,19 @@

    • Extracted IResolver and IBinder interfaces from DiContainer
    -

    2.4

    +
    + +

    +2.4

    • Refactored the way IFactory is used to be a lot cleaner. It now uses a kind of fluent syntax through its own bind method BindIFactory<>
    -

    2.3

    +
    + +

    +2.3

    • Added "ParentContexts" property to InjectContext, to allow very complex conditional bindings that involve potentially several identifiers, etc.
    • @@ -339,13 +486,19 @@

    • Added ability to build dlls for use in outside unity from the assembly build solution
    -

    2.2

    +
    + +

    +2.2

    • Changed the way installers invoke other installers. Previously you would Bind them to IInstaller and now you call Container.Install instead. This is better because it allows you to immediately call Rebind<> afterwards
    -

    2.1

    +
    + +

    +2.1

    • Simplified interface a bit more by moving more methods into DiContainer such as Inject and Instantiate. Moved all helper methods into extension methods for readability. Deleted FieldsInjector and Instantiator classes as part of this
    • @@ -357,7 +510,10 @@

    • Added 'InjectFullScene' flag to CompositionRoot to allow injecting across the entire unity scene instead of just objects underneath the CompositionRoot
    -

    2.0

    +
    + +

    +2.0

    • Added ability to inject dependencies via parameters to the [PostInject] method just like it does with constructors. Especially useful for MonoBehaviours.
    • @@ -370,7 +526,10 @@

    • Changed to allow using conditions to override a default binding. When multiple providers are found it will now try and use the one with conditions. So for example you can define a default with Container.Bind<IFoo>().ToSingle<Foo1>() and then override for specific classes with Container.Bind<IFoo>().ToSingle<Foo2>().WhenInjectedInto<Bar>(), etc.
    -

    1.19

    +
    + +

    +1.19

    • Upgraded to Unity 5
    • @@ -379,7 +538,10 @@

    • Added some helper methods to ZenEditorUtil for use by CI servers to validate all scenes
    -

    1.18

    +
    + +

    +1.18

    • Added minor optimizations to reduce per-frame allocation to zero
    • @@ -387,25 +549,37 @@

    • Minor bug fix with scene decorators, GameObjectInstantiator.
    -

    1.17

    +
    + +

    +1.17

    • Bug fix. Was not forwarding parameters correctly when instantiating objects from prefabs
    -

    1.16

    +
    + +

    +1.16

    • Removed the word 'ModestTree' from namespaces since Zenject is open source and not proprietary to the company ModestTree.
    -

    1.15

    +
    + +

    +1.15

    • Fixed bug with ToSinglePrefab which was causing it to create multiple instances when used in different bindings.
    -

    1.14

    +
    + +

    +1.14

    • Added flag to CompositionRoot for whether to inject into inactive game objects or ignore them completely
    • @@ -415,13 +589,19 @@

    • Added support for 'decorators', which can be used to add dependencies to another scene
    -

    1.13

    +
    + +

    +1.13

    • Minor bug fix to global composition root. Also fixed a few compiler warnings.
    -

    1.12

    +
    + +

    +1.12

    • Added Rebind<> method
    • @@ -434,20 +614,29 @@

    • Added IFixedTickable class to support unity FixedUpdate method
    -

    1.11

    +
    + +

    +1.11

    • Removed Fasterflect library to keep Zenject nice and lightweight (it was also causing issues on WP8)
    • Fixed bug related to singletons + object graph validation. Changed the way IDisposables are handled to be closer to the way IInitializable and ITickable are handled. Added method to BinderUntyped.
    -

    1.10

    +
    + +

    +1.10

    • Added custom editor for the Installers property of CompositionRoot to make re-ordering easier
    -

    1.09

    +
    + +

    +1.09

    • Added support for nested containers
    • @@ -456,7 +645,10 @@

    • Bug fixes
    -

    1.08

    +
    + +

    +1.08

    • Order of magnitude speed improvement by using more caching
    • @@ -464,14 +656,20 @@

    • Bug fixes
    -

    1.07

    +
    + +

    +1.07

    • Simplified API by removing the concept of modules in favour of just having installers instead (and add support for installers installing other installers)
    • Bug fixes
    -

    1.06

    +
    + +

    +1.06

    • Introduced concept of scene installer, renamed installers 'modules'
    • diff --git a/UnityProject/Assets/Zenject/Documentation/Signals.html b/UnityProject/Assets/Zenject/Documentation/Signals.html new file mode 100644 index 000000000..8a321a5b6 --- /dev/null +++ b/UnityProject/Assets/Zenject/Documentation/Signals.html @@ -0,0 +1,488 @@ + + + + + Signals.md - Grip + + + + + + +
      +
      + + + +
      +
      +
      +
      + +

      + + Signals.md +

      + +
      +

      +Signals

      + +

      +Motivation / Theory

      + +

      Given two classes A and B that need to communicate, your options are usually:

      + +
        +
      1. Directly call a method on B from A. In this case, A is strongly coupled with B.
      2. +
      3. Inverse the dependency by having B observe an event on A. In this case, B is strongly coupled with A.
      4. +
      + +

      So, often you have to ask yourself, should A know about B or should B know about A?

      + +

      As a third option, in some cases it might actually be better for neither one to know about the other. This way your code is kept as loosely coupled as possible. You can achieve this by having A and B interact with an intermediary object instead of directly with each other. In Zenject this intermediary object is called a Signal.

      + +

      +Signals Quick Start

      + +

      If you just want to get up and running immediately, see the following example which shows basic usage:

      + +
      public class UserJoinedSignal : Signal<string, UserJoinedSignal>
      +{
      +}
      +
      +public class Greeter
      +{
      +    public void SayHello(string userName)
      +    {
      +        Debug.Log("Hello " + userName + "!");
      +    }
      +}
      +
      +public class GameInitializer : IInitializable
      +{
      +    readonly UserJoinedSignal _userJoinedSignal;
      +
      +    public GameInitializer(UserJoinedSignal userJoinedSignal)
      +    {
      +        _userJoinedSignal = userJoinedSignal;
      +    }
      +
      +    public void Initialize()
      +    {
      +        _userJoinedSignal.Fire("Bob");
      +    }
      +}
      +
      +public class GameInstaller : MonoInstaller<GameInstaller>
      +{
      +    public override void InstallBindings()
      +    {
      +        Container.Bind<SignalManager>().AsSingle();
      +        Container.DeclareSignal<UserJoinedSignal>();
      +
      +        Container.BindSignal<string, UserJoinedSignal>()
      +            .To<Greeter>(x => x.SayHello).AsSingle();
      +
      +        Container.BindInterfacesTo<GameInitializer>().AsSingle();
      +    }
      +}
      + +

      To run, just create copy and paste the code above into a new file named GameInstaller then create an empty scene with a new scene context and attach the new installer.

      + +

      There are several ways of creating signal handlers. Another approach would be the following

      + +
      public class Greeter : IInitializable, IDisposable
      +{
      +    UserJoinedSignal _userJoinedSignal;
      +
      +    public Greeter(UserJoinedSignal userJoinedSignal)
      +    {
      +        _userJoinedSignal = userJoinedSignal;
      +    }
      +
      +    public void Initialize()
      +    {
      +        _userJoinedSignal += OnUserJoined;
      +    }
      +
      +    public void Dispose()
      +    {
      +        _userJoinedSignal -= OnUserJoined;
      +    }
      +
      +    void OnUserJoined(string username)
      +    {
      +        Debug.Log("Hello again " + username + "!");
      +    }
      +}
      +
      +public class GameInstaller : MonoInstaller<GameInstaller>
      +{
      +    public override void InstallBindings()
      +    {
      +        Container.Bind<SignalManager>().AsSingle();
      +        Container.DeclareSignal<UserJoinedSignal>();
      +
      +        Container.BindInterfacesTo<GameInitializer>().AsSingle();
      +        Container.BindInterfacesTo<Greeter>().AsSingle();
      +    }
      +}
      + +

      As you can see in the the above examples, you can either directly bind a handler method to a signal in an installer (first example) or you can have your signal handler attach and detach itself to the signal (second example).

      + +

      For more details on what's going on above see the following sections.

      + +

      +Signals Declaration

      + +

      Signals are defined like this:

      + +
      public class DoSomethingSignal : Signal<DoSomethingSignal>
      +{
      +}
      + +

      Note that the signal class must provide itself as a generic argument to the Signal base class.

      + +

      Classes that derive from Signal should always be left empty - their only purpose is to represent a single action.

      + +

      Any parameters passed along with the signal need to be included as more generic arguments:

      + +
      public class DoSomethingSignal : Signal<string, int, DoSomethingSignal>
      +{
      +}
      + +

      In this case, the signal would take a string and an int parameter.

      + +

      Then in an installer they must be declared somewhere:

      + +
      public override void InstallBindings()
      +{
      +    Container.DeclareSignal<DoSomethingSignal>();
      +}
      + +

      Note that the declaration is the same regardless of the parameter list.

      + +

      The format of the DeclareSignal statement is the following:

      + +
      +Container.DeclareSignal<SignalType>()
      +    .WithId(Identifier)
      +    .RequireHandler()
      +    .When(Condition);
      +
      + +

      The When Condition can be any Zenject condition just like any other binding (see Zenject docs for details). When using installer handlers (see below) this can be useful to restrict which classes are allowed to fire the signal

      + +

      The RequireHandler() method is optional. If not included, then the signal will be allowed to fire with zero handlers attached. If RequireHandler() is added to the binding, then an exception will be thrown if the signal is fired and there isn't any handlers attached.

      + +

      +Signal Firing

      + +

      Firing the signal is as simple as just adding a reference to it and calling Fire

      + +
      public class Bar : ITickable
      +{
      +    readonly DoSomethingSignal _signal;
      +
      +    public Bar(DoSomethingSignal signal)
      +    {
      +        _signal = signal;
      +    }
      +
      +    public void DoSomething()
      +    {
      +        _signal.Fire();
      +    }
      +}
      + +

      +Signal Handlers

      + +

      There are three ways of adding handlers to a signal:

      + +
        +
      1. C# events
      2. +
      3. UniRx Stream
      4. +
      5. Installer Binding
      6. +
      + +

      +C# Event Signal Handler

      + +

      Probably the easiest method to add a handler is to add it directly from within the handler class. For example:

      + +
      public class Greeter : IInitializable, IDisposable
      +{
      +    AppStartedSignal _appStartedSignal;
      +
      +    public Greeter(AppStartedSignal appStartedSignal)
      +    {
      +        _appStartedSignal = appStartedSignal;
      +    }
      +
      +    public void Initialize()
      +    {
      +        _appStartedSignal += OnAppStarted;
      +    }
      +
      +    public void Dispose()
      +    {
      +        _appStartedSignal -= OnAppStarted;
      +    }
      +
      +    void OnAppStarted()
      +    {
      +        Debug.Log("Hello world!");
      +    }
      +}
      + +

      Or, equivalently:

      + +
      public class Greeter : IInitializable, IDisposable
      +{
      +    AppStartedSignal _appStartedSignal;
      +
      +    public Greeter(AppStartedSignal appStartedSignal)
      +    {
      +        _appStartedSignal = appStartedSignal;
      +    }
      +
      +    public void Initialize()
      +    {
      +        _appStartedSignal.Listen(OnAppStarted);
      +    }
      +
      +    public void Dispose()
      +    {
      +        _appStartedSignal.Unlisten(OnAppStarted);
      +    }
      +
      +    void OnAppStarted()
      +    {
      +        Debug.Log("Hello world!");
      +    }
      +}
      + +

      +UniRx Signal Handler

      + +

      If you are a fan of UniRx, as we are, then you might also want to treat the signal as a UniRx stream. For example:

      + +
      public class Greeter : MonoBehaviour
      +{
      +    [Inject]
      +    AppStartedSignal _appStartedSignal;
      +
      +    public void Start()
      +    {
      +        _appStartedSignal.Stream.Subscribe(OnAppStarted).AddTo(this);
      +    }
      +
      +    void OnAppStarted()
      +    {
      +        Debug.Log("Hello World!");
      +    }
      +}
      + +

      NOTE: Integration with UniRx is disabled by default. To enable, you must add the define ZEN_SIGNALS_ADD_UNIRX to your project, which you can do by selecting Edit -> Project Settings -> Player and then adding ZEN_SIGNALS_ADD_UNIRX in the "Scripting Define Symbols" section

      + +

      +Installer Binding Signal Handler

      + +

      Finally, you can also add signal handlers directly within an installer. For example:

      + +
      public class Greeter1
      +{
      +    public void SayHello()
      +    {
      +        Debug.Log("Hello!");
      +    }
      +}
      +
      +public class GreeterInstaller : MonoInstaller<GreeterInstaller>
      +{
      +    public override void InstallBindings()
      +    {
      +        Container.BindSignal<AppStartedSignal>()
      +            .To<Greeter1>(x => x.SayHello).AsSingle();
      +    }
      +}
      + +

      Or, when the signal has parameters:

      + +
      public class Greeter1
      +{
      +    public void SayHello(string name)
      +    {
      +        Debug.Log("Hello " + name + "!");
      +    }
      +}
      +
      +public class GreeterInstaller : MonoInstaller<GreeterInstaller>
      +{
      +    public override void InstallBindings()
      +    {
      +        Container.BindSignal<string, AppStartedSignal>()
      +            .To<Greeter1>(x => x.SayHello).AsSingle();
      +    }
      +}
      + +

      This approach has the following advantages:

      + +
        +
      • More flexible, because you can wire it up in the installer and can have multiple installer configurations
      • +
      • More loosely coupled, because the handler class can remain completely ignorant of the signal
      • +
      • Less error prone, because you don't have to remember to unsubscribe. The signal will automatically be unsubscribed when the 'context' is disposed of. This means that if you add a handler within a sub-container, the handler will automatically unsubscribe when the sub-container is disposed of
      • +
      • You can more easily control which classes are allowed to fire the signal. You can do this by adding a When() conditional to the declaration. (You can't do this with the other handler types because the listener also needs access to the signal to add itself to it)
      • +
      + +

      Which approach to signal handlers depends on the specifics of each case and personal preference.

      + +

      +Signals With Subcontainers

      + +

      One interesting feature of signals is that the signal handlers do not need to be in the same container as the signal declaration. The declaration can either be in the same container, a parent container, or a sub-container, and it should trigger the handlers regardless of where they are declared. Note that the declaration will however determine which container the signal can be fired from (the signal itself will be accessible as a dependency for the container it is declared in and all sub-containers just like other bindings)

      + +

      For example, you can declare a signal in your ProjectContext and then add signal handlers for each particular scene. Then, when each scene exits, the signal handler that was added in that scene will no longer be called when the signal is fired.

      + +

      Or, you could add signal handlers in the ProjectContext and then declare the signal in some particular scene.

      + +

      For example, You might use this to implement your GUI entirely in its own scene, loaded alongside the main backend scene. Then you could have the GUI scene strictly fire Signals, which would then have method bindings in the game scene.

      + +

      Something else you'll have noticed in the examples above is that we also needed to install the SignalManager class:

      + +
      Container.Bind<SignalManager>().AsSingle();
      + +

      This needs to be installed somewhere, and it doesn't matter which container this is installed to, as long as the container is "above" or equal to every place that either signals or signal handlers are used. Therefore, the ideal place to put this line would be in the ProjectContext since this is the highest level container that exists.

      + +

      +Signals With Identifiers

      + +

      If you want to define multiple instances of the same signal, you would need to use identifiers. This works identically to how normal zenject binding identifiers work. For example:

      + +
      Container.DeclareSignal<FooSignal>().WithId("foo");
      + +

      Then for installer handlers:

      + +
      Container.BindSignal<FooSignal>().WithId("foo").To<Bar>(x => x.DoSomething).AsSingle();
      + +

      Then to access it to fire it, or to add a C# event / unirx handlers:

      + +
      public class Qux
      +{
      +    FooSignal _signal;
      +
      +    public Qux(
      +        [Inject(Id = "foo")] FooSignal signal)
      +    {
      +        _signal = signal;
      +    }
      +
      +    public void Run()
      +    {
      +        _signal.Fire();
      +    }
      +}
      + +
      +
      +
      +
      +
      + + + +
      +
       
      +
      + + \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Documentation/Signals.html.meta b/UnityProject/Assets/Zenject/Documentation/Signals.html.meta new file mode 100644 index 000000000..52e6bb886 --- /dev/null +++ b/UnityProject/Assets/Zenject/Documentation/Signals.html.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 116b60ec6a2c8ae40b200dd20f8ef919 +timeCreated: 1487002135 +licenseType: Free +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/Documentation/SubContainers.html b/UnityProject/Assets/Zenject/Documentation/SubContainers.html index 9427eea68..1cdb01c66 100644 --- a/UnityProject/Assets/Zenject/Documentation/SubContainers.html +++ b/UnityProject/Assets/Zenject/Documentation/SubContainers.html @@ -36,18 +36,18 @@
      - +
      - +

      SubContainers.md

      - +

      Sub-Containers And Facades

      @@ -56,7 +56,7 @@

      Another example might be if you are designing an open-world space ship game, you might want each space ship to have it's own container that contains all the class instances responsible for running that specific spaceship.

      -

      This is actually how global bindings work. There is one global container for the entire application, and when a unity scene starts up, it creates a new sub-container "underneath" the global container. All the bindings that you add in your scene MonoInstaller are bound to your sub-container. This allows the dependencies in your scene to automatically get injected with global bindings, because sub-containers automatically inherit all the bindings in its parent (and grandparent, etc.).

      +

      This is actually how ProjectContext bindings work. There is one container for the entire project, and when a unity scene starts up, it container within each SceneContext is created "underneath" the ProjectContext container. All the bindings that you add in your scene MonoInstaller are bound to your SceneContext container. This allows the dependencies in your scene to automatically get injected with ProjectContext bindings, because sub-containers automatically inherit all the bindings in their parent (and grandparent, etc.).

      A common design pattern that we like to use in relation to sub-containers is the Facade pattern. This pattern is used to abstract away a related group of dependencies so that it can be used at a higher level when used by other modules in the code base. This is relevant here because often when you are defining sub-containers in your application it is very useful to also define a Facade class that is used to interact with this sub-container as a whole. So, to apply it to the spaceship example above, you might have a SpaceshipFacade class that represents very high-level operations on a spaceship such as "Start Engine", "Take Damage", "Fly to destination", etc. And then internally, the SpaceshipFacade class can delegate the specific handling of all the parts of these requests to the relevant single-responsibility dependencies that exist within the sub-container.

      @@ -67,9 +67,9 @@

      public class Greeter
       {
      -    readonly string _message;
      +    readonly string _message;
       
      -    public Greeter(string message)
      +    public Greeter(string message)
           {
               _message = message;
           }
      @@ -80,11 +80,11 @@ 

      } } -public class GameController : IInitializable +public class GameController : IInitializable { - readonly Greeter _greeter; + readonly Greeter _greeter; - public GameController(Greeter greeter) + public GameController(Greeter greeter) { _greeter = greeter; } @@ -95,15 +95,15 @@

      } } -public class TestInstaller : MonoInstaller +public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfaces<GameController>().To<GameController>().AsSingle(); + Container.BindInterfacesTo<GameController>().AsSingle(); Container.Bind<Greeter>().FromSubContainerResolve().ByMethod(InstallGreeter).AsSingle(); } - void InstallGreeter(DiContainer subContainer) + void InstallGreeter(DiContainer subContainer) { subContainer.Bind<Greeter>().AsSingle(); subContainer.BindInstance("Hello world!"); @@ -112,16 +112,16 @@

      The important thing to understand here is that any bindings that we add inside the InstallGreeter method will only be visible to objects within this sub-container. The only exception is the Facade class (in this case, Greeter) since it is bound to the parent container using the FromSubContainerResolve binding. In other words, in this example, the string "Hello World" is only visible by the Greeter class.

      -

      Note that you should always add a bind statement for whatever class is given to FromSubContainerResolve, otherwise this will fail.

      +

      Note that you should always add a bind statement for whatever class is given to FromSubContainerResolve within the sub-container install method - otherwise you'll get exceptions and validation will fail.

      -

      Note also that it is often better to use ByInstaller instead of ByMethod. This is because when you use ByMethod it is easy to accidentally reference the Container instead of the subContainer. Also, by using ByInstaller you can pass arguments into the Installer itself.

      +

      Note also that unlike the above example, it is often better to use ByInstaller instead of ByMethod. This is because when you use ByMethod it is easy to accidentally reference the Container instead of the subContainer. Also, by using ByInstaller you can pass arguments into the Installer itself.

      Using IInitializable / ITickable / IDisposable within Sub-Containers

      One issue with the Hello World example above is that if I wanted to add some ITickable's or IInitializable's or IDisposable's to my sub-container it would not work. For example, I might try doing this:

      -
      public class GoodbyeHandler : IDisposable
      +
      public class GoodbyeHandler : IDisposable
       {
           public void Dispose()
           {
      @@ -129,7 +129,7 @@ 

      } } -public class HelloHandler : IInitializable +public class HelloHandler : IInitializable { public void Initialize() { @@ -145,25 +145,25 @@

      } } -public class TestInstaller : MonoInstaller +public class TestInstaller : MonoInstaller { public override void InstallBindings() { Container.Bind<Greeter>().FromSubContainerResolve().ByMethod(InstallGreeter).AsSingle().NonLazy(); } - void InstallGreeter(DiContainer subContainer) + void InstallGreeter(DiContainer subContainer) { subContainer.Bind<Greeter>().AsSingle(); - subContainer.BindAllInterfaces<GoodbyeHandler>().To<GoodbyeHandler>().AsSingle(); - subContainer.BindAllInterfaces<HelloHandler>().To<HelloHandler>().AsSingle(); + subContainer.BindInterfacesTo<GoodbyeHandler>().AsSingle(); + subContainer.BindInterfacesTo<HelloHandler>().AsSingle(); } }

      However, while we will find that our Greeter class is created (due to the fact we're using NonLazy) and the text "Created Greeter!" is printed to the console, the Hello and Goodbye messages are not. To get this working we need to change it to the following:

      -
      public class GoodbyeHandler : IDisposable
      +
      public class GoodbyeHandler : IDisposable
       {
           public void Dispose()
           {
      @@ -171,7 +171,7 @@ 

      } } -public class HelloHandler : IInitializable +public class HelloHandler : IInitializable { public void Initialize() { @@ -179,7 +179,7 @@

      } } -public class Greeter : Kernel +public class Greeter : Kernel { public Greeter() { @@ -187,32 +187,32 @@

      } } -public class TestInstaller : MonoInstaller +public class TestInstaller : MonoInstaller { public override void InstallBindings() { - Container.BindAllInterfacesAndSelf<Greeter>() - .To<Greeter>().FromSubContainerResolve().ByMethod(InstallGreeter).AsSingle().NonLazy(); + Container.BindInterfacesAndSelfTo<Greeter>() + .FromSubContainerResolve().ByMethod(InstallGreeter).AsSingle().NonLazy(); } - void InstallGreeter(DiContainer subContainer) + void InstallGreeter(DiContainer subContainer) { subContainer.Bind<Greeter>().AsSingle(); - subContainer.BindAllInterfaces<GoodbyeHandler>().To<GoodbyeHandler>().AsSingle(); - subContainer.BindAllInterfaces<HelloHandler>().To<HelloHandler>().AsSingle(); + subContainer.BindInterfacesTo<GoodbyeHandler>().AsSingle(); + subContainer.BindInterfacesTo<HelloHandler>().AsSingle(); } }

      Now if we run it, we should see the Hello message, then if we stop playing we should see the Goodbye message.

      -

      The reason this works is because we are now binding IInitializable, IDisposable, and ITickable on the root container to the Greeter class given by Container.BindAllInterfacesAndSelf<Greeter>().To<Greeter>(). Greeter now inherits from Kernel, which inherits from all these interfaces and also handles forwarding these calls to the IInitializable's / ITickable's / IDisposable's in our sub container. Note that we use AsSingle() here, which is important otherwise it will create a new sub-container for every interface which is not what we want.

      +

      The reason this works is because we are now binding IInitializable, IDisposable, and ITickable on the root container to the Greeter class given by Container.BindInterfacesAndSelfTo<Greeter>(). Greeter now inherits from Kernel, which inherits from all these interfaces and also handles forwarding these calls to the IInitializable's / ITickable's / IDisposable's in our sub container. Note that we use AsSingle() here, which is important otherwise it will create a new sub-container for every interface which is not what we want.

      Creating Sub-Containers on GameObject's by using Game Object Context

      -

      Another issue with the sub-container hello world example above is that it does not work very well for MonoBehaviour classes. There is nothing preventing us from adding MonoBehaviour bindings such as FromPrefab, FromGameObject, etc. to our sub-container, however these will cause these new game objects to be added to the root of the scene heirarchy, so we'll have to manually track the lifetime of these objects ourselves by calling GameObject.Destroy on them when the Facade is destroyed. Also, there is no way to have GameObject's that exist in our scene at the start but also exist within our sub-container. These problems can be solved by using Game Object Context.

      +

      Another issue with the sub-container hello world example above is that it does not work very well for MonoBehaviour classes. There is nothing preventing us from adding MonoBehaviour bindings such as FromComponentInNewPrefab, FromNewComponentOnNewGameObject, etc. to our sub-container, however these will cause these new game objects to be added to the root of the scene heirarchy, so we'll have to manually track the lifetime of these objects ourselves by calling GameObject.Destroy on them when the Facade is destroyed. Also, there is no way to have GameObject's that exist in our scene at the start but also exist within our sub-container. These problems can be solved by using Game Object Context.

      For this example, let's try to actually implement something similar to the open world space ship game described in the sub-container introduction:

      @@ -224,12 +224,12 @@

      using Zenject;
       using UnityEngine;
       
      -public class Ship : MonoBehaviour
      +public class Ship : MonoBehaviour
       {
      -    ShipHealthHandler _healthHandler;
      +    ShipHealthHandler _healthHandler;
       
           [Inject]
      -    public void Construct(ShipHealthHandler healthHandler)
      +    public void Construct(ShipHealthHandler healthHandler)
           {
               _healthHandler = healthHandler;
           }
      @@ -243,11 +243,11 @@ 

      using UnityEngine;
       using Zenject;
       
      -public class GameRunner : ITickable
      +public class GameRunner : ITickable
       {
      -    readonly Ship _ship;
      +    readonly Ship _ship;
       
      -    public GameRunner(Ship ship)
      +    public GameRunner(Ship ship)
           {
               _ship = ship;
           }
      @@ -261,24 +261,24 @@ 

      } }

      -
      public class GameInstaller : MonoInstaller
      +
      public class GameInstaller : MonoInstaller
       {
           public override void InstallBindings()
           {
      -        Container.BindAllInterfaces<GameRunner>().To<GameRunner>().AsSingle();
      +        Container.BindInterfacesTo<GameRunner>().AsSingle();
           }
       }
      using Zenject;
       using UnityEngine;
       
      -public class ShipHealthHandler : MonoBehaviour
      +public class ShipHealthHandler : MonoBehaviour
       {
      -    float _health = 100;
      +    float _health = 100;
       
           public void OnGUI()
           {
      -        GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 200, 100), "Health: " + _health);
      +        GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 200, 100), "Health: " + _health);
           }
       
           public void TakeDamage(float damage)
      @@ -290,10 +290,10 @@ 

      using UnityEngine;
       using System.Collections;
       
      -public class ShipInputHandler : MonoBehaviour
      +public class ShipInputHandler : MonoBehaviour
       {
           [SerializeField]
      -    float _speed = 2;
      +    float _speed = 2;
       
           public void Update()
           {
      @@ -325,7 +325,7 @@ 

    • Your scene should look like this:
    -

    Ship Facade Example

    +

    Ship Facade Example

    • The idea here is that everything at or underneath the Ship game object should be considered inside it's own sub-container. When we're done, we should be able to add multiple ships to our scene, each with their own components ShipHealthHandler, ShipInputHandler, etc. that can treat each other as singletons.
    • @@ -360,16 +360,16 @@

      • First, create a prefab for the entire Ship GameObject that we created above and then delete it from the Scene.
      • -
      • Then just change
      • +
      • Then just add the following changes
      -
      public class GameRunner : ITickable
      +
      public class GameRunner : ITickable
       {
      -    readonly Ship.Factory _shipFactory;
      +    readonly Ship.Factory _shipFactory;
       
      -    Vector3 lastShipPosition;
      +    Vector3 lastShipPosition;
       
      -    public GameRunner(Ship.Factory shipFactory)
      +    public GameRunner(Ship.Factory shipFactory)
           {
               _shipFactory = shipFactory;
           }
      @@ -378,7 +378,7 @@ 

      { if (Input.GetKeyDown(KeyCode.Space)) { - var ship = _shipFactory.Create(); + var ship = _shipFactory.Create(); ship.transform.position = lastShipPosition; lastShipPosition += Vector3.forward * 2; @@ -386,16 +386,16 @@

      } }

      -
      public class GameInstaller : MonoInstaller
      +
      public class GameInstaller : MonoInstaller
       {
           [SerializeField]
      -    GameObject ShipPrefab;
      +    GameObject ShipPrefab;
       
           public override void InstallBindings()
           {
      -        Container.BindAllInterfaces<GameRunner>().To<GameRunner>().AsSingle();
      +        Container.BindInterfacesTo<GameRunner>().AsSingle();
       
      -        Container.BindFactory<Ship, Ship.Factory>().FromSubContainerResolve().ByPrefab(ShipPrefab);
      +        Container.BindFactory<Ship, Ship.Factory>().FromSubContainerResolve().ByNewPrefab(ShipPrefab);
           }
       }
      @@ -413,13 +413,13 @@

    • Change our classes to the following:
    -
    public class GameRunner : ITickable
    +
    public class GameRunner : ITickable
     {
    -    readonly Ship.Factory _shipFactory;
    +    readonly Ship.Factory _shipFactory;
     
    -    Vector3 lastShipPosition;
    +    Vector3 lastShipPosition;
     
    -    public GameRunner(Ship.Factory shipFactory)
    +    public GameRunner(Ship.Factory shipFactory)
         {
             _shipFactory = shipFactory;
         }
    @@ -428,7 +428,7 @@ 

    { if (Input.GetKeyDown(KeyCode.Space)) { - var ship = _shipFactory.Create(Random.RandomRange(2, 20)); + var ship = _shipFactory.Create(Random.RandomRange(2, 20)); ship.transform.position = lastShipPosition; lastShipPosition += Vector3.forward * 2; @@ -436,28 +436,28 @@

    } }

    -
    public class GameInstaller : MonoInstaller
    +
    public class GameInstaller : MonoInstaller
     {
         [SerializeField]
    -    GameObject ShipPrefab;
    +    GameObject ShipPrefab;
     
         public override void InstallBindings()
         {
    -        Container.BindAllInterfaces<GameRunner>().To<GameRunner>().AsSingle();
    +        Container.BindInterfacesTo<GameRunner>().AsSingle();
     
    -        Container.BindFactory<float, Ship, Ship.Factory>().FromSubContainerResolve().ByPrefab<ShipInstaller>(ShipPrefab);
    +        Container.BindFactory<float, Ship, Ship.Factory>().FromSubContainerResolve().ByNewPrefab<ShipInstaller>(ShipPrefab);
         }
     }
    using Zenject;
     using UnityEngine;
     
    -public class Ship : MonoBehaviour
    +public class Ship : MonoBehaviour
     {
    -    ShipHealthHandler _healthHandler;
    +    ShipHealthHandler _healthHandler;
     
         [Inject]
    -    public void Construct(ShipHealthHandler healthHandler)
    +    public void Construct(ShipHealthHandler healthHandler)
         {
             _healthHandler = healthHandler;
         }
    @@ -467,7 +467,7 @@ 

    _healthHandler.TakeDamage(damage); } - public class Factory : Factory<float, Ship> + public class Factory : Factory<float, Ship> { } }

    @@ -476,10 +476,10 @@

    using System.Collections; using Zenject; -public class ShipInputHandler : MonoBehaviour +public class ShipInputHandler : MonoBehaviour { [Inject] - float _speed; + float _speed; public void Update() { @@ -500,10 +500,10 @@

    using System;
     using Zenject;
     
    -public class ShipInstaller : MonoInstaller
    +public class ShipInstaller : MonoInstaller
     {
         [Inject]
    -    float _speed;
    +    float _speed;
     
         public override void InstallBindings()
         {
    @@ -530,11 +530,11 @@ 

    using Zenject; using UnityEngine; -public class ShipInstaller : MonoInstaller +public class ShipInstaller : MonoInstaller { [SerializeField] [InjectOptional] - float _speed; + float _speed; public override void InstallBindings() { @@ -544,7 +544,7 @@

    This way, you can drop the Ship prefab into the scene and control the speed in the inspector, but you can also create them dynamically and pass the speed into the factory as a parameter.

    -

    For a more real-world example see the "Sample2" demo project which makes heavy use of Game Object Contexts.

    +

    For a more real-world example see the SpaceFighter sample project which makes heavy use of Game Object Contexts.

    @@ -552,7 +552,7 @@

    - +
     
    @@ -622,4 +622,4 @@

    } - + \ No newline at end of file diff --git a/UnityProject/Assets/Zenject/Documentation/WritingAutomatedTests.html b/UnityProject/Assets/Zenject/Documentation/WritingAutomatedTests.html index 6933d45e1..fa76be713 100644 --- a/UnityProject/Assets/Zenject/Documentation/WritingAutomatedTests.html +++ b/UnityProject/Assets/Zenject/Documentation/WritingAutomatedTests.html @@ -72,17 +72,17 @@

    Log = ""; } - public string Log + public string Log { get; - private set; + private set; } public void Write(string value) { if (value == null) { - throw new ArgumentException(); + throw new ArgumentException(); } Log += value; @@ -96,7 +96,7 @@

    using NUnit.Framework; [TestFixture] -public class TestLogger : ZenjectUnitTestFixture +public class TestLogger : ZenjectUnitTestFixture { [SetUp] public void CommonInstall() @@ -107,7 +107,7 @@

    [Test] public void TestInitialValues() { - var logger = Container.Resolve<Logger>(); + var logger = Container.Resolve<Logger>(); Assert.That(logger.Log == ""); } @@ -115,7 +115,7 @@

    [Test] public void TestFirstEntry() { - var logger = Container.Resolve<Logger>(); + var logger = Container.Resolve<Logger>(); logger.Write("foo"); Assert.That(logger.Log == "foo"); @@ -124,7 +124,7 @@

    [Test] public void TestAppend() { - var logger = Container.Resolve<Logger>(); + var logger = Container.Resolve<Logger>(); logger.Write("foo"); logger.Write("bar"); @@ -136,7 +136,7 @@

    [ExpectedException] public void TestNullValue() { - var logger = Container.Resolve<Logger>(); + var logger = Container.Resolve<Logger>(); logger.Write(null); } @@ -147,11 +147,11 @@

    As you can see above, this approach is very basic and just involves inheriting from the ZenjectUnitTestFixture class. All this helper class does is ensure that a new Container is re-created before each test method is called. That's it. This is the entire code for it:

    -
    public abstract class ZenjectUnitTestFixture
    +
    public abstract class ZenjectUnitTestFixture
     {
    -    DiContainer _container;
    +    DiContainer _container;
     
    -    protected DiContainer Container
    +    protected DiContainer Container
         {
             get
             {
    @@ -162,7 +162,7 @@ 

    [SetUp] public virtual void Setup() { - _container = new DiContainer(); + _container = new DiContainer(); } }

    @@ -175,7 +175,7 @@

    using NUnit.Framework; [TestFixture] -public class TestLogger : ZenjectUnitTestFixture +public class TestLogger : ZenjectUnitTestFixture { [SetUp] public void CommonInstall() @@ -185,7 +185,7 @@

    } [Inject] - Logger _logger; + Logger _logger; [Test] public void TestInitialValues() @@ -220,18 +220,18 @@

    Integration Testss

    -

    Integration tests, on the other hand, are executed in a similar environment to the scenes in your project. A SceneContext and ProjectContext are created, so you can invoke MonoInstallers, ScriptableObjectInstallers, etc. as necessary.

    +

    Integration tests, on the other hand, are executed in a similar environment to the scenes in your project. Unlike ZenjectUnitTestFixture, a SceneContext and ProjectContext are created for each test, so your code will run in similar way that it would normally. For example, any bindings to IInitializable and IDisposable will be executed how you expect.

    Let's pull from the included sample project and test one of the classes there (AsteroidManager):

    [TestFixture]
    -public class TestAsteroidManager : ZenjectIntegrationTestFixture
    +public class TestAsteroidManager : ZenjectIntegrationTestFixture
     {
         [SetUp]
         public void CommonInstall()
         {
             GameSettingsInstaller.InstallFromResource(Container);
    -        var gameSettings = Container.Resolve<GameInstaller.Settings>();
    +        var gameSettings = Container.Resolve<GameInstaller.Settings>();
             Container.Bind<AsteroidManager>().AsSingle();
             Container.BindFactory<Asteroid, Asteroid.Factory>().FromPrefab(gameSettings.AsteroidPrefab);
             Container.Bind<Camera>().WithId("Main").FromGameObject();
    @@ -241,10 +241,10 @@ 

    } [Inject] - AsteroidManager _asteroidManager; + AsteroidManager _asteroidManager; [Inject] - AsteroidManager.Settings _asteroidManagerSettings; + AsteroidManager.Settings _asteroidManagerSettings; [Test] [ValidateOnly] @@ -276,7 +276,7 @@

    When you start running a test through Unity's EditorTestRunner window, Unity will open up a new empty scene and run the tests there, and then Unity will re-open your previously open scenes once the tests complete. This is great because any new game objects you create will not affect any currently open scenes (more details here.)

    -

    Before each one of your test methods are run, ZenjectIntegrationTestFixture will create a new SceneContext in this empty scene. The Container that you reference in your tests refers to the container used by this new temporary SceneContext. After you have finished installing all your bindings on the Container, either by using [SetUp] methods or from within your test method, you need to call ZenjectIntegrationTestFixture.Initialize(). This will resolve all the NonLazy bindings and also trigger IInitializable.Initialize for all classes that are bound to IInitializable. If you have common fields on your test marked with [Inject] then these fields are also filled in at this time. Alternatively, you can diretcly call Container.Resolve<> from within your test methods to get the classes you want to run tests on.

    +

    Before each one of your test methods are run, ZenjectIntegrationTestFixture will create a new SceneContext in this empty scene. The Container that you reference in your tests refers to the container used by this new temporary SceneContext. After you have finished installing all your bindings on the Container, either by using [SetUp] methods or from within your test method, you need to call ZenjectIntegrationTestFixture.Initialize(). This will resolve all the NonLazy bindings and also trigger IInitializable.Initialize for all classes that are bound to IInitializable. If you have common fields on your test marked with [Inject] then these fields are also filled in at this time. Alternatively, you can directly call Container.Resolve<> from within your test methods to get the classes you want to run tests on.

    You can also run zenject validation on your test by adding a [ValidateOnly] attribute above your test method (as shown in example above). This will cause the test to not instantiate any of your bindings and instead just verify that the configuration of your Container is valid. However, you could also just as easily rely on configuration errors to be caught when running normal tests too, so it probably has limited use for you.

    From a33a3cd9bcda6b485f288edba2aab9e305988e85 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 13 Feb 2017 13:00:26 -0400 Subject: [PATCH 61/62] Moved asteroid unit test into test directory --- UnityProject/.gitignore | 1 + .../Tests.meta => IntegrationTests/Asteroids.meta} | 0 .../IntegrationTests/Asteroids/Editor.meta | 9 +++++++++ .../Asteroids/Editor}/TestAsteroidManager.cs | 0 .../Asteroids/Editor}/TestAsteroidManager.cs.meta | 0 5 files changed, 10 insertions(+) rename UnityProject/Assets/Zenject/OptionalExtras/{SampleGame1 (Beginner)/Scripts/Editor/Tests.meta => IntegrationTests/Asteroids.meta} (100%) create mode 100644 UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids/Editor.meta rename UnityProject/Assets/Zenject/OptionalExtras/{SampleGame1 (Beginner)/Scripts/Editor/Tests => IntegrationTests/Asteroids/Editor}/TestAsteroidManager.cs (100%) rename UnityProject/Assets/Zenject/OptionalExtras/{SampleGame1 (Beginner)/Scripts/Editor/Tests => IntegrationTests/Asteroids/Editor}/TestAsteroidManager.cs.meta (100%) diff --git a/UnityProject/.gitignore b/UnityProject/.gitignore index 0604ccc02..d76fd2987 100644 --- a/UnityProject/.gitignore +++ b/UnityProject/.gitignore @@ -2,6 +2,7 @@ /Temp /Library /Build +/Builds /obj #ignoring pidb, they are just code completion caching data according to: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids.meta diff --git a/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids/Editor.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids/Editor.meta new file mode 100644 index 000000000..1459316a2 --- /dev/null +++ b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c8ad8301a16253940acf9757b11b241f +folderAsset: yes +timeCreated: 1487005450 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids/Editor/TestAsteroidManager.cs similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids/Editor/TestAsteroidManager.cs diff --git a/UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs.meta b/UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids/Editor/TestAsteroidManager.cs.meta similarity index 100% rename from UnityProject/Assets/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Editor/Tests/TestAsteroidManager.cs.meta rename to UnityProject/Assets/Zenject/OptionalExtras/IntegrationTests/Asteroids/Editor/TestAsteroidManager.cs.meta From e8ad8e5c0cdbd824cb9757acd49879b715701b61 Mon Sep 17 00:00:00 2001 From: Steve Vermeulen Date: Mon, 13 Feb 2017 14:02:50 -0400 Subject: [PATCH 62/62] Tweak to release notes --- Documentation/ReleaseNotes.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Documentation/ReleaseNotes.md b/Documentation/ReleaseNotes.md index dc439377e..5ba180db9 100644 --- a/Documentation/ReleaseNotes.md +++ b/Documentation/ReleaseNotes.md @@ -3,6 +3,10 @@ ###5.0 (February 11, 2017) +Summary + +Notable parts of this release includes the long awaited support for Memory Pools and support for late resolve via Lazy<> construct. It also includes some API breaking changes to make it easier for new users. Some of the bind methods were renamed to better represent what they mean, and in some cases the scope is now required to be made explicit, to avoid accidentally using transient scope. Finally, there was also some significant performance improvements for when using Zenject in scenes with many transforms. + New Features - Added Lazy<> construct so that you can have the resolve occur upon first usage - Added menu option "Validate All Active Scenes" @@ -20,14 +24,7 @@ Changes - Updated sample projects to be easier to understand - Improved error messages to include full type names - Changed list bindings to default to optional so that you don't have to do this explicitly constantly - -Optimizations -- Fixed major performance issue for scenes that have a lot of transforms Re issue #188. -- Fixed to avoid the extra performance costs of calling SetParent by directly passing the parent to the GameObject.Instantiate method issue #188 - -Breaking changes - Changed to require that the scope be explicitly set for some of the bind methods to avoid extremely common errors of accidentally leaving it as transient. Bind methods that are more like "look ups" (eg. FromMethod, FromComponentInParents, etc.) have it as optional, however bind methods that create new instances require that it be set explicitly -- Moved commands and signals packages into a seperate repo - Renamed BindAllInterfaces to BindInterfacesTo and BindAllInterfacesAndSelf to BindInterfacesAndSelfTo to avoid the extremely common mistake of forgetting the To - Removed support for passing arguments to InjectGameObject and InstantiatePrefab methods (issue #125) - Removed UnityEventManager since it isn't core to keep things lightweight @@ -41,6 +38,8 @@ Breaking changes - FromSubContainerResolve.ByPrefab => FromSubContainerResolve.ByNewPrefab Bug fixes +- (optimization) Fixed major performance issue for scenes that have a lot of transforms Re issue #188. +- (optimization) Fixed to avoid the extra performance costs of calling SetParent by directly passing the parent to the GameObject.Instantiate method issue #188 - Fixed extremely rare bug that would cause an infinite loop when using complex subcontainer setups - Fixed to work with nunit test case attributes - Fixed to instantiate prefabs without always changing them to be active