// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine.SceneManagement;
namespace Microsoft.MixedReality.Toolkit.SceneSystem
{
///
/// Interface for managing scenes in Unity.
/// Scenes are divided into three categories: Manager, Lighting and Content.
///
/// The Manager scene is loaded first and remains loaded for the duration of the app.
/// Only one Manager scene is ever loaded, and no scene operation will ever unload it.
///
/// The Lighting scene is a largely empty scene which controls lighting settings.
/// Ambient lighting, skybox, sun direction, etc. A default lighting scene is loaded on initialization.
/// After that the active lighting scene may be changed at any time via SetLightingScene.
/// Only one lighting scene can ever be loaded at a time.
///
/// Content scenes are everything else. These can be loaded and unloaded at will in any combination.
///
/// The scene actions provided improve on unity's SceneManagement events by ensuring that scenes
/// are considered valid before the action is invoked.
///
public interface IMixedRealitySceneSystem : IMixedRealityEventSystem, IMixedRealityEventSource
{
#region Actions
///
/// Called just before a set of content scenes is loaded.
/// Includes names of all scenes about to be loaded.
///
Action> OnWillLoadContent { get; set; }
///
/// Called when a set of content scenes have been loaded, activated and are valid.
/// Includes names of all scenes loaded.
///
Action> OnContentLoaded { get; set; }
///
/// Called just before a set of content scenes will be unloaded.
/// Includes names of all scenes about to be unloaded.
///
Action> OnWillUnloadContent { get; set; }
///
/// Called after a set of content scenes have been completely unloaded.
/// Includes names of all scenes about to be unloaded.
///
Action> OnContentUnloaded { get; set; }
///
/// Called just before a lighting scene is loaded.
/// Includes name of scene.
///
Action OnWillLoadLighting { get; set; }
///
/// Called when a lighting scene has been loaded, activated and is valid.
/// Includes scene name.
///
Action OnLightingLoaded { get; set; }
///
/// Called just before a lighting scene unload operation begins.
/// Includes scene name.
///
Action OnWillUnloadLighting { get; set; }
///
/// Called after a lighting scene has been completely unloaded.
/// Includes scene name.
///
Action OnLightingUnloaded { get; set; }
///
/// Called just before a scene is loaded.
/// Called for all scene types (content, lighting and manager)
/// Includes scene name
///
Action OnWillLoadScene { get; set; }
///
/// Called when scene has been loaded, activated and is valid.
/// Called for all scene types (content, lighting and manager)
/// Includes scene name
///
Action OnSceneLoaded { get; set; }
///
/// Called just before a scene will be unloaded
/// Called for all scene types (content, lighting and manager)
/// Includes scene name
///
Action OnWillUnloadScene { get; set; }
///
/// Called when scene has been unloaded
/// Called for all scene types (content, lighting and manager)
/// Includes scene name
///
Action OnSceneUnloaded { get; set; }
#endregion
#region Properties
///
/// True if the scene system is loading or unloading content scenes.
/// Manager and lighting scenes are ignored.
///
bool SceneOperationInProgress { get; }
///
/// Progress of the current scene operation, from 0-1.
/// A scene operation may include multiple concurrently loaded scenes.
///
float SceneOperationProgress { get; }
///
/// True if the scene system is transitioning from one lighting scene to another.
/// Lighting operations will not impede other operations.
///
bool LightingOperationInProgress { get; }
///
/// Progress of current lighting operation, from 0-1
///
float LightingOperationProgress { get; }
///
/// True when content has been loaded with an activation token and AllowSceneActivation has not been set to true.
/// Useful for existing entities that shouldn't act until a newly loaded scene is actually activated.
///
bool WaitingToProceed { get; }
///
/// Name of the currently loaded lighting scene.
/// If a transition is in progress, this reports the target lighting scene we're transitioning to.
///
string ActiveLightingScene { get; }
///
/// Returns true if a content scene appears in build settings PRIOR to the latest loaded build index.
/// Use to verify that LoadPrevContent can be performed without wrapping.
///
bool PrevContentExists { get; }
///
/// Returns true if a content scene appears in build settings AFTER the latest loaded build index.
/// Use to verify that LoadNextContent can be performed without wrapping.
///
bool NextContentExists { get; }
///
/// An array of content scenes available to load / unload. Order in array matches build order.
/// Useful if you want to present an ordered list of options, or if you want to track which scenes are loaded via IsContentLoaded.
///
string[] ContentSceneNames { get; }
#endregion
#region Scene Operations
///
/// Async method to load the scenes by name.
/// If a scene operation is in progress, no action will be taken.
///
/// Names of content scenes to load. Invalid scenes will be ignored.
/// Additive mode will load the content additively. Single mode will first unload all loaded content scenes first.
///
/// Optional token for manual scene activation. Useful for loading screens and multiplayer.
/// If not null, operation will wait until activationToken's AllowSceneActivation value is true before activating scene objects.
///
/// Task
Task LoadContent(IEnumerable scenesToLoad, LoadSceneMode mode = LoadSceneMode.Additive, SceneActivationToken activationToken = null);
///
/// Async method to unload scenes by name.
/// If a scene is not loaded, it will be ignored.
/// If a scene operation is in progress, no action will be taken.
///
/// Task
Task UnloadContent(IEnumerable scenesToUnload);
///
/// Async method to load a single scene by name.
/// If a scene operation is in progress, no action will be taken.
///
/// Name of content scene to load. Invalid scenes will be ignored.
/// Additive mode will load the content additively. Single mode will first unload all loaded content scenes first.
///
/// Optional token for manual scene activation. Useful for loading screens and multiplayer.
/// If not null, operation will wait until activationToken's AllowSceneActivation value is true before activating scene objects.
///
/// Task
Task LoadContent(string sceneToLoad, LoadSceneMode mode = LoadSceneMode.Additive, SceneActivationToken activationToken = null);
///
/// Async method to unload a single scene by name.
/// If the scene is not loaded, no action will be taken.
/// If a scene operation is in progress, no action will be taken.
///
/// Task
Task UnloadContent(string sceneToUnload);
///
/// Async method to load content scenes by tag. All scenes with the supplied tag will be loaded.
/// If no scenes with this tag are found, no action will be taken.
/// If a scene operation is in progress, no action will be taken.
///
/// Scene tag.
/// Additive mode will load the content additively. Single mode will first unload all loaded content scenes first.
///
/// Optional token for manual scene activation. Useful for loading screens and multiplayer.
/// If not null, operation will wait until activationToken's AllowSceneActivation value is true before activating scene objects.
///
/// Task
Task LoadContentByTag(string tag, LoadSceneMode mode = LoadSceneMode.Additive, SceneActivationToken activationToken = null);
///
/// Async method to unload scenes by name.
/// If a scene is not loaded, it will be ignored.
/// If a scene operation is in progress, no action will be taken.
///
/// Scene tag
/// Task
Task UnloadContentByTag(string tag);
///
/// Loads the next content scene according to build index.
/// Uses the last-loaded content scene as previous build index.
/// If no next content exists, and wrap is false, no action is taken.
/// Use NextContentExists to verify that this operation is possible (if not using wrap).
///
/// If true, if the current scene is the LAST content scene, the FIRST content scene will be loaded.
/// Additive mode will load the content additively. Single mode will first unload all loaded content scenes first.
///
/// Optional token for manual scene activation. Useful for loading screens and multiplayer.
/// If not null, operation will wait until activationToken's AllowSceneActivation value is true before activating scene objects.
///
/// Task
Task LoadNextContent(bool wrap = false, LoadSceneMode mode = LoadSceneMode.Single, SceneActivationToken activationToken = null);
///
/// Loads the previous content scene according to build index.
/// Uses the loaded content scene with the smallest build index as previous build index.
/// If no previous content exists, and wrap is false, no action is taken.
/// Use PrevContentExists to verify that this operation is possible (if not using wrap).
///
/// If true, if the current scene is the FIRST content scene, the LAST content scene will be loaded.
/// Additive mode will load the content additively. Single mode will first unload all loaded content scenes first.
///
/// Optional token for manual scene activation. Useful for loading screens and multiplayer.
/// If not null, operation will wait until activationToken's AllowSceneActivation value is true before activating scene objects.
///
/// Task
Task LoadPrevContent(bool wrap = false, LoadSceneMode mode = LoadSceneMode.Single, SceneActivationToken activationToken = null);
///
/// Returns true if a content scene is fully loaded.
///
bool IsContentLoaded(string sceneName);
///
/// Sets the current lighting scene. The lighting scene determines ambient light and skybox settings. It can optionally contain light objects.
/// If the lighting scene is already loaded, no action will be taken.
/// If a lighting scene transition is in progress, request will be queued and executed when the transition is complete.
///
/// The name of the lighting scene.
/// The transition type to use. See LightingSceneTransitionType for information about each transition type.
/// The duration of the transition (if not None).
void SetLightingScene(string newLightingSceneName, LightingSceneTransitionType transitionType = LightingSceneTransitionType.None, float transitionDuration = 1f);
#endregion
#region Utilities
///
/// Returns a set of scenes by name.
/// Useful for processing events.
///
IEnumerable GetScenes(IEnumerable sceneNames);
///
/// Returns a scene by name.
/// Useful for processing events.
///
Scene GetScene(string sceneName);
#endregion
}
}