예제 #1
0
        internal static void Inject(DiContainer container, object injectable, IEnumerable <object> additional, bool shouldUseAll, ZenjectTypeInfo typeInfo)
        {
            Assert.IsEqual(typeInfo.TypeAnalyzed, injectable.GetType());
            Assert.That(injectable != null);

            var additionalCopy = additional.ToList();

            foreach (var injectInfo in typeInfo.FieldInjectables.Concat(typeInfo.PropertyInjectables))
            {
                bool didInject = InjectFromExtras(injectInfo, injectable, additionalCopy);

                if (!didInject)
                {
                    InjectFromResolve(injectInfo, container, injectable);
                }
            }

            if (shouldUseAll && !additionalCopy.IsEmpty())
            {
                throw new ZenjectResolveException(
                          "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}"
                          .With(injectable.GetType().Name(), String.Join(",", additionalCopy.Select(x => x.GetType().Name()).ToArray()), DiContainer.GetCurrentObjectGraph()));
            }

            foreach (var methodInfo in typeInfo.PostInjectMethods)
            {
                using (ProfileBlock.Start("{0}.{1}()".With(injectable.GetType(), methodInfo.Name)))
                {
                    methodInfo.Invoke(injectable, new object[0]);
                }
            }
        }
예제 #2
0
        public void Initialize()
        {
            _initializables.Sort(SortCompare);

            if (Assert.IsEnabled)
            {
                foreach (var initializable in _initializables.Select(x => x.Initializable).GetDuplicates())
                {
                    Assert.That(false, "Found duplicate IInitializable with type '{0}'".With(initializable.GetType()));
                }
            }

            foreach (var initializable in _initializables)
            {
                //Log.Info("Initializing initializable with type '" + initializable.GetType() + "'");

                try
                {
                    using (ProfileBlock.Start("{0}.Initialize()", initializable.Initializable.GetType().Name()))
                    {
                        initializable.Initializable.Initialize();
                    }
                }
                catch (Exception e)
                {
                    throw new ZenjectException(
                              "Error occurred while initializing IInitializable with type '{0}'".With(initializable.Initializable.GetType().Name()), e);
                }
            }
        }
예제 #3
0
 void UpdateTickable(ITickable tickable)
 {
     using (ProfileBlock.Start("{0}.Tick()".With(tickable.GetType().Name())))
     {
         tickable.Tick();
     }
 }
예제 #4
0
        object InstantiateInternal(
            Type concreteType, params object[] constructorArgs)
        {
            Assert.That(!concreteType.DerivesFrom <UnityEngine.Component>(),
                        "Error occurred while instantiating object of type '{0}'. Instantiator should not be used to create new mono behaviours.  Must use GameObjectInstantiator, GameObjectFactory, or GameObject.Instantiate.", concreteType.Name());

            var typeInfo = TypeAnalyzer.GetInfo(concreteType);

            if (typeInfo.InjectConstructor == null)
            {
                throw new ZenjectResolveException(
                          "More than one or zero constructors found for type '{0}' when creating dependencies.  Use one [Inject] attribute to specify which to use.".With(concreteType));
            }

            var paramValues = new List <object>();
            var extrasList  = new List <object>(constructorArgs);

            Assert.That(!extrasList.Contains(null),
                        "Null value given to factory constructor arguments. This is currently not allowed");

            foreach (var injectInfo in typeInfo.ConstructorInjectables)
            {
                var found = false;

                foreach (var extra in extrasList)
                {
                    if (extra.GetType().DerivesFromOrEqual(injectInfo.ContractType))
                    {
                        found = true;
                        paramValues.Add(extra);
                        extrasList.Remove(extra);
                        break;
                    }
                }

                if (!found)
                {
                    paramValues.Add(_container.Resolve(injectInfo));
                }
            }

            object newObj;

            try
            {
                using (ProfileBlock.Start("{0}.{0}()".With(concreteType)))
                {
                    newObj = typeInfo.InjectConstructor.Invoke(paramValues.ToArray());
                }
            }
            catch (Exception e)
            {
                throw new ZenjectResolveException(
                          "Error occurred while instantiating object with type '{0}'".With(concreteType.Name()), e);
            }

            FieldsInjecter.Inject(_container, newObj, extrasList, true, typeInfo);

            return(newObj);
        }
        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());
                }
            }
        }
예제 #6
0
 public object Instantiate(
     Type concreteType, params object[] constructorArgs)
 {
     using (ProfileBlock.Start("Zenject.Instantiate({0})".With(concreteType)))
     {
         using (_container.PushLookup(concreteType))
         {
             return(InstantiateInternal(concreteType, constructorArgs));
         }
     }
 }
예제 #7
0
 public object InstantiateExplicit(
     Type concreteType, List <TypeValuePair> extraArgMap)
 {
     using (ProfileBlock.Start("Zenject.Instantiate({0})", concreteType))
     {
         using (_container.PushLookup(concreteType))
         {
             return(InstantiateInternal(concreteType, extraArgMap));
         }
     }
 }
예제 #8
0
        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();
            }
        }
예제 #9
0
        public void UpdateUnsorted()
        {
            foreach (var taskInfo in _unsortedTasks.Where(x => !x.IsRemoved))
            {
                Assert.That(!taskInfo.Priority.HasValue);

                using (ProfileBlock.Start("{0}.Tick()".With(taskInfo.Tickable.GetType().Name())))
                {
                    taskInfo.Tickable.Tick();
                }
            }

            ClearRemovedTasks(_unsortedTasks);
        }
예제 #10
0
        object InstantiateInternal(
            Type concreteType, IEnumerable <TypeValuePair> extraArgMapParam)
        {
            Assert.That(!concreteType.DerivesFrom <UnityEngine.Component>(),
                        "Error occurred while instantiating object of type '{0}'. Instantiator should not be used to create new mono behaviours.  Must use GameObjectInstantiator, GameObjectFactory, or GameObject.Instantiate.", concreteType.Name());

            var typeInfo = TypeAnalyzer.GetInfo(concreteType);

            if (typeInfo.InjectConstructor == null)
            {
                throw new ZenjectResolveException(
                          "More than one or zero constructors found for type '{0}' when creating dependencies.  Use one [Inject] attribute to specify which to use.".With(concreteType));
            }

            // Make a copy since we remove from it below
            var extraArgMap = extraArgMapParam.ToList();
            var paramValues = new List <object>();

            foreach (var injectInfo in typeInfo.ConstructorInjectables)
            {
                object value;

                if (!InstantiateUtil.PopValueWithType(extraArgMap, injectInfo.ContractType, out value))
                {
                    value = _container.Resolve(injectInfo);
                }

                paramValues.Add(value);
            }

            object newObj;

            try
            {
                using (ProfileBlock.Start("{0}.{0}()", concreteType))
                {
                    newObj = typeInfo.InjectConstructor.Invoke(paramValues.ToArray());
                }
            }
            catch (Exception e)
            {
                throw new ZenjectResolveException(
                          "Error occurred while instantiating object with type '{0}'".With(concreteType.Name()), e);
            }

            FieldsInjecter.Inject(_container, newObj, extraArgMap, true, typeInfo);

            return(newObj);
        }
예제 #11
0
        public void Update(int minPriority, int maxPriority)
        {
            foreach (var taskInfo in _sortedTasks.Where(x =>
                                                        !x.IsRemoved && x.Priority >= minPriority && x.Priority < maxPriority))
            {
                Assert.That(taskInfo.Priority.HasValue);

                using (ProfileBlock.Start("{0}.Tick()".With(taskInfo.Tickable.GetType().Name())))
                {
                    taskInfo.Tickable.Tick();
                }
            }

            ClearRemovedTasks(_sortedTasks);
        }
예제 #12
0
        internal static void Inject(
            DiContainer container, object injectable,
            IEnumerable <TypeValuePair> extraArgMapParam, bool shouldUseAll, ZenjectTypeInfo typeInfo)
        {
            Assert.IsEqual(typeInfo.TypeAnalyzed, injectable.GetType());
            Assert.That(injectable != null);

            // Make a copy since we remove from it below
            var extraArgMap = extraArgMapParam.ToList();

            foreach (var injectInfo in typeInfo.FieldInjectables.Concat(typeInfo.PropertyInjectables))
            {
                object value;

                if (InstantiateUtil.PopValueWithType(extraArgMap, injectInfo.ContractType, out value))
                {
                    injectInfo.Setter(injectable, value);
                }
                else
                {
                    value = container.Resolve(injectInfo, injectable);

                    if (injectInfo.Optional && value == null)
                    {
                        // Do not override in this case so it retains the hard-coded value
                    }
                    else
                    {
                        injectInfo.Setter(injectable, value);
                    }
                }
            }

            if (shouldUseAll && !extraArgMap.IsEmpty())
            {
                throw new ZenjectResolveException(
                          "Passed unnecessary parameters when injecting into type '{0}'. \nExtra Parameters: {1}\nObject graph:\n{2}"
                          .With(injectable.GetType().Name(), String.Join(",", extraArgMap.Select(x => x.Type.Name()).ToArray()), DiContainer.GetCurrentObjectGraph()));
            }

            foreach (var methodInfo in typeInfo.PostInjectMethods)
            {
                using (ProfileBlock.Start("{0}.{1}()", injectable.GetType(), methodInfo.Name))
                {
                    methodInfo.Invoke(injectable, new object[0]);
                }
            }
        }
예제 #13
0
        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();
                }
            }
        }
예제 #14
0
        public TValue Spawn()
        {
            var item = GetInternal();

            if (!Container.IsValidating)
            {
#if ZEN_INTERNAL_PROFILING
                using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
                using (ProfileBlock.Start("{0}.Reinitialize", GetType()))
#endif
                {
                    Reinitialize(item);
                }
            }
            return(item);
        }
예제 #15
0
        public void LazyInjectAll()
        {
#if UNITY_EDITOR
            using (ProfileBlock.Start("Zenject.LazyInstanceInjector.LazyInjectAll"))
#endif
            {
                var tempList = new List <object>();
                while (!_instancesToInject.IsEmpty())
                {
                    tempList.Clear();
                    tempList.AddRange(_instancesToInject);
                    _instancesToInject.Clear();
                    foreach (var instance in tempList)
                    {
                        _container.Inject(instance);
                    }
                }
            }
        }
예제 #16
0
        protected override void RunInternal()
        {
            // We always want to initialize ProjectContext as early as possible
            ProjectContext.Instance.EnsureIsInitialized();

#if UNITY_EDITOR
            using (ProfileBlock.Start("Zenject.SceneContext.Install"))
#endif
            {
                Install();
            }

#if UNITY_EDITOR
            using (ProfileBlock.Start("Zenject.SceneContext.Resolve"))
#endif
            {
                Resolve();
            }
        }
예제 #17
0
        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();
                }
            }
        }
예제 #18
0
        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());
                }
            }
        }
예제 #19
0
        public void Despawn(TContract item)
        {
            Assert.That(!_inactiveItems.Contains(item),
                        "Tried to return an item to pool {0} twice", GetType());

            _activeCount--;

            _inactiveItems.Push(item);

#if ZEN_INTERNAL_PROFILING
            using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
#if UNITY_EDITOR
            using (ProfileBlock.Start("{0}.OnDespawned", GetType()))
#endif
            {
                OnDespawned(item);
            }

            if (_inactiveItems.Count > _settings.MaxSize)
            {
                Resize(_settings.MaxSize);
            }
        }