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();
                }
            }
        }
예제 #2
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);
        }
예제 #3
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();
                }
            }
        }
        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());
                }
            }
        }
예제 #5
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);
            }
        }
        public DiContainer CreateSubContainer(List <TypeValuePair> args, InjectContext parentContext, out Action injectAction)
        {
            Assert.That(!args.IsEmpty());

            var prefab        = _prefabProvider.GetPrefab();
            var tempContainer = CreateTempContainer(args);

            bool shouldMakeActive;
            var  gameObject = tempContainer.CreateAndParentPrefab(
                prefab, _gameObjectBindInfo, null, out shouldMakeActive);

            var context = gameObject.GetComponent <GameObjectContext>();

            Assert.That(context != null,
                        "Expected prefab with name '{0}' to container a component of type 'GameObjectContext'", prefab.name);

            context.Install(tempContainer);

            injectAction = () =>
            {
                // Note: We don't need to call ResolveRoots here because GameObjectContext does this for us
                tempContainer.Inject(context);

                if (shouldMakeActive && !_container.IsValidating)
                {
#if ZEN_INTERNAL_PROFILING
                    using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
                    {
                        gameObject.SetActive(true);
                    }
                }
            };

            return(context.Container);
        }
예제 #7
0
        protected void InstallInstallers(
            List <InstallerBase> normalInstallers,
            List <Type> normalInstallerTypes,
            List <ScriptableObjectInstaller> scriptableObjectInstallers,
            List <MonoInstaller> installers,
            List <MonoInstaller> installerPrefabs)
        {
            CheckInstallerPrefabTypes(installers, installerPrefabs);

            // Ideally we would just have one flat list of all the installers
            // since that way the user has complete control over the order, but
            // that's not possible since Unity does not allow serializing lists of interfaces
            // (and it has to be an inteface since the scriptable object installers only share
            // the interface)
            //
            // So the best we can do is have a hard-coded order in terms of the installer type
            //
            // The order is:
            //      - Normal installers given directly via code
            //      - ScriptableObject installers
            //      - MonoInstallers in the scene
            //      - Prefab Installers
            //
            // We put ScriptableObject installers before the MonoInstallers because
            // ScriptableObjectInstallers are often used for settings (including settings
            // that are injected into other installers like MonoInstallers)

            var allInstallers = normalInstallers.Cast <IInstaller>()
                                .Concat(scriptableObjectInstallers.Cast <IInstaller>())
                                .Concat(installers.Cast <IInstaller>()).ToList();

            foreach (var installerPrefab in installerPrefabs)
            {
                Assert.IsNotNull(installerPrefab, "Found null installer prefab in '{0}'", GetType());

                GameObject installerGameObject;

#if ZEN_INTERNAL_PROFILING
                using (ProfileTimers.CreateTimedBlock("GameObject.Instantiate"))
#endif
                {
                    installerGameObject = GameObject.Instantiate(installerPrefab.gameObject);
                }

                installerGameObject.transform.SetParent(transform, false);
                var installer = installerGameObject.GetComponent <MonoInstaller>();

                Assert.IsNotNull(installer, "Could not find installer component on prefab '{0}'", installerPrefab.name);

                allInstallers.Add(installer);
            }

            foreach (var installerType in normalInstallerTypes)
            {
                var installer = (InstallerBase)Container.Instantiate(installerType);

#if ZEN_INTERNAL_PROFILING
                using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
                {
                    installer.InstallBindings();
                }
            }

            foreach (var installer in allInstallers)
            {
                Assert.IsNotNull(installer,
                                 "Found null installer in '{0}'", GetType());

                Container.Inject(installer);

#if ZEN_INTERNAL_PROFILING
                using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
                {
                    installer.InstallBindings();
                }
            }
        }
예제 #8
0
        static void InstantiateAndInitialize()
        {
#if UNITY_EDITOR
            ProfileBlock.UnityMainThread = Thread.CurrentThread;
#endif

            Assert.That(FindObjectsOfType <ProjectContext>().IsEmpty(),
                        "Tried to create multiple instances of ProjectContext!");

            var prefab = TryGetPrefab();

            var prefabWasActive = false;

#if ZEN_INTERNAL_PROFILING
            using (ProfileTimers.CreateTimedBlock("GameObject.Instantiate"))
#endif
            {
                if (prefab == null)
                {
                    _instance = new GameObject("ProjectContext")
                                .AddComponent <ProjectContext>();
                }
                else
                {
                    prefabWasActive = prefab.activeSelf;

                    GameObject gameObjectInstance;
#if UNITY_EDITOR
                    if (prefabWasActive)
                    {
                        // This ensures the prefab's Awake() methods don't fire (and, if in the editor, that the prefab file doesn't get modified)
                        gameObjectInstance = GameObject.Instantiate(prefab, ZenUtilInternal.GetOrCreateInactivePrefabParent());
                        gameObjectInstance.SetActive(false);
                        gameObjectInstance.transform.SetParent(null, false);
                    }
                    else
                    {
                        gameObjectInstance = GameObject.Instantiate(prefab);
                    }
#else
                    if (prefabWasActive)
                    {
                        prefab.SetActive(false);
                        gameObjectInstance = GameObject.Instantiate(prefab);
                        prefab.SetActive(true);
                    }
                    else
                    {
                        gameObjectInstance = GameObject.Instantiate(prefab);
                    }
#endif

                    _instance = gameObjectInstance.GetComponent <ProjectContext>();

                    Assert.IsNotNull(_instance,
                                     "Could not find ProjectContext component on prefab 'Resources/{0}.prefab'", ProjectContextResourcePath);
                }
            }

            // Note: We use Initialize instead of awake here in case someone calls
            // ProjectContext.Instance while ProjectContext is initializing
            _instance.Initialize();

            if (prefabWasActive)
            {
#if ZEN_INTERNAL_PROFILING
                using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
                {
                    // We always instantiate it as disabled so that Awake and Start events are triggered after inject
                    _instance.gameObject.SetActive(true);
                }
            }
        }
        public GameObject Instantiate(InjectContext context, List <TypeValuePair> args, out Action injectAction)
        {
            Assert.That(_argumentTarget == null || _argumentTarget.DerivesFromOrEqual(context.MemberType));

            bool shouldMakeActive;
            var  gameObject = _container.CreateAndParentPrefab(
                GetPrefab(context), _gameObjectBindInfo, context, out shouldMakeActive);

            Assert.IsNotNull(gameObject);

            injectAction = () =>
            {
                var allArgs = ZenPools.SpawnList <TypeValuePair>();

                allArgs.AllocFreeAddRange(_extraArguments);
                allArgs.AllocFreeAddRange(args);

                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
                {
                    _container.InjectGameObjectForComponentExplicit(
                        gameObject, _argumentTarget, allArgs, context, null);

                    Assert.That(allArgs.Count == 0);
                }

                ZenPools.DespawnList <TypeValuePair>(allArgs);

                if (shouldMakeActive && !_container.IsValidating)
                {
#if ZEN_INTERNAL_PROFILING
                    using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
                    {
                        gameObject.SetActive(true);
                    }
                }

                if (_instantiateCallback != null)
                {
                    var callbackObjects = ZenPools.SpawnHashSet <object>();

                    foreach (var type in _instantiateCallbackTypes)
                    {
                        var obj = gameObject.GetComponentInChildren(type);

                        if (obj != null)
                        {
                            callbackObjects.Add(obj);
                        }
                    }

                    foreach (var obj in callbackObjects)
                    {
                        _instantiateCallback(context, obj);
                    }

                    ZenPools.DespawnHashSet(callbackObjects);
                }
            };

            return(gameObject);
        }
        static InjectTypeInfo GetInfoInternal(Type type)
        {
            if (ShouldSkipTypeAnalysis(type))
            {
                return(null);
            }

#if ZEN_INTERNAL_PROFILING
            // Make sure that the static constructor logic doesn't inflate our profile measurements
            using (ProfileTimers.CreateTimedBlock("User Code"))
            {
                RuntimeHelpers.RunClassConstructor(type.TypeHandle);
            }
#endif

#if ZEN_INTERNAL_PROFILING
            using (ProfileTimers.CreateTimedBlock("Type Analysis - Calling Baked Reflection Getter"))
#endif
            {
                var getInfoMethod = type.GetMethod(
                    ReflectionBakingGetInjectInfoMethodName,
                    BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);

                if (getInfoMethod != null)
                {
#if UNITY_WSA && ENABLE_DOTNET && !UNITY_EDITOR
                    var infoGetter = (ZenTypeInfoGetter)getInfoMethod.CreateDelegate(
                        typeof(ZenTypeInfoGetter), null);
#else
                    var infoGetter = ((ZenTypeInfoGetter)Delegate.CreateDelegate(
                                          typeof(ZenTypeInfoGetter), getInfoMethod));
#endif

                    return(infoGetter());
                }
            }

            if (ReflectionBakingCoverageMode == ReflectionBakingCoverageModes.NoCheckAssumeFullCoverage)
            {
                // If we are confident that the reflection baking supplies all the injection information,
                // then we can avoid the costs of doing reflection on types that were not covered
                // by the baking
                return(null);
            }

#if !(UNITY_WSA && ENABLE_DOTNET) || UNITY_EDITOR
            if (ReflectionBakingCoverageMode == ReflectionBakingCoverageModes.FallbackToDirectReflectionWithWarning)
            {
                Log.Warn(
                    "No reflection baking information found for type '{0}' - using more costly direct reflection instead",
                    type);
            }
#endif

#if ZEN_INTERNAL_PROFILING
            using (ProfileTimers.CreateTimedBlock("Type Analysis - Direct Reflection"))
#endif
            {
                return(CreateTypeInfoFromReflection(type));
            }
        }
        public GameObject Instantiate(List <TypeValuePair> args, out Action injectAction)
        {
            var  context = new InjectContext(_container, _argumentTarget, null);
            bool shouldMakeActive;
            var  gameObject = _container.CreateAndParentPrefab(
                GetPrefab(), _gameObjectBindInfo, context, out shouldMakeActive);

            Assert.IsNotNull(gameObject);

            injectAction = () =>
            {
                var allArgs = ZenPools.SpawnList <TypeValuePair>();

                allArgs.AllocFreeAddRange(_extraArguments);
                allArgs.AllocFreeAddRange(args);

                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");
                }

                Component targetComponent = null;

                if (_argumentTarget == null || allArgs.IsEmpty())
                {
                    _container.InjectGameObject(gameObject);
                }
                else
                {
                    targetComponent = _container.InjectGameObjectForComponentExplicit(
                        gameObject, _argumentTarget, allArgs, context, null);

                    Assert.That(allArgs.Count == 0);
                }

                ZenPools.DespawnList <TypeValuePair>(allArgs);

                if (shouldMakeActive && !_container.IsValidating)
                {
#if ZEN_INTERNAL_PROFILING
                    using (ProfileTimers.CreateTimedBlock("User Code"))
#endif
                    {
                        gameObject.SetActive(true);
                    }
                }

                if (_instantiateCallback != null && _argumentTarget != null)
                {
                    if (targetComponent == null)
                    {
                        targetComponent = gameObject.GetComponentInChildren(_argumentTarget);
                    }

                    if (targetComponent != null)
                    {
                        _instantiateCallback(context, targetComponent);
                    }
                }
            };

            return(gameObject);
        }
예제 #12
0
        // 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());
        }
예제 #13
0
        // Only needed to set "script execution order" in unity project settings

#if ZEN_INTERNAL_PROFILING
        public override void Start()
        {
            base.Start();
            Log.Info(ProfileTimers.FormatResults());
        }