| | 1 | | using System; |
| | 2 | | using UnityEngine; |
| | 3 | | using UnityEngine.Assertions; |
| | 4 | |
|
| | 5 | | namespace DCL |
| | 6 | | { |
| | 7 | | /// <summary> |
| | 8 | | /// This class wraps around the DataStore's DataStore_WorldObjects instance. |
| | 9 | | /// |
| | 10 | | /// The DataStore_WorldObjects scene data objects must be removed aggressively when the |
| | 11 | | /// DataStore_WorldObjects.SceneData is empty, right after the last object is removed. |
| | 12 | | /// |
| | 13 | | /// The DataStore_WorldObjects.SceneData objects can't be removed just when the scene is |
| | 14 | | /// unloaded because the underlying assets are removed lazily (i.e. by ParcelScenesCleaner). |
| | 15 | | /// |
| | 16 | | /// This helper ensures that any events persist even in the case of the scene being removed and then |
| | 17 | | /// added due to the last object being removed and then added again. |
| | 18 | | /// </summary> |
| | 19 | | public class WorldSceneObjectsTrackingHelper : IDisposable |
| | 20 | | { |
| 1 | 21 | | private static bool VERBOSE = false; |
| 1 | 22 | | private static ILogger logger = new Logger(Debug.unityLogger.logHandler) { filterLogType = VERBOSE ? LogType.Log |
| | 23 | |
|
| 0 | 24 | | public DataStore.DataStore_WorldObjects.SceneData sceneData { get; private set; } |
| | 25 | | public event Action<Rendereable> OnWillAddRendereable; |
| | 26 | | public event Action<Rendereable> OnWillRemoveRendereable; |
| | 27 | |
|
| | 28 | | private string sceneId; |
| | 29 | | private DataStore dataStore; |
| | 30 | |
|
| 710 | 31 | | public WorldSceneObjectsTrackingHelper (DataStore dataStore, string sceneId) |
| | 32 | | { |
| 710 | 33 | | logger.Log("A wild WorldSceneObjectsTrackingHelper appears!"); |
| 710 | 34 | | this.dataStore = dataStore; |
| 710 | 35 | | this.sceneId = sceneId; |
| | 36 | |
|
| 710 | 37 | | if (dataStore.sceneWorldObjects.sceneData.ContainsKey(sceneId)) |
| 0 | 38 | | SetSceneData(dataStore.sceneWorldObjects.sceneData[sceneId]); |
| | 39 | |
|
| 710 | 40 | | dataStore.sceneWorldObjects.sceneData.OnAdded += OnSceneAdded; |
| 710 | 41 | | dataStore.sceneWorldObjects.sceneData.OnRemoved += OnSceneRemoved; |
| 710 | 42 | | } |
| | 43 | |
|
| | 44 | | private void OnSceneRemoved(string sceneId, DataStore.DataStore_WorldObjects.SceneData arg2) |
| | 45 | | { |
| 204 | 46 | | if ( sceneId != this.sceneId ) |
| 0 | 47 | | return; |
| | 48 | |
|
| | 49 | | // Set dummy scene data so null reference exceptions are avoided. |
| 204 | 50 | | logger.Log($"Scene {sceneId} was removed! Using dummy scene data."); |
| 204 | 51 | | SetSceneData( new DataStore.DataStore_WorldObjects.SceneData() ); |
| 204 | 52 | | } |
| | 53 | |
|
| | 54 | | private void OnSceneAdded(string sceneId, DataStore.DataStore_WorldObjects.SceneData sceneData) |
| | 55 | | { |
| 212 | 56 | | if ( sceneId != this.sceneId ) |
| 0 | 57 | | return; |
| | 58 | |
|
| 212 | 59 | | logger.Log($"Scene {sceneId} was added!"); |
| 212 | 60 | | SetSceneData( sceneData ); |
| 212 | 61 | | } |
| | 62 | |
|
| | 63 | | private void SetSceneData(DataStore.DataStore_WorldObjects.SceneData sceneData) |
| | 64 | | { |
| 416 | 65 | | Assert.IsNotNull(sceneData, "sceneData should never be null!"); |
| | 66 | |
|
| 416 | 67 | | if ( sceneData == this.sceneData ) |
| 0 | 68 | | return; |
| | 69 | |
|
| 416 | 70 | | if ( this.sceneData != null ) |
| | 71 | | { |
| | 72 | | // This should never happen because of how the flow works. |
| | 73 | | // |
| | 74 | | // Scenes with the same sceneId shouldn't ever be added twice, and if this happens |
| | 75 | | // we have an early exit. |
| 260 | 76 | | this.sceneData.renderedObjects.OnAdded -= OnRenderedObjectsAdded; |
| 260 | 77 | | this.sceneData.renderedObjects.OnRemoved -= OnRenderedObjectsRemoved; |
| | 78 | | } |
| | 79 | |
|
| 416 | 80 | | logger.Log($"Subscribing events for {sceneId}."); |
| 416 | 81 | | sceneData.renderedObjects.OnAdded += OnRenderedObjectsAdded; |
| 416 | 82 | | sceneData.renderedObjects.OnRemoved += OnRenderedObjectsRemoved; |
| | 83 | |
|
| 416 | 84 | | this.sceneData = sceneData; |
| 416 | 85 | | } |
| | 86 | |
|
| | 87 | | private void OnRenderedObjectsRemoved(Rendereable rendereable) |
| | 88 | | { |
| 271 | 89 | | logger.Log($"Removing rendereable."); |
| 271 | 90 | | OnWillRemoveRendereable?.Invoke(rendereable); |
| 101 | 91 | | } |
| | 92 | |
|
| | 93 | | private void OnRenderedObjectsAdded(Rendereable rendereable) |
| | 94 | | { |
| 278 | 95 | | logger.Log($"Adding rendereable."); |
| 278 | 96 | | OnWillAddRendereable?.Invoke(rendereable); |
| 278 | 97 | | } |
| | 98 | |
|
| | 99 | | public void Dispose() |
| | 100 | | { |
| 710 | 101 | | if ( sceneData == null ) |
| 554 | 102 | | return; |
| | 103 | |
|
| 156 | 104 | | sceneData.renderedObjects.OnAdded -= OnRenderedObjectsAdded; |
| 156 | 105 | | sceneData.renderedObjects.OnRemoved -= OnRenderedObjectsRemoved; |
| | 106 | |
|
| 156 | 107 | | dataStore.sceneWorldObjects.sceneData.OnAdded -= OnSceneAdded; |
| 156 | 108 | | dataStore.sceneWorldObjects.sceneData.OnRemoved -= OnSceneRemoved; |
| 156 | 109 | | logger.Log($"Disposing."); |
| 156 | 110 | | } |
| | 111 | | } |
| | 112 | | } |