// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. using System; using System.Collections.Generic; using UnityEngine; using HoloToolkit.Sharing.SyncModel; namespace HoloToolkit.Sharing.Spawning { /// <summary> /// A SpawnManager is in charge of spawning the appropriate objects based on changes to an array of data model objects /// to which it is registered. /// It also manages the lifespan of these spawned objects. /// </summary> /// <typeparam name="T">Type of SyncObject in the array being monitored by the SpawnManager.</typeparam> public abstract class SpawnManager<T> : MonoBehaviour where T : SyncObject, new() { protected SharingStage NetworkManager { get; private set; } protected SyncArray<T> SyncSource; protected List<GameObject> SyncSpawnObjectListInternal = new List<GameObject>(0); public bool IsSpawningObjects { get; protected set; } public List<GameObject> SyncSpawnObjectList { get { return SyncSpawnObjectListInternal; } } protected virtual void Start() { // SharingStage should be valid at this point, but we may not be connected. NetworkManager = SharingStage.Instance; if (NetworkManager.IsConnected) { Connected(); } else { NetworkManager.SharingManagerConnected += Connected; } } protected virtual void Connected(object sender = null, EventArgs e = null) { if (SyncSource != null) { IsSpawningObjects = true; UnRegisterToDataModel(); for (var i = 0; i < SyncSpawnObjectListInternal.Count; i++) { Destroy(SyncSpawnObjectListInternal[i]); } SyncSpawnObjectListInternal.Clear(); } SetDataModelSource(); RegisterToDataModel(); if (IsSpawningObjects) { ReSpawnObjects(); IsSpawningObjects = false; } } /// <summary> /// Sets the data model source for the spawn manager. /// </summary> protected abstract void SetDataModelSource(); /// <summary> /// Register to data model updates; /// </summary> private void RegisterToDataModel() { SyncSource.ObjectAdded += OnObjectAdded; SyncSource.ObjectRemoved += OnObjectRemoved; } private void UnRegisterToDataModel() { SyncSource.ObjectAdded -= OnObjectAdded; SyncSource.ObjectRemoved -= OnObjectRemoved; } private void OnObjectAdded(T addedObject) { InstantiateFromNetwork(addedObject); } private void OnObjectRemoved(T removedObject) { RemoveFromNetwork(removedObject); } private void ReSpawnObjects() { T[] objs = SyncSource.GetDataArray(); for (var i = 0; i < objs.Length; i++) { InstantiateFromNetwork(objs[i]); } } /// <summary> /// Delete the data model for an object and all its related game objects. /// </summary> /// <param name="objectToDelete">Object that needs to be deleted.</param> public abstract void Delete(T objectToDelete); /// <summary> /// Instantiate game objects based on data model that was created on the network. /// </summary> /// <param name="addedObject">Object that was added to the data model.</param> protected abstract void InstantiateFromNetwork(T addedObject); /// <summary> /// Remove an object based on data model that was removed on the network. /// </summary> /// <param name="removedObject">Object that was removed from the data model.</param> protected abstract void RemoveFromNetwork(T removedObject); } }