Пример #1
0
        void IModuleBehaviorCallbacks.OnBehaviorAwake()
        {
            if (!Application.isPlaying)
            {
                return;
            }

            var session = MARSSession.Instance;

            if (session == null)
            {
                return;
            }

            GetAllMonoBehaviors();
            var subscriberCount = 0;
            var sceneObjects    = k_MonoBehaviourObjects;

            sceneObjects.AddRange(m_CustomRuntimeSceneObjects);
            var providers       = new List <IFunctionalityProvider>();
            var providerTypes   = new HashSet <Type>();
            var subscriberTypes = new HashSet <Type>();

            subscriberTypes.Add(typeof(MARSSceneModule));
            foreach (var behavior in sceneObjects)
            {
                // Exclude modules as they have already been set up for FI
                if (behavior is IModule)
                {
                    continue;
                }

                var functionalityProvider = behavior as IFunctionalityProvider;
                if (functionalityProvider != null)
                {
                    providers.Add(functionalityProvider);
                    providerTypes.Add(functionalityProvider.GetType());
                }

                var subscriber = behavior as IFunctionalitySubscriber;
                if (subscriber != null)
                {
                    subscriberCount++;
                    subscriberTypes.Add(subscriber.GetType());
                }
            }

            if (MarsDebugSettings.SceneModuleLogging)
            {
                Debug.Log(string.Format("Scene Module found {0} providers with types: {1}", providers.Count,
                                        string.Join(",", providerTypes.Select(type => type.Name).ToArray())));
                Debug.Log(string.Format("Scene Module found {0} subscribers with types: {1}", subscriberCount,
                                        string.Join(",", subscriberTypes.Select(type => type.Name).ToArray())));
            }

            // TODO: notify other modules (i.e. backend) that the active island has changed
#if UNITY_EDITOR
            var useSimulationIsland = Application.isPlaying && simulateInPlaymode;
            if (useSimulationIsland)
            {
                var simulationIsland = m_SimulateDiscovery ? m_SimulatedDiscoveryIsland : m_SimulationIsland;
                if (simulationIsland != null)
                {
                    m_FIModule.SetActiveIsland(simulationIsland);
                }
            }
            else
            {
                var island = session.island;
                if (island != null)
                {
                    m_FIModule.SetActiveIsland(island);
                }
            }
#else
            var island = session.island;
            if (island)
            {
                m_FIModule.SetActiveIsland(island);
            }
#endif
            var activeIsland = m_FIModule.activeIsland;
            activeIsland.AddProviders(providers);

            var newProviders = new List <IFunctionalityProvider>();
            if (BeforeSetupDefaultProviders != null)
            {
                BeforeSetupDefaultProviders(newProviders);
                activeIsland.AddProviders(newProviders);
            }

            activeIsland.SetupDefaultProviders(subscriberTypes, newProviders);

            var definitions = new HashSet <TraitDefinition>();
            foreach (var requirement in session.requirements.TraitRequirements)
            {
                definitions.Add(requirement);
            }

            activeIsland.InjectFunctionality(sceneObjects);
            activeIsland.RequireProvidersWithDefaultProviders(definitions, newProviders);
            sceneObjects.Clear();
            sceneObjects.AddRange(newProviders);
            activeIsland.InjectFunctionality(sceneObjects);
            activeIsland.InjectFunctionalitySingle(this);

#if UNITY_EDITOR
            if (EditorOnlyDelegates.CullEnvironmentFromSceneLights != null)
            {
                for (var i = 0; i < SceneManager.sceneCount; i++)
                {
                    EditorOnlyDelegates.CullEnvironmentFromSceneLights(SceneManager.GetSceneAt(i));
                }
            }
#endif

            // Update the scale provider to the scene's session scale in case it needs to cache this value
            this.SetCameraScale(session.transform.localScale.x);
            subscriberTypes.Clear();
        }
        bool TryStartSimulation()
        {
            if (!TraitCodeGenerator.HasGenerated || EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return(false);
            }

            var useExistingData = KeepDataBetweenSimulations;

            KeepDataBetweenSimulations = false;
            m_SimulationRestartNeeded  = false;
            NextSimModeSelection       = SimulationModeSelection.NoModePreference;

            // Make sure the watchdog is up-to-date before we check if the scene has entities or subscribers
            m_SceneWatchdogModule.ExecutePollingTask();
            if (!sceneIsSimulatable)
            {
                CleanupSimulation();
                return(false);
            }

            if (!m_SimulationSceneModule.IsSimulationReady)
            {
                return(false);
            }

            // if this method is null, that means something has tried to start simulation when the database isn't setup
            if (IUsesQueryResultsMethods.RegisterQuery == null)
            {
                return(false);
            }

            var simulationSettings = SimulationSettings.instance;

            if (!simulationSettings.IsSpatialContextAvailable)
            {
                return(false);
            }

            var marsSession = MarsRuntimeUtils.GetMarsSessionInActiveScene();

            if (marsSession == null)
            {
                return(false);
            }

            ProfilerMarkers.TryStartSimulation.Begin(); // only profile after safety checks
            if (MarsDebugSettings.QuerySimulationModuleLogging)
            {
                Debug.Log("Start simulation");
            }

            // Cancel delay calls in case the previous simulation was one-shot. Otherwise we can end up stopping behaviors
            // in the middle of temporal simulation or doubling up on delay calls for one-shot simulation.
            EditorApplication.delayCall -= StopRunningOneShot;
            EditorApplication.delayCall -= DelayStopRunningOneShot;

            BeforeSimulationSetup?.Invoke();

            m_SlowTaskModule.ClearTasks();
            QueryObjectMapping.Map.Clear();
            k_TraitRequirements.Clear();
            k_FunctionalitySubscriberObjects.Clear();
            EditorOnlyEvents.OnSimulationStart(k_FunctionalitySubscriberObjects, k_TraitRequirements);
            m_SimulatedObjectsManager.SetupSimulatables(k_FunctionalitySubscriberObjects);

            simulating = true;

            var providersPreserved = useExistingData;

            if (!useExistingData)
            {
                if (m_SimulationContext.Update(marsSession, k_FunctionalitySubscriberObjects, simulatingTemporal))
                {
                    if (MarsDebugSettings.QuerySimulationModuleLogging)
                    {
                        Debug.Log("Simulation context changed. Recreating providers.");
                    }

                    CleanupProviders();

                    functionalityIsland = simulationSettings.EnvironmentMode == EnvironmentMode.Synthetic && simulatingTemporal ?
                                          m_SimulatedDiscoveryIsland : m_SimulationIsland;

                    providersRoot = new GameObject("Providers");
                    m_SimulationSceneModule.AddContentGameObject(providersRoot);
                    GameObjectUtils.gameObjectInstantiated += OnProviderInstantiated;

                    if (addCustomProviders != null)
                    {
                        addCustomProviders(m_Providers);
                        functionalityIsland.AddProviders(m_Providers);
                    }

                    var subscriberTypes = m_SimulationContext.SceneSubscriberTypes;
                    functionalityIsland.SetupDefaultProviders(subscriberTypes, m_Providers);
                    var definitions = new HashSet <TraitDefinition>();
                    k_TraitRequirements.UnionWith(m_SimulationContext.SceneRequirements);
                    m_ReasoningModule.ExtraTraitRequirements.Clear();
                    m_ReasoningModule.ExtraTraitRequirements.UnionWith(k_TraitRequirements);
                    foreach (var requirement in k_TraitRequirements)
                    {
                        definitions.Add(requirement);
                    }

                    functionalityIsland.RequireProvidersWithDefaultProviders(definitions, m_Providers);
                    functionalityIsland.PrepareFunctionalityForSubscriberTypes(subscriberTypes, m_Providers);

                    ModuleLoaderCore.instance.InjectFunctionalityInModules(functionalityIsland);
                    GameObjectUtils.gameObjectInstantiated -= OnProviderInstantiated;
                    providersRoot.SetHideFlagsRecursively(SimulatedObjectsManager.SimulatedObjectHideFlags);

                    foreach (var provider in m_Providers)
                    {
                        var providerBehaviour = provider as MonoBehaviour;
                        if (providerBehaviour != null)
                        {
                            m_ProviderBehaviours.Add(providerBehaviour);
                        }
                    }

                    foreach (var gameObject in m_ProviderGameObjects)
                    {
                        foreach (var simulatable in gameObject.GetComponentsInChildren <ISimulatable>())
                        {
                            var providerBehaviour = simulatable as MonoBehaviour;
                            if (providerBehaviour != null)
                            {
                                m_ProviderBehaviours.Add(providerBehaviour);
                            }
                        }
                    }
                }
                else
                {
                    providersPreserved = true;
                    StopRunningProviders();
                }
            }

            // When using providers from the last simulation, ensure they stay at the bottom of the hierarchy
            if (providersPreserved)
            {
                providersRoot.transform.SetAsLastSibling();
            }

            this.SetCameraScale(MarsWorldScaleModule.GetWorldScale());

            // Set active island now that providers have been setup
            m_FIModule.SetActiveIsland(functionalityIsland);
            functionalityIsland.InjectFunctionalitySingle(marsSession);
            marsSession.StartRunInEditMode();

            if (!useExistingData)
            {
                // Clear the database and then run providers in edit mode so we start getting data.
                m_Database.Clear();
                foreach (var providerBehaviour in m_ProviderBehaviours)
                {
                    providerBehaviour.StartRunInEditMode();
                }
            }

            m_ReasoningModule.ResetReasoningAPIs();

            // We must also reset the backend's query management state each time, otherwise there is no guarantee that
            // the its collections will be ordered the same way each time, even if the ordering of clients in the scene
            // stays the same. This also ensures its slow tasks are registered using edit mode time rather than play mode time.
            m_QueryBackend.ResetQueryManagement();

            GameObjectUtils.gameObjectInstantiated += m_SimulatedObjectsManager.AddSpawnedObjectToSimulation;
            m_QueryBackend.onQueryMatchFound       += k_OnQueryMatchFound;
            m_QueryBackend.onSetQueryMatchFound    += k_OnSetQueryMatchFound;
            if (simulationSettings.FindAllMatchingDataPerQuery)
            {
                m_QueryBackend.onQueryMatchesFound += k_OnQueryMatchesFound;
            }

            // inject functionality on all copied functionality subscribers
            functionalityIsland.InjectPreparedFunctionality(k_FunctionalitySubscriberObjects);

            GeoLocationModule.instance.AddOrUpdateLocationTrait();

            m_SchedulerModule.ResetTime();
            m_SimulatedObjectsManager.StartRunningSimulatables();

            ProfilerMarkers.TryStartSimulation.End();
            return(true);
        }