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