Update Project

This commit is contained in:
2026-03-20 13:04:43 +02:00
parent 9b587e6cba
commit beae2dea89
2295 changed files with 251259 additions and 33 deletions
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 3c5ae8c1093da554d8bf77c912cc5433
folderAsset: yes
timeCreated: 1487820668
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
using System.Collections.Generic;
using UnityEngine;
namespace Zenject
{
public class AnimatorIkHandlerManager : MonoBehaviour
{
List<IAnimatorIkHandler> _handlers;
[Inject]
public void Construct(
// Use local to avoid inheriting handlers from a parent context
[Inject(Source = InjectSources.Local)]
List<IAnimatorIkHandler> handlers)
{
_handlers = handlers;
}
public void OnAnimatorIk()
{
foreach (var handler in _handlers)
{
handler.OnAnimatorIk();
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 34ee2459debfb734d968c54ced01b9af
timeCreated: 1487820668
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
using UnityEngine;
namespace Zenject
{
public class AnimatorInstaller : Installer<Animator, AnimatorInstaller>
{
readonly Animator _animator;
public AnimatorInstaller(Animator animator)
{
_animator = animator;
}
public override void InstallBindings()
{
Container.Bind<AnimatorIkHandlerManager>().FromNewComponentOn(_animator.gameObject);
Container.Bind<AnimatorIkHandlerManager>().FromNewComponentOn(_animator.gameObject);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f4cbf7c6883911843ae4a64582422dda
timeCreated: 1487820669
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
using System.Collections.Generic;
using UnityEngine;
namespace Zenject
{
public class AnimatorMoveHandlerManager : MonoBehaviour
{
List<IAnimatorMoveHandler> _handlers;
[Inject]
public void Construct(
// Use local to avoid inheriting handlers from a parent context
[Inject(Source = InjectSources.Local)]
List<IAnimatorMoveHandler> handlers)
{
_handlers = handlers;
}
public void OnAnimatorMove()
{
foreach (var handler in _handlers)
{
handler.OnAnimatorMove();
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a07f8d298d010b34ca694d0d124b66d2
timeCreated: 1487820669
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
namespace Zenject
{
public interface IAnimatorIkHandler
{
void OnAnimatorIk();
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 510bfbdebf6be804b92145cf677898b9
timeCreated: 1487820668
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
namespace Zenject
{
public interface IAnimatorMoveHandler
{
void OnAnimatorMove();
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8e42d79e9a3ccae46b54d9b173778a17
timeCreated: 1487820669
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,156 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ModestTree;
using ModestTree.Util;
namespace Zenject
{
public class DisposableManager : IDisposable
{
readonly List<DisposableInfo> _disposables = new List<DisposableInfo>();
readonly List<LateDisposableInfo> _lateDisposables = new List<LateDisposableInfo>();
bool _disposed;
bool _lateDisposed;
[Inject]
public DisposableManager(
[Inject(Optional = true, Source = InjectSources.Local)]
List<IDisposable> disposables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ILateDisposable> lateDisposables,
[Inject(Id = "Late", Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> latePriorities)
{
foreach (var disposable in disposables)
{
// Note that we use zero for unspecified priority
// This is nice because you can use negative or positive for before/after unspecified
var match = priorities.Where(x => disposable.GetType().DerivesFromOrEqual(x.First)).Select(x => (int?)x.Second).SingleOrDefault();
int priority = match.HasValue ? match.Value : 0;
_disposables.Add(new DisposableInfo(disposable, priority));
}
foreach (var lateDisposable in lateDisposables)
{
var match = latePriorities.Where(x => lateDisposable.GetType().DerivesFromOrEqual(x.First)).Select(x => (int?)x.Second).SingleOrDefault();
int priority = match.HasValue ? match.Value : 0;
_lateDisposables.Add(new LateDisposableInfo(lateDisposable, priority));
}
}
public void Add(IDisposable disposable)
{
Add(disposable, 0);
}
public void Add(IDisposable disposable, int priority)
{
_disposables.Add(
new DisposableInfo(disposable, priority));
}
public void AddLate(ILateDisposable disposable)
{
AddLate(disposable, 0);
}
public void AddLate(ILateDisposable disposable, int priority)
{
_lateDisposables.Add(
new LateDisposableInfo(disposable, priority));
}
public void Remove(IDisposable disposable)
{
_disposables.RemoveWithConfirm(
_disposables.Where(x => ReferenceEquals(x.Disposable, disposable)).Single());
}
public void LateDispose()
{
Assert.That(!_lateDisposed, "Tried to late dispose DisposableManager twice!");
_lateDisposed = true;
// Dispose in the reverse order that they are initialized in
var disposablesOrdered = _lateDisposables.OrderBy(x => x.Priority).Reverse().ToList();
#if UNITY_EDITOR
foreach (var disposable in disposablesOrdered.Select(x => x.LateDisposable).GetDuplicates())
{
Assert.That(false, "Found duplicate ILateDisposable with type '{0}'".Fmt(disposable.GetType()));
}
#endif
foreach (var disposable in disposablesOrdered)
{
try
{
disposable.LateDisposable.LateDispose();
}
catch (Exception e)
{
throw Assert.CreateException(
e, "Error occurred while late disposing ILateDisposable with type '{0}'", disposable.LateDisposable.GetType());
}
}
}
public void Dispose()
{
Assert.That(!_disposed, "Tried to dispose DisposableManager twice!");
_disposed = true;
// Dispose in the reverse order that they are initialized in
var disposablesOrdered = _disposables.OrderBy(x => x.Priority).Reverse().ToList();
#if UNITY_EDITOR
foreach (var disposable in disposablesOrdered.Select(x => x.Disposable).GetDuplicates())
{
Assert.That(false, "Found duplicate IDisposable with type '{0}'".Fmt(disposable.GetType()));
}
#endif
foreach (var disposable in disposablesOrdered)
{
try
{
disposable.Disposable.Dispose();
}
catch (Exception e)
{
throw Assert.CreateException(
e, "Error occurred while disposing IDisposable with type '{0}'", disposable.Disposable.GetType());
}
}
}
struct DisposableInfo
{
public IDisposable Disposable;
public int Priority;
public DisposableInfo(IDisposable disposable, int priority)
{
Disposable = disposable;
Priority = priority;
}
}
class LateDisposableInfo
{
public ILateDisposable LateDisposable;
public int Priority;
public LateDisposableInfo(ILateDisposable lateDisposable, int priority)
{
LateDisposable = lateDisposable;
Priority = priority;
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e62fabfe4695e4a439003c1c1fd5d008
timeCreated: 1461708054
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ModestTree;
using ModestTree.Util;
namespace Zenject
{
// See comment in IGuiRenderable.cs for usage
public class GuiRenderableManager
{
List<RenderableInfo> _renderables;
public GuiRenderableManager(
[Inject(Optional = true, Source = InjectSources.Local)]
List<IGuiRenderable> renderables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities)
{
_renderables = new List<RenderableInfo>();
foreach (var renderable in renderables)
{
// Note that we use zero for unspecified priority
// This is nice because you can use negative or positive for before/after unspecified
var matches = priorities
.Where(x => renderable.GetType().DerivesFromOrEqual(x.First))
.Select(x => x.Second).ToList();
int priority = matches.IsEmpty() ? 0 : matches.Distinct().Single();
_renderables.Add(
new RenderableInfo(renderable, priority));
}
_renderables = _renderables.OrderBy(x => x.Priority).ToList();
#if UNITY_EDITOR
foreach (var renderable in _renderables.Select(x => x.Renderable).GetDuplicates())
{
Assert.That(false, "Found duplicate IGuiRenderable with type '{0}'".Fmt(renderable.GetType()));
}
#endif
}
public void OnGui()
{
foreach (var renderable in _renderables)
{
try
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.GuiRender()", renderable.Renderable.GetType()))
#endif
{
renderable.Renderable.GuiRender();
}
}
catch (Exception e)
{
throw Assert.CreateException(
e, "Error occurred while calling {0}.GuiRender", renderable.Renderable.GetType());
}
}
}
class RenderableInfo
{
public IGuiRenderable Renderable;
public int Priority;
public RenderableInfo(IGuiRenderable renderable, int priority)
{
Renderable = renderable;
Priority = priority;
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5ca4a43d84d9d554080d313280363783
timeCreated: 1484528928
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
using UnityEngine;
namespace Zenject
{
public class GuiRenderer : MonoBehaviour
{
GuiRenderableManager _renderableManager;
[Inject]
void Construct(GuiRenderableManager renderableManager)
{
_renderableManager = renderableManager;
}
public void OnGUI()
{
_renderableManager.OnGui();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d6ee197c5aed3b048b76b82a9be3d094
timeCreated: 1484530704
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: -9995
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ModestTree;
using ModestTree.Util;
namespace Zenject
{
// Responsibilities:
// - Run Initialize() on all Iinitializable's, in the order specified by InitPriority
public class InitializableManager
{
List<InitializableInfo> _initializables;
protected bool _hasInitialized;
[Inject]
public InitializableManager(
[Inject(Optional = true, Source = InjectSources.Local)]
List<IInitializable> initializables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities)
{
_initializables = new List<InitializableInfo>();
for (int i = 0; i < initializables.Count; i++)
{
var initializable = initializables[i];
// Note that we use zero for unspecified priority
// This is nice because you can use negative or positive for before/after unspecified
var matches = priorities.Where(x => initializable.GetType().DerivesFromOrEqual(x.First)).Select(x => x.Second).ToList();
int priority = matches.IsEmpty() ? 0 : matches.Distinct().Single();
_initializables.Add(new InitializableInfo(initializable, priority));
}
}
public void Add(IInitializable initializable)
{
Add(initializable, 0);
}
public void Add(IInitializable initializable, int priority)
{
Assert.That(!_hasInitialized);
_initializables.Add(
new InitializableInfo(initializable, priority));
}
public void Initialize()
{
Assert.That(!_hasInitialized);
_hasInitialized = true;
_initializables = _initializables.OrderBy(x => x.Priority).ToList();
#if UNITY_EDITOR
foreach (var initializable in _initializables.Select(x => x.Initializable).GetDuplicates())
{
Assert.That(false, "Found duplicate IInitializable with type '{0}'".Fmt(initializable.GetType()));
}
#endif
foreach (var initializable in _initializables)
{
try
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.Initialize()", initializable.Initializable.GetType()))
#endif
{
initializable.Initializable.Initialize();
}
}
catch (Exception e)
{
throw Assert.CreateException(
e, "Error occurred while initializing IInitializable with type '{0}'", initializable.Initializable.GetType());
}
}
}
class InitializableInfo
{
public IInitializable Initializable;
public int Priority;
public InitializableInfo(IInitializable initializable, int priority)
{
Initializable = initializable;
Priority = priority;
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8e5838132ef34e14ea93d2e3b30b7140
timeCreated: 1461708051
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 605550c45d7550e498dfe6968192459d
folderAsset: yes
timeCreated: 1462650136
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,73 @@
namespace Zenject
{
public interface IDecoratableMonoKernel
{
bool ShouldInitializeOnStart();
void Initialize();
void Update();
void FixedUpdate();
void LateUpdate();
void Dispose();
void LateDispose();
}
public class DecoratableMonoKernel : IDecoratableMonoKernel
{
[InjectLocal]
public TickableManager TickableManager { get; protected set; } = null;
[InjectLocal]
public InitializableManager InitializableManager { get; protected set; } = null;
[InjectLocal]
public DisposableManager DisposablesManager { get; protected set; } = null;
public virtual bool ShouldInitializeOnStart() => true;
public virtual void Initialize()
{
InitializableManager.Initialize();
}
public void Update()
{
TickableManager.Update();
}
public void FixedUpdate()
{
TickableManager.FixedUpdate();
}
public void LateUpdate()
{
TickableManager.LateUpdate();
}
public void Dispose()
{
DisposablesManager.Dispose();
}
public void LateDispose()
{
DisposablesManager.LateDispose();
}
}
public abstract class BaseMonoKernelDecorator : IDecoratableMonoKernel
{
[Inject]
protected IDecoratableMonoKernel DecoratedMonoKernel;
public virtual bool ShouldInitializeOnStart() => DecoratedMonoKernel.ShouldInitializeOnStart();
public virtual void Initialize() => DecoratedMonoKernel.Initialize();
public virtual void Update() => DecoratedMonoKernel.Update();
public virtual void FixedUpdate() => DecoratedMonoKernel.FixedUpdate();
public virtual void LateUpdate() => DecoratedMonoKernel.LateUpdate();
public virtual void Dispose() => DecoratedMonoKernel.Dispose();
public virtual void LateDispose() => DecoratedMonoKernel.LateDispose();
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f054684b4d0f44a1904823270ae3f137
timeCreated: 1587868417
@@ -0,0 +1,10 @@
#if !NOT_UNITY3D
namespace Zenject
{
public class DefaultGameObjectKernel : MonoKernel
{
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1c47912ae4e51a84d92f1acf689997c8
timeCreated: 1461708048
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: -9996
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,48 @@
using System;
using System.Diagnostics;
namespace Zenject
{
[DebuggerStepThrough]
public class Kernel : IInitializable, IDisposable, ITickable, ILateTickable, IFixedTickable, ILateDisposable
{
[InjectLocal]
TickableManager _tickableManager = null;
[InjectLocal]
InitializableManager _initializableManager = null;
[InjectLocal]
DisposableManager _disposablesManager = null;
public virtual void Initialize()
{
_initializableManager.Initialize();
}
public virtual void Dispose()
{
_disposablesManager.Dispose();
}
public virtual void LateDispose()
{
_disposablesManager.LateDispose();
}
public virtual void Tick()
{
_tickableManager.Update();
}
public virtual void LateTick()
{
_tickableManager.LateUpdate();
}
public virtual void FixedTick()
{
_tickableManager.FixedUpdate();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8a25347f1a9a6b544b4ef8b643824a6f
timeCreated: 1461708051
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,130 @@
#if !NOT_UNITY3D
#pragma warning disable 649
using ModestTree;
using UnityEngine;
using UnityEngine.Analytics;
namespace Zenject
{
public abstract class MonoKernel : MonoBehaviour
{
[InjectLocal]
TickableManager _tickableManager = null;
[InjectLocal]
InitializableManager _initializableManager = null;
[InjectLocal]
DisposableManager _disposablesManager = null;
[InjectOptional]
private IDecoratableMonoKernel decoratableMonoKernel;
bool _hasInitialized;
bool _isDestroyed;
protected bool IsDestroyed
{
get { return _isDestroyed; }
}
public virtual void Start()
{
if (decoratableMonoKernel?.ShouldInitializeOnStart()??true)
{
Initialize();
}
}
public void Initialize()
{
// We don't put this in start in case Start is overridden
if (!_hasInitialized)
{
_hasInitialized = true;
if (decoratableMonoKernel != null)
{
decoratableMonoKernel.Initialize();
}
else
{
_initializableManager.Initialize();
}
}
}
public virtual void Update()
{
// Don't spam the log every frame if initialization fails and leaves it as null
if (_tickableManager != null)
{
if (decoratableMonoKernel != null)
{
decoratableMonoKernel.Update();
}
else
{
_tickableManager.Update();
}
}
}
public virtual void FixedUpdate()
{
// Don't spam the log every frame if initialization fails and leaves it as null
if (_tickableManager != null)
{
if (decoratableMonoKernel != null)
{
decoratableMonoKernel.FixedUpdate();
}
else
{
_tickableManager.FixedUpdate();
}
}
}
public virtual void LateUpdate()
{
// Don't spam the log every frame if initialization fails and leaves it as null
if (_tickableManager != null)
{
if (decoratableMonoKernel != null)
{
decoratableMonoKernel.LateUpdate();
}
else
{
_tickableManager.LateUpdate();
}
}
}
public virtual void OnDestroy()
{
// _disposablesManager can be null if we get destroyed before the Start event
if (_disposablesManager != null)
{
Assert.That(!_isDestroyed);
_isDestroyed = true;
if (decoratableMonoKernel != null)
{
decoratableMonoKernel.Dispose();
decoratableMonoKernel.LateDispose();
}
else
{
_disposablesManager.Dispose();
_disposablesManager.LateDispose();
}
}
}
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0ed09ac17d1c3ca44b8064ce22ebba27
timeCreated: 1461708048
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,87 @@
#if !NOT_UNITY3D
using System.Collections.Generic;
using System.Linq;
using ModestTree;
using UnityEngine.SceneManagement;
namespace Zenject
{
public class ProjectKernel : MonoKernel
{
[Inject]
ZenjectSettings _settings = null;
[Inject]
SceneContextRegistry _contextRegistry = null;
// One issue with relying on MonoKernel.OnDestroy to call IDisposable.Dispose
// is that the order that OnDestroy is called in is difficult to predict
// One good thing is that it does follow the heirarchy order (so root game objects
// will have thier OnDestroy called before child objects)
// However, the order that OnDestroy is called for the root game objects themselves
// is largely random
// Within an individual scene, this can be helped somewhat by placing all game objects
// underneath the SceneContext and then also checking the 'ParentNewObjectsUnderRoot'
// property to ensure any new game objects will also be parented underneath SceneContext
// By doing this, we can be guaranteed to have any bound IDisposable's have their
// Dispose called before any game object is destroyed in the scene
// However, when using multiple scenes (each with their own SceneContext) the order
// that these SceneContext game objects are destroyed is random
// So to address that, we explicitly call GameObject.DestroyImmediate for all
// SceneContext's in the reverse order that the scenes were loaded in below
// (this works because OnApplicationQuit is always called before OnDestroy)
// Note that this only works when stopping the app and not when changing scenes
// When changing scenes, if you have multiple scenes loaded at once, you will have to
// manually unload the scenes in the reverse order they were loaded before going to
// the new scene, if you require a predictable destruction order. Or you can always use
// ZenjectSceneLoader which will do this for you
public void OnApplicationQuit()
{
if (_settings.EnsureDeterministicDestructionOrderOnApplicationQuit)
{
DestroyEverythingInOrder();
}
}
public void DestroyEverythingInOrder()
{
ForceUnloadAllScenes(true);
// Destroy project context after all scenes
Assert.That(!IsDestroyed);
DestroyImmediate(gameObject);
Assert.That(IsDestroyed);
}
public void ForceUnloadAllScenes(bool immediate = false)
{
// OnApplicationQuit should always be called before OnDestroy
// (Unless it is destroyed manually)
Assert.That(!IsDestroyed);
var sceneOrder = new List<Scene>();
for (int i = 0; i < SceneManager.sceneCount; i++)
{
sceneOrder.Add(SceneManager.GetSceneAt(i));
}
// Destroy the scene contexts from bottom to top
// Since this is the reverse order that they were loaded in
foreach (var sceneContext in _contextRegistry.SceneContexts.OrderByDescending(x => sceneOrder.IndexOf(x.gameObject.scene)).ToList())
{
if (immediate)
{
DestroyImmediate(sceneContext.gameObject);
}
else
{
Destroy(sceneContext.gameObject);
}
}
}
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 374b2cd725ea28a46a6377959bb73c9c
timeCreated: 1461708049
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: -9998
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
#if !NOT_UNITY3D
using ModestTree;
namespace Zenject
{
public class SceneKernel : MonoKernel
{
// Only needed to set "script execution order" in unity project settings
#if ZEN_INTERNAL_PROFILING
public override void Start()
{
base.Start();
Log.Info("SceneContext.Awake detailed profiling: {0}", ProfileTimers.FormatResults());
}
#endif
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: aff38aaefd39d0d41a92c2707718d15c
timeCreated: 1461708052
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: -9997
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,485 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ModestTree;
using ModestTree.Util;
namespace Zenject
{
public class PoolableManager
{
readonly List<IPoolable> _poolables;
bool _isSpawned;
public PoolableManager(
[InjectLocal]
List<IPoolable> poolables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities)
{
_poolables = poolables.Select(x => CreatePoolableInfo(x, priorities))
.OrderBy(x => x.Priority).Select(x => x.Poolable).ToList();
}
PoolableInfo CreatePoolableInfo(IPoolable poolable, List<ValuePair<Type, int>> priorities)
{
var match = priorities.Where(x => poolable.GetType().DerivesFromOrEqual(x.First)).Select(x => (int?)(x.Second)).SingleOrDefault();
int priority = match.HasValue ? match.Value : 0;
return new PoolableInfo(poolable, priority);
}
public void TriggerOnSpawned()
{
Assert.That(!_isSpawned);
_isSpawned = true;
for (int i = 0; i < _poolables.Count; i++)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnSpawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnSpawned();
}
}
}
public void TriggerOnDespawned()
{
Assert.That(_isSpawned);
_isSpawned = false;
// Call OnDespawned in the reverse order just like how dispose works
for (int i = _poolables.Count - 1; i >= 0; i--)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnDespawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnDespawned();
}
}
}
struct PoolableInfo
{
public IPoolable Poolable;
public int Priority;
public PoolableInfo(IPoolable poolable, int priority)
{
Poolable = poolable;
Priority = priority;
}
}
}
/// <summary>
/// A modified version of PoolableManager that adds a generic argument, allowing
/// the passing of a parameter to all IPoolable<T> objects in the container.
/// </summary>
public class PoolableManager<T>
{
readonly List<IPoolable<T>> _poolables;
bool _isSpawned;
public PoolableManager(
[InjectLocal]
List<IPoolable<T>> poolables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities)
{
_poolables = poolables.Select(x => CreatePoolableInfo(x, priorities))
.OrderBy(x => x.Priority).Select(x => x.Poolable).ToList();
}
PoolableInfo CreatePoolableInfo(IPoolable<T> poolable, List<ValuePair<Type, int>> priorities)
{
var match = priorities.Where(x => poolable.GetType().DerivesFromOrEqual(x.First)).Select(x => (int?)(x.Second)).SingleOrDefault();
int priority = match.HasValue ? match.Value : 0;
return new PoolableInfo(poolable, priority);
}
public void TriggerOnSpawned(T param)
{
Assert.That(!_isSpawned);
_isSpawned = true;
for (int i = 0; i < _poolables.Count; i++)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnSpawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnSpawned(param);
}
}
}
public void TriggerOnDespawned()
{
Assert.That(_isSpawned);
_isSpawned = false;
// Call OnDespawned in the reverse order just like how dispose works
for (int i = _poolables.Count - 1; i >= 0; i--)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnDespawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnDespawned();
}
}
}
struct PoolableInfo
{
public IPoolable<T> Poolable;
public int Priority;
public PoolableInfo(IPoolable<T> poolable, int priority)
{
Poolable = poolable;
Priority = priority;
}
}
}
/// <summary>
/// A modified version of PoolableManager that adds a generic argument, allowing
/// the passing of a parameter to all IPoolable<T1, T2> objects in the container.
/// </summary>
public class PoolableManager<T1, T2>
{
readonly List<IPoolable<T1, T2>> _poolables;
bool _isSpawned;
public PoolableManager(
[InjectLocal]
List<IPoolable<T1, T2>> poolables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities)
{
_poolables = poolables.Select(x => CreatePoolableInfo(x, priorities))
.OrderBy(x => x.Priority).Select(x => x.Poolable).ToList();
}
PoolableInfo CreatePoolableInfo(IPoolable<T1, T2> poolable, List<ValuePair<Type, int>> priorities)
{
var match = priorities.Where(x => poolable.GetType().DerivesFromOrEqual(x.First)).Select(x => (int?)(x.Second)).SingleOrDefault();
int priority = match.HasValue ? match.Value : 0;
return new PoolableInfo(poolable, priority);
}
public void TriggerOnSpawned(T1 p1, T2 p2)
{
Assert.That(!_isSpawned);
_isSpawned = true;
for (int i = 0; i < _poolables.Count; i++)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnSpawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnSpawned(p1, p2);
}
}
}
public void TriggerOnDespawned()
{
Assert.That(_isSpawned);
_isSpawned = false;
// Call OnDespawned in the reverse order just like how dispose works
for (int i = _poolables.Count - 1; i >= 0; i--)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnDespawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnDespawned();
}
}
}
struct PoolableInfo
{
public IPoolable<T1, T2> Poolable;
public int Priority;
public PoolableInfo(IPoolable<T1, T2> poolable, int priority)
{
Poolable = poolable;
Priority = priority;
}
}
}
/// <summary>
/// A modified version of PoolableManager that adds a generic argument, allowing
/// the passing of a parameter to all IPoolable<T1, T2> objects in the container.
/// </summary>
public class PoolableManager<T1, T2, T3>
{
readonly List<IPoolable<T1, T2, T3>> _poolables;
bool _isSpawned;
public PoolableManager(
[InjectLocal]
List<IPoolable<T1, T2, T3>> poolables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities)
{
_poolables = poolables.Select(x => CreatePoolableInfo(x, priorities))
.OrderBy(x => x.Priority).Select(x => x.Poolable).ToList();
}
PoolableInfo CreatePoolableInfo(IPoolable<T1, T2, T3> poolable, List<ValuePair<Type, int>> priorities)
{
var match = priorities.Where(x => poolable.GetType().DerivesFromOrEqual(x.First)).Select(x => (int?)(x.Second)).SingleOrDefault();
int priority = match.HasValue ? match.Value : 0;
return new PoolableInfo(poolable, priority);
}
public void TriggerOnSpawned(T1 p1, T2 p2, T3 p3)
{
Assert.That(!_isSpawned);
_isSpawned = true;
for (int i = 0; i < _poolables.Count; i++)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnSpawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnSpawned(p1, p2, p3);
}
}
}
public void TriggerOnDespawned()
{
Assert.That(_isSpawned);
_isSpawned = false;
// Call OnDespawned in the reverse order just like how dispose works
for (int i = _poolables.Count - 1; i >= 0; i--)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnDespawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnDespawned();
}
}
}
struct PoolableInfo
{
public IPoolable<T1, T2, T3> Poolable;
public int Priority;
public PoolableInfo(IPoolable<T1, T2, T3> poolable, int priority)
{
Poolable = poolable;
Priority = priority;
}
}
}
/// <summary>
/// A modified version of PoolableManager that adds a generic argument, allowing
/// the passing of a parameter to all IPoolable<T1, T2> objects in the container.
/// </summary>
public class PoolableManager<T1, T2, T3, T4>
{
readonly List<IPoolable<T1, T2, T3, T4>> _poolables;
bool _isSpawned;
public PoolableManager(
[InjectLocal]
List<IPoolable<T1, T2, T3, T4>> poolables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities)
{
_poolables = poolables.Select(x => CreatePoolableInfo(x, priorities))
.OrderBy(x => x.Priority).Select(x => x.Poolable).ToList();
}
PoolableInfo CreatePoolableInfo(IPoolable<T1, T2, T3, T4> poolable, List<ValuePair<Type, int>> priorities)
{
var match = priorities.Where(x => poolable.GetType().DerivesFromOrEqual(x.First)).Select(x => (int?)(x.Second)).SingleOrDefault();
int priority = match.HasValue ? match.Value : 0;
return new PoolableInfo(poolable, priority);
}
public void TriggerOnSpawned(T1 p1, T2 p2, T3 p3, T4 p4)
{
Assert.That(!_isSpawned);
_isSpawned = true;
for (int i = 0; i < _poolables.Count; i++)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnSpawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnSpawned(p1, p2, p3, p4);
}
}
}
public void TriggerOnDespawned()
{
Assert.That(_isSpawned);
_isSpawned = false;
// Call OnDespawned in the reverse order just like how dispose works
for (int i = _poolables.Count - 1; i >= 0; i--)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnDespawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnDespawned();
}
}
}
struct PoolableInfo
{
public IPoolable<T1, T2, T3, T4> Poolable;
public int Priority;
public PoolableInfo(IPoolable<T1, T2, T3, T4> poolable, int priority)
{
Poolable = poolable;
Priority = priority;
}
}
}
/// <summary>
/// A modified version of PoolableManager that adds a generic argument, allowing
/// the passing of a parameter to all IPoolable<T1, T2> objects in the container.
/// </summary>
public class PoolableManager<T1, T2, T3, T4, T5>
{
readonly List<IPoolable<T1, T2, T3, T4, T5>> _poolables;
bool _isSpawned;
public PoolableManager(
[InjectLocal]
List<IPoolable<T1, T2, T3, T4, T5>> poolables,
[Inject(Optional = true, Source = InjectSources.Local)]
List<ValuePair<Type, int>> priorities)
{
_poolables = poolables.Select(x => CreatePoolableInfo(x, priorities))
.OrderBy(x => x.Priority).Select(x => x.Poolable).ToList();
}
PoolableInfo CreatePoolableInfo(IPoolable<T1, T2, T3, T4, T5> poolable, List<ValuePair<Type, int>> priorities)
{
var match = priorities.Where(x => poolable.GetType().DerivesFromOrEqual(x.First)).Select(x => (int?)(x.Second)).SingleOrDefault();
int priority = match.HasValue ? match.Value : 0;
return new PoolableInfo(poolable, priority);
}
public void TriggerOnSpawned(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
{
Assert.That(!_isSpawned);
_isSpawned = true;
for (int i = 0; i < _poolables.Count; i++)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnSpawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnSpawned(p1, p2, p3, p4, p5);
}
}
}
public void TriggerOnDespawned()
{
Assert.That(_isSpawned);
_isSpawned = false;
// Call OnDespawned in the reverse order just like how dispose works
for (int i = _poolables.Count - 1; i >= 0; i--)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.OnDespawned", _poolables[i].GetType()))
#endif
{
_poolables[i].OnDespawned();
}
}
}
struct PoolableInfo
{
public IPoolable<T1, T2, T3, T4, T5> Poolable;
public int Priority;
public PoolableInfo(IPoolable<T1, T2, T3, T4, T5> poolable, int priority)
{
Poolable = poolable;
Priority = priority;
}
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: aef2cb2ede47a96439cbb34a8935111a
timeCreated: 1528650779
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,94 @@
using System.Collections.Generic;
using ModestTree;
using UnityEngine.SceneManagement;
namespace Zenject
{
public class SceneContextRegistry
{
readonly Dictionary<Scene, SceneContext> _map = new Dictionary<Scene, SceneContext>();
public IEnumerable<SceneContext> SceneContexts
{
get { return _map.Values; }
}
public void Add(SceneContext context)
{
Assert.That(!_map.ContainsKey(context.gameObject.scene));
_map.Add(context.gameObject.scene, context);
}
public SceneContext GetSceneContextForScene(string name)
{
var scene = SceneManager.GetSceneByName(name);
Assert.That(scene.IsValid(), "Could not find scene with name '{0}'", name);
return GetSceneContextForScene(scene);
}
public SceneContext GetSceneContextForScene(Scene scene)
{
return _map[scene];
}
public SceneContext TryGetSceneContextForScene(string name)
{
var scene = SceneManager.GetSceneByName(name);
Assert.That(scene.IsValid(), "Could not find scene with name '{0}'", name);
return TryGetSceneContextForScene(scene);
}
public SceneContext TryGetSceneContextForScene(Scene scene)
{
SceneContext context;
if (_map.TryGetValue(scene, out context))
{
return context;
}
return null;
}
public DiContainer GetContainerForScene(Scene scene)
{
var container = TryGetContainerForScene(scene);
if (container != null)
{
return container;
}
throw Assert.CreateException(
"Unable to find DiContainer for scene '{0}'", scene.name);
}
public DiContainer TryGetContainerForScene(Scene scene)
{
if (scene == ProjectContext.Instance.gameObject.scene)
{
return ProjectContext.Instance.Container;
}
var sceneContext = TryGetSceneContextForScene(scene);
if (sceneContext != null)
{
return sceneContext.Container;
}
return null;
}
public void Remove(SceneContext context)
{
bool removed = _map.Remove(context.gameObject.scene);
if (!removed)
{
Log.Warn("Failed to remove SceneContext from SceneContextRegistry");
}
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 11e438b2dc7552349949f24c14de14be
timeCreated: 1510660712
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using System;
namespace Zenject
{
public class SceneContextRegistryAdderAndRemover : IInitializable, IDisposable
{
readonly SceneContextRegistry _registry;
readonly SceneContext _sceneContext;
public SceneContextRegistryAdderAndRemover(
SceneContext sceneContext,
SceneContextRegistry registry)
{
_registry = registry;
_sceneContext = sceneContext;
}
public void Initialize()
{
_registry.Add(_sceneContext);
}
public void Dispose()
{
_registry.Remove(_sceneContext);
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: b13656f05675c384181e749264e6bcf9
timeCreated: 1510660712
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,194 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ModestTree;
namespace Zenject
{
// Update tasks once per frame based on a priority
[DebuggerStepThrough]
public abstract class TaskUpdater<TTask>
{
readonly LinkedList<TaskInfo> _tasks = new LinkedList<TaskInfo>();
readonly List<TaskInfo> _queuedTasks = new List<TaskInfo>();
IEnumerable<TaskInfo> AllTasks
{
get { return ActiveTasks.Concat(_queuedTasks); }
}
IEnumerable<TaskInfo> ActiveTasks
{
get { return _tasks; }
}
public void AddTask(TTask task, int priority)
{
AddTaskInternal(task, priority);
}
void AddTaskInternal(TTask task, int priority)
{
Assert.That(!AllTasks.Select(x => x.Task).ContainsItem(task),
"Duplicate task added to DependencyRoot with name '" + task.GetType().FullName + "'");
// Wait until next frame to add the task, otherwise whether it gets updated
// on the current frame depends on where in the update order it was added
// from, so you might get off by one frame issues
_queuedTasks.Add(new TaskInfo(task, priority));
}
public void RemoveTask(TTask task)
{
var info = AllTasks.Where(x => ReferenceEquals(x.Task, task)).SingleOrDefault();
Assert.IsNotNull(info, "Tried to remove a task not added to DependencyRoot, task = " + task.GetType().Name);
Assert.That(!info.IsRemoved, "Tried to remove task twice, task = " + task.GetType().Name);
info.IsRemoved = true;
}
public void OnFrameStart()
{
// See above comment
AddQueuedTasks();
}
public void UpdateAll()
{
UpdateRange(int.MinValue, int.MaxValue);
}
public void UpdateRange(int minPriority, int maxPriority)
{
var node = _tasks.First;
while (node != null)
{
var next = node.Next;
var taskInfo = node.Value;
// Make sure that tasks with priority of int.MaxValue are updated when maxPriority is int.MaxValue
if (!taskInfo.IsRemoved && taskInfo.Priority >= minPriority
&& (maxPriority == int.MaxValue || taskInfo.Priority < maxPriority))
{
UpdateItem(taskInfo.Task);
}
node = next;
}
ClearRemovedTasks(_tasks);
}
void ClearRemovedTasks(LinkedList<TaskInfo> tasks)
{
var node = tasks.First;
while (node != null)
{
var next = node.Next;
var info = node.Value;
if (info.IsRemoved)
{
//ModestTree.Log.Debug("Removed task '" + info.Task.GetType().ToString() + "'");
tasks.Remove(node);
}
node = next;
}
}
void AddQueuedTasks()
{
for (int i = 0; i < _queuedTasks.Count; i++)
{
var task = _queuedTasks[i];
if (!task.IsRemoved)
{
InsertTaskSorted(task);
}
}
_queuedTasks.Clear();
}
void InsertTaskSorted(TaskInfo task)
{
for (var current = _tasks.First; current != null; current = current.Next)
{
if (current.Value.Priority > task.Priority)
{
_tasks.AddBefore(current, task);
return;
}
}
_tasks.AddLast(task);
}
protected abstract void UpdateItem(TTask task);
class TaskInfo
{
public TTask Task;
public int Priority;
public bool IsRemoved;
public TaskInfo(TTask task, int priority)
{
Task = task;
Priority = priority;
}
}
}
public class TickablesTaskUpdater : TaskUpdater<ITickable>
{
protected override void UpdateItem(ITickable task)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.Tick()", task.GetType()))
#endif
{
task.Tick();
}
}
}
public class LateTickablesTaskUpdater : TaskUpdater<ILateTickable>
{
protected override void UpdateItem(ILateTickable task)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.LateTick()", task.GetType()))
#endif
{
task.LateTick();
}
}
}
public class FixedTickablesTaskUpdater : TaskUpdater<IFixedTickable>
{
protected override void UpdateItem(IFixedTickable task)
{
#if ZEN_INTERNAL_PROFILING
using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
using (ProfileBlock.Start("{0}.FixedTick()", task.GetType()))
#endif
{
task.FixedTick();
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4e52124c243adb44aaf26eed3a8413c8
timeCreated: 1461708050
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ModestTree;
using ModestTree.Util;
#if ZEN_SIGNALS_ADD_UNIRX
using UniRx;
#endif
namespace Zenject
{
public class TickableManager
{
[Inject(Optional = true, Source = InjectSources.Local)]
readonly List<ITickable> _tickables = null;
[Inject(Optional = true, Source = InjectSources.Local)]
readonly List<IFixedTickable> _fixedTickables = null;
[Inject(Optional = true, Source = InjectSources.Local)]
readonly List<ILateTickable> _lateTickables = null;
[Inject(Optional = true, Source = InjectSources.Local)]
readonly List<ValuePair<Type, int>> _priorities = null;
[Inject(Optional = true, Id = "Fixed", Source = InjectSources.Local)]
readonly List<ValuePair<Type, int>> _fixedPriorities = null;
[Inject(Optional = true, Id = "Late", Source = InjectSources.Local)]
readonly List<ValuePair<Type, int>> _latePriorities = null;
#if ZEN_SIGNALS_ADD_UNIRX
readonly Subject<Unit> _tickStream = new Subject<Unit>();
readonly Subject<Unit> _lateTickStream = new Subject<Unit>();
readonly Subject<Unit> _fixedTickStream = new Subject<Unit>();
#endif
readonly TickablesTaskUpdater _updater = new TickablesTaskUpdater();
readonly FixedTickablesTaskUpdater _fixedUpdater = new FixedTickablesTaskUpdater();
readonly LateTickablesTaskUpdater _lateUpdater = new LateTickablesTaskUpdater();
bool _isPaused;
[Inject]
public TickableManager()
{
}
#if ZEN_SIGNALS_ADD_UNIRX
public IObservable<Unit> TickStream
{
get { return _tickStream; }
}
public IObservable<Unit> LateTickStream
{
get { return _lateTickStream; }
}
public IObservable<Unit> FixedTickStream
{
get { return _fixedTickStream; }
}
#endif
public IEnumerable<ITickable> Tickables
{
get { return _tickables; }
}
public bool IsPaused
{
get { return _isPaused; }
set { _isPaused = value; }
}
[Inject]
public void Initialize()
{
InitTickables();
InitFixedTickables();
InitLateTickables();
}
void InitFixedTickables()
{
foreach (var type in _fixedPriorities.Select(x => x.First))
{
Assert.That(type.DerivesFrom<IFixedTickable>(),
"Expected type '{0}' to drive from IFixedTickable while checking priorities in TickableHandler", type);
}
foreach (var tickable in _fixedTickables)
{
// Note that we use zero for unspecified priority
// This is nice because you can use negative or positive for before/after unspecified
var matches = _fixedPriorities.Where(x => tickable.GetType().DerivesFromOrEqual(x.First)).Select(x => x.Second).ToList();
int priority = matches.IsEmpty() ? 0 : matches.Distinct().Single();
_fixedUpdater.AddTask(tickable, priority);
}
}
void InitTickables()
{
foreach (var type in _priorities.Select(x => x.First))
{
Assert.That(type.DerivesFrom<ITickable>(),
"Expected type '{0}' to drive from ITickable while checking priorities in TickableHandler", type);
}
foreach (var tickable in _tickables)
{
// Note that we use zero for unspecified priority
// This is nice because you can use negative or positive for before/after unspecified
var matches = _priorities.Where(x => tickable.GetType().DerivesFromOrEqual(x.First)).Select(x => x.Second).ToList();
int priority = matches.IsEmpty() ? 0 : matches.Distinct().Single();
_updater.AddTask(tickable, priority);
}
}
void InitLateTickables()
{
foreach (var type in _latePriorities.Select(x => x.First))
{
Assert.That(type.DerivesFrom<ILateTickable>(),
"Expected type '{0}' to drive from ILateTickable while checking priorities in TickableHandler", type);
}
foreach (var tickable in _lateTickables)
{
// Note that we use zero for unspecified priority
// This is nice because you can use negative or positive for before/after unspecified
var matches = _latePriorities.Where(x => tickable.GetType().DerivesFromOrEqual(x.First)).Select(x => x.Second).ToList();
int priority = matches.IsEmpty() ? 0 : matches.Distinct().Single();
_lateUpdater.AddTask(tickable, priority);
}
}
public void Add(ITickable tickable, int priority)
{
_updater.AddTask(tickable, priority);
}
public void Add(ITickable tickable)
{
Add(tickable, 0);
}
public void AddLate(ILateTickable tickable, int priority)
{
_lateUpdater.AddTask(tickable, priority);
}
public void AddLate(ILateTickable tickable)
{
AddLate(tickable, 0);
}
public void AddFixed(IFixedTickable tickable, int priority)
{
_fixedUpdater.AddTask(tickable, priority);
}
public void AddFixed(IFixedTickable tickable)
{
_fixedUpdater.AddTask(tickable, 0);
}
public void Remove(ITickable tickable)
{
_updater.RemoveTask(tickable);
}
public void RemoveLate(ILateTickable tickable)
{
_lateUpdater.RemoveTask(tickable);
}
public void RemoveFixed(IFixedTickable tickable)
{
_fixedUpdater.RemoveTask(tickable);
}
public void Update()
{
if(IsPaused)
{
return;
}
_updater.OnFrameStart();
_updater.UpdateAll();
#if ZEN_SIGNALS_ADD_UNIRX
_tickStream.OnNext(Unit.Default);
#endif
}
public void FixedUpdate()
{
if(IsPaused)
{
return;
}
_fixedUpdater.OnFrameStart();
_fixedUpdater.UpdateAll();
#if ZEN_SIGNALS_ADD_UNIRX
_fixedTickStream.OnNext(Unit.Default);
#endif
}
public void LateUpdate()
{
if(IsPaused)
{
return;
}
_lateUpdater.OnFrameStart();
_lateUpdater.UpdateAll();
#if ZEN_SIGNALS_ADD_UNIRX
_lateTickStream.OnNext(Unit.Default);
#endif
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2fa54cf0e36bd194faa8f877e9f699a4
timeCreated: 1461708049
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: