< Summary

Class:DCL.Controllers.ParcelScene
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScene.cs
Covered lines:269
Uncovered lines:79
Coverable lines:348
Total lines:809
Line coverage:77.2% (269 of 348)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ParcelScene()0%110100%
Awake()0%110100%
OnDestroy()0%110100%
OnDisable()0%110100%
Update()0%330100%
SetEditMode(...)0%2100%
IsEditModeActive()0%2100%
SetData(...)0%440100%
OnWorldReposition(...)0%110100%
SetUpdateData(...)0%110100%
InitializeDebugPlane()0%440100%
RemoveDebugPlane()0%6200%
Cleanup(...)0%5.015094.12%
ToString()0%2100%
IsInsideSceneBoundaries(...)0%330100%
IsInsideSceneBoundaries(...)0%3.333066.67%
IsInsideSceneBoundaries(...)0%8.338082.76%
GetSceneTransform()0%110100%
CreateEntity(...)0%440100%
RemoveEntity(...)0%3.143075%
CleanUpEntityRecursively(...)0%550100%
RemoveAllEntities(...)0%6.396077.78%
RemoveAllEntitiesImmediate()0%110100%
SetEntityParent(...)0%11.0611092%
SharedComponentAttach(...)0%330100%
EntityComponentCreateOrUpdateWithModel(...)0%11.0511092.59%
EntityComponentCreateOrUpdate(...)0%110100%
EntityComponentUpdate(...)0%3.793055.56%
SharedComponentCreate(...)0%7.187084.62%
SharedComponentDispose(...)0%4.134080%
EntityComponentRemove(...)0%2.032080%
GetSharedComponent[T]()0%220100%
RemoveComponentType[T](...)0%12300%
RemoveEntityComponent(...)0%11.5610075%
SharedComponentUpdate(...)0%5.23037.5%
SharedComponentUpdate(...)0%5.23037.5%
SendMetricsEvent()0%220100%
GetSharedComponent(...)0%220100%
GetEntityForUpdate(...)0%7.195055.56%
DisposeAllSceneComponents()0%330100%
GetStateString()0%27.1510044.44%
RefreshLoadingState()0%110100%
GetWaitingComponentsDebugInfo()0%42600%
CalculateSceneLoadingState()0%7.397080%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScene.cs

#LineLine coverage
 1using DCL.Components;
 2using DCL.Configuration;
 3using DCL.Helpers;
 4using DCL.Models;
 5using DCL.Controllers.ParcelSceneDebug;
 6using System.Collections.Generic;
 7using System.Linq;
 8using UnityEngine;
 9using UnityEngine.Assertions;
 10
 11namespace DCL.Controllers
 12{
 13    public class ParcelScene : MonoBehaviour, IParcelScene
 14    {
 15        public static bool VERBOSE = false;
 72616        public Dictionary<string, IDCLEntity> entities { get; private set; } = new Dictionary<string, IDCLEntity>();
 100517        public Dictionary<string, ISharedComponent> disposableComponents { get; private set; } = new Dictionary<string, 
 502518        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 19
 72620        public HashSet<Vector2Int> parcels = new HashSet<Vector2Int>();
 21        public SceneController ownerController;
 4022        public ISceneMetricsController metricsController { get; set; }
 23        public event System.Action<IDCLEntity> OnEntityAdded;
 24        public event System.Action<IDCLEntity> OnEntityRemoved;
 25        public event System.Action<IComponent> OnComponentAdded;
 26        public event System.Action<IComponent> OnComponentRemoved;
 27        public event System.Action OnChanged;
 28        public event System.Action<LoadParcelScenesMessage.UnityParcelScene> OnSetData;
 29        public event System.Action<string, ISharedComponent> OnAddSharedComponent;
 30        public event System.Action<float> OnLoadingStateUpdated;
 31
 10732        public ContentProvider contentProvider { get; protected set; }
 33
 67034        public bool isTestScene { get; set; } = false;
 227535        public bool isPersistent { get; set; } = false;
 036        public float loadingProgress { get; private set; }
 37
 38        [System.NonSerialized]
 39        public string sceneName;
 40
 41        [System.NonSerialized]
 72642        public bool unloadWithDistance = true;
 43
 44        bool isEditModeActive = false;
 45
 46        SceneDebugPlane sceneDebugPlane = null;
 47
 48        public SceneLifecycleHandler sceneLifecycleHandler;
 49
 050        public bool isReleased { get; private set; }
 51
 52        public void Awake()
 53        {
 72654            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 55
 72656            metricsController = new SceneMetricsController(this);
 72657            metricsController.Enable();
 58
 72659            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 72660        }
 61
 145262        private void OnDestroy() { CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition; }
 63
 145264        void OnDisable() { metricsController.Disable(); }
 65
 66        private void Update()
 67        {
 811668            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY && CommonScriptableObjects.rendererStat
 713769                SendMetricsEvent();
 811670        }
 71
 137372        protected virtual string prettyName => sceneData.basePosition.ToString();
 73
 074        public void SetEditMode(bool isActive) { isEditModeActive = isActive; }
 75
 076        public bool IsEditModeActive() { return isEditModeActive; }
 77
 78        public virtual void SetData(LoadParcelScenesMessage.UnityParcelScene data)
 79        {
 70380            this.sceneData = data;
 81
 70382            contentProvider = new ContentProvider();
 70383            contentProvider.baseUrl = data.baseUrl;
 70384            contentProvider.contents = data.contents;
 70385            contentProvider.BakeHashes();
 86
 70387            parcels.Clear();
 284888            for (int i = 0; i < sceneData.parcels.Length; i++)
 89            {
 72190                parcels.Add(sceneData.parcels[i]);
 91            }
 92
 70393            if (DCLCharacterController.i != null)
 70394                gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(data.basePo
 95
 70396            OnSetData?.Invoke(data);
 70397        }
 98
 99        void OnWorldReposition(Vector3 current, Vector3 previous)
 100        {
 5101            Vector3 sceneWorldPos = Utils.GridToWorldPosition(sceneData.basePosition.x, sceneData.basePosition.y);
 5102            gameObject.transform.position = PositionUtils.WorldToUnityPosition(sceneWorldPos);
 5103        }
 104
 105        public virtual void SetUpdateData(LoadParcelScenesMessage.UnityParcelScene data)
 106        {
 16107            contentProvider = new ContentProvider();
 16108            contentProvider.baseUrl = data.baseUrl;
 16109            contentProvider.contents = data.contents;
 16110            contentProvider.BakeHashes();
 16111        }
 112
 113        public void InitializeDebugPlane()
 114        {
 699115            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 116            {
 697117                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 118            }
 699119        }
 120
 121        public void RemoveDebugPlane()
 122        {
 0123            if (sceneDebugPlane != null)
 124            {
 0125                sceneDebugPlane.Dispose();
 0126                sceneDebugPlane = null;
 127            }
 0128        }
 129
 130        public void Cleanup(bool immediate)
 131        {
 718132            if (isReleased)
 0133                return;
 134
 718135            if (sceneDebugPlane != null)
 136            {
 697137                sceneDebugPlane.Dispose();
 697138                sceneDebugPlane = null;
 139            }
 140
 718141            DisposeAllSceneComponents();
 142
 718143            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 144            {
 1145                RemoveAllEntitiesImmediate();
 1146            }
 147            else
 148            {
 717149                if (entities.Count > 0)
 150                {
 254151                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 254152                    this.gameObject.SetActive(false);
 153
 254154                    RemoveAllEntities();
 254155                }
 156                else
 157                {
 463158                    Destroy(this.gameObject);
 159                }
 160            }
 161
 718162            isReleased = true;
 718163        }
 164
 0165        public override string ToString() { return "Parcel Scene: " + base.ToString() + "\n" + sceneData.ToString(); }
 166
 167        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 168        {
 164169            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 120170                return false;
 44171            if (!IsInsideSceneBoundaries(objectBounds.max + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 14172                return false;
 173
 30174            return true;
 175        }
 176
 177        public virtual bool IsInsideSceneBoundaries(Vector2Int gridPosition, float height = 0f)
 178        {
 930179            if (parcels.Count == 0)
 0180                return false;
 181
 930182            float heightLimit = metricsController.GetLimits().sceneHeight;
 183
 930184            if (height > heightLimit)
 0185                return false;
 186
 930187            return parcels.Contains(gridPosition);
 188        }
 189
 190        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 191        {
 271192            if (parcels.Count == 0)
 0193                return false;
 194
 271195            float heightLimit = metricsController.GetLimits().sceneHeight;
 271196            if (height > heightLimit)
 24197                return false;
 198
 247199            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 247200            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 201
 202            // We check the target world position
 247203            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 247204            if (parcels.Contains(targetCoordinate))
 122205                return true;
 206
 207            // We need to check using a threshold from the target point, in order to cover correctly the parcel "border/
 125208            Vector2Int coordinateMin = new Vector2Int();
 125209            coordinateMin.x = Mathf.FloorToInt((worldPosition.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 125210            coordinateMin.y = Mathf.FloorToInt((worldPosition.z - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 211
 125212            Vector2Int coordinateMax = new Vector2Int();
 125213            coordinateMax.x = Mathf.FloorToInt((worldPosition.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 125214            coordinateMax.y = Mathf.FloorToInt((worldPosition.z + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 215
 216            // We check the east/north-threshold position
 125217            targetCoordinate.Set(coordinateMax.x, coordinateMax.y);
 125218            if (parcels.Contains(targetCoordinate))
 0219                return true;
 220
 221            // We check the east/south-threshold position
 125222            targetCoordinate.Set(coordinateMax.x, coordinateMin.y);
 125223            if (parcels.Contains(targetCoordinate))
 0224                return true;
 225
 226            // We check the west/north-threshold position
 125227            targetCoordinate.Set(coordinateMin.x, coordinateMax.y);
 125228            if (parcels.Contains(targetCoordinate))
 0229                return true;
 230
 231            // We check the west/south-threshold position
 125232            targetCoordinate.Set(coordinateMin.x, coordinateMin.y);
 125233            if (parcels.Contains(targetCoordinate))
 0234                return true;
 235
 125236            return false;
 237        }
 238
 154239        public Transform GetSceneTransform() { return transform; }
 240
 241        public IDCLEntity CreateEntity(string id)
 242        {
 543243            if (entities.ContainsKey(id))
 244            {
 1245                return entities[id];
 246            }
 247
 542248            var newEntity = new DecentralandEntity();
 542249            newEntity.entityId = id;
 250
 542251            Environment.i.world.sceneController.EnsureEntityPool();
 252
 253            // As we know that the pool already exists, we just get one gameobject from it
 542254            PoolableObject po = PoolManager.i.Get(SceneController.EMPTY_GO_POOL_NAME);
 255
 542256            newEntity.meshesInfo.innerGameObject = po.gameObject;
 542257            newEntity.gameObject = po.gameObject;
 258
 259#if UNITY_EDITOR
 542260            newEntity.gameObject.name = "ENTITY_" + id;
 261#endif
 542262            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 542263            newEntity.gameObject.SetActive(true);
 542264            newEntity.scene = this;
 265
 542266            newEntity.OnCleanupEvent += po.OnCleanup;
 267
 542268            if (Environment.i.world.sceneBoundsChecker.enabled)
 455269                newEntity.OnShapeUpdated += Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 270
 542271            entities.Add(id, newEntity);
 272
 542273            OnEntityAdded?.Invoke(newEntity);
 274
 542275            return newEntity;
 276        }
 277
 278        public void RemoveEntity(string id, bool removeImmediatelyFromEntitiesList = true)
 279        {
 520280            if (entities.ContainsKey(id))
 281            {
 520282                IDCLEntity entity = entities[id];
 283
 520284                if (!entity.markedForCleanup)
 285                {
 286                    // This will also cleanup its children
 520287                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 288                }
 289
 520290                entities.Remove(id);
 520291            }
 292#if UNITY_EDITOR || DEVELOPMENT_BUILD
 293            else
 294            {
 0295                Debug.LogError($"Couldn't remove entity with ID: {id} as it doesn't exist.");
 296            }
 297#endif
 0298        }
 299
 300        void CleanUpEntityRecursively(IDCLEntity entity, bool removeImmediatelyFromEntitiesList)
 301        {
 302            // Iterate through all entity children
 529303            using (var iterator = entity.children.GetEnumerator())
 304            {
 538305                while (iterator.MoveNext())
 306                {
 9307                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 308                }
 529309            }
 310
 529311            OnEntityRemoved?.Invoke(entity);
 312
 529313            if (Environment.i.world.sceneBoundsChecker.enabled)
 314            {
 34315                entity.OnShapeUpdated -= Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 34316                Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(entity);
 317            }
 318
 529319            if (removeImmediatelyFromEntitiesList)
 320            {
 321                // Every entity ends up being removed through here
 33322                entity.Cleanup();
 33323                entities.Remove(entity.entityId);
 33324            }
 325            else
 326            {
 496327                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 328            }
 496329        }
 330
 331        void RemoveAllEntities(bool instant = false)
 332        {
 333            //NOTE(Brian): We need to remove only the rootEntities.
 334            //             If we don't, duplicated entities will get removed when destroying
 335            //             recursively, making this more complicated than it should.
 255336            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 337
 255338            using (var iterator = entities.GetEnumerator())
 339            {
 764340                while (iterator.MoveNext())
 341                {
 509342                    if (iterator.Current.Value.parent == null)
 343                    {
 501344                        if (instant)
 0345                            rootEntities.Add(iterator.Current.Value);
 346                        else
 501347                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 348                    }
 349                }
 255350            }
 351
 255352            if (instant)
 353            {
 1354                int rootEntitiesCount = rootEntities.Count;
 2355                for (int i = 0; i < rootEntitiesCount; i++)
 356                {
 0357                    IDCLEntity entity = rootEntities[i];
 0358                    RemoveEntity(entity.entityId, instant);
 359                }
 360
 1361                entities.Clear();
 362
 1363                Destroy(this.gameObject);
 364            }
 255365        }
 366
 2367        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 368
 369        public void SetEntityParent(string entityId, string parentId)
 370        {
 14371            if (entityId == parentId)
 372            {
 0373                return;
 374            }
 375
 14376            IDCLEntity me = GetEntityForUpdate(entityId);
 377
 14378            if (me == null)
 0379                return;
 380
 14381            if (parentId == "FirstPersonCameraEntityReference" || parentId == "PlayerEntityReference") // PlayerEntityRe
 382            {
 383                // In this case, the entity will attached to the first person camera
 384                // On first person mode, the entity will rotate with the camera. On third person mode, the entity will r
 1385                me.SetParent(DCLCharacterController.i.firstPersonCameraReference);
 1386                Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1387            }
 13388            else if (parentId == "AvatarEntityReference" || parentId == "AvatarPositionEntityReference") // AvatarPositi
 389            {
 390                // In this case, the entity will be attached to the avatar
 391                // It will simply rotate with the avatar, regardless of where the camera is pointing
 1392                me.SetParent(DCLCharacterController.i.avatarReference);
 1393                Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1394            }
 395            else
 396            {
 12397                if (me.parent == DCLCharacterController.i.firstPersonCameraReference || me.parent == DCLCharacterControl
 398                {
 1399                    Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(me);
 400                }
 401
 12402                if (parentId == "0")
 403                {
 404                    // The entity will be child of the scene directly
 2405                    me.SetParent(null);
 2406                    me.gameObject.transform.SetParent(gameObject.transform, false);
 2407                }
 408                else
 409                {
 10410                    IDCLEntity myParent = GetEntityForUpdate(parentId);
 411
 10412                    if (myParent != null)
 413                    {
 10414                        me.SetParent(myParent);
 415                    }
 416                }
 417            }
 418
 14419            Environment.i.platform.cullingController.MarkDirty();
 14420            Environment.i.platform.physicsSyncController.MarkDirty();
 14421        }
 422
 423        /**
 424          * This method is called when we need to attach a disposable component to the entity
 425          */
 426        public void SharedComponentAttach(string entityId, string id)
 427        {
 348428            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 429
 348430            if (decentralandEntity == null)
 431            {
 2432                return;
 433            }
 434
 346435            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 436            {
 344437                sharedComponent.AttachTo(decentralandEntity);
 438            }
 346439        }
 440
 441        public IEntityComponent EntityComponentCreateOrUpdateWithModel(string entityId, CLASS_ID_COMPONENT classId, obje
 442        {
 313443            IDCLEntity entity = GetEntityForUpdate(entityId);
 444
 313445            if (entity == null)
 446            {
 0447                Debug.LogError($"scene '{sceneData.id}': Can't create entity component if the entity {entityId} doesn't 
 0448                return null;
 449            }
 450
 313451            IEntityComponent newComponent = null;
 452
 313453            if (classId == CLASS_ID_COMPONENT.UUID_CALLBACK)
 454            {
 47455                OnPointerEvent.Model model = JsonUtility.FromJson<OnPointerEvent.Model>(data as string);
 47456                classId = model.GetClassIdFromType();
 457            }
 458
 313459            if (!entity.components.ContainsKey(classId))
 460            {
 241461                var factory = Environment.i.world.componentFactory;
 241462                newComponent = factory.CreateComponent((int) classId) as IEntityComponent;
 463
 241464                if (newComponent != null)
 465                {
 241466                    entity.components.Add(classId, newComponent);
 241467                    OnComponentAdded?.Invoke(newComponent);
 468
 241469                    newComponent.Initialize(this, entity);
 470
 241471                    if (data is string json)
 472                    {
 205473                        newComponent.UpdateFromJSON(json);
 205474                    }
 475                    else
 476                    {
 36477                        newComponent.UpdateFromModel(data as BaseModel);
 478                    }
 479                }
 36480            }
 481            else
 482            {
 72483                newComponent = EntityComponentUpdate(entity, classId, data as string);
 484            }
 485
 313486            if (newComponent != null && newComponent is IOutOfSceneBoundariesHandler)
 14487                Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(entity);
 488
 313489            OnChanged?.Invoke();
 313490            Environment.i.platform.physicsSyncController.MarkDirty();
 313491            Environment.i.platform.cullingController.MarkDirty();
 313492            return newComponent;
 493        }
 494
 277495        public IEntityComponent EntityComponentCreateOrUpdate(string entityId, CLASS_ID_COMPONENT classId, string data) 
 496
 497        // The EntityComponentUpdate() parameters differ from other similar methods because there is no EntityComponentU
 498        public IEntityComponent EntityComponentUpdate(IDCLEntity entity, CLASS_ID_COMPONENT classId,
 499            string componentJson)
 500        {
 89501            if (entity == null)
 502            {
 0503                Debug.LogError($"Can't update the {classId} component of a nonexistent entity!", this);
 0504                return null;
 505            }
 506
 89507            if (!entity.components.ContainsKey(classId))
 508            {
 0509                Debug.LogError($"Entity {entity.entityId} doesn't have a {classId} component to update!", this);
 0510                return null;
 511            }
 512
 89513            IComponent targetComponent = entity.components[classId];
 89514            targetComponent.UpdateFromJSON(componentJson);
 515
 89516            return targetComponent as IEntityComponent;
 517        }
 518
 519        public ISharedComponent SharedComponentCreate(string id, int classId)
 520        {
 541521            if (disposableComponents.TryGetValue(id, out ISharedComponent component))
 4522                return component;
 523
 537524            if (classId == (int) CLASS_ID.UI_SCREEN_SPACE_SHAPE || classId == (int) CLASS_ID.UI_FULLSCREEN_SHAPE)
 525            {
 43526                if (GetSharedComponent<UIScreenSpace>() != null)
 0527                    return null;
 528            }
 529
 537530            var factory = Environment.i.world.componentFactory;
 537531            ISharedComponent newComponent = factory.CreateComponent(classId) as ISharedComponent;
 532
 537533            if (newComponent == null)
 0534                return null;
 535
 537536            disposableComponents.Add(id, newComponent);
 537537            OnAddSharedComponent?.Invoke(id, newComponent);
 538
 537539            newComponent.Initialize(this, id);
 540
 537541            return newComponent;
 542        }
 543
 544        public void SharedComponentDispose(string id)
 545        {
 528546            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 547            {
 528548                sharedComponent?.Dispose();
 528549                disposableComponents.Remove(id);
 528550                OnComponentRemoved?.Invoke(sharedComponent);
 551            }
 0552        }
 553
 554        public void EntityComponentRemove(string entityId, string name)
 555        {
 18556            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 557
 18558            if (decentralandEntity == null)
 559            {
 0560                return;
 561            }
 562
 18563            RemoveEntityComponent(decentralandEntity, name);
 18564        }
 565
 566        public T GetSharedComponent<T>()
 567            where T : class
 568        {
 166569            return disposableComponents.Values.FirstOrDefault(x => x is T) as T;
 570        }
 571
 572        private void RemoveComponentType<T>(IDCLEntity entity, CLASS_ID_COMPONENT classId)
 573            where T : MonoBehaviour
 574        {
 0575            var component = entity.components[classId] as IEntityComponent;
 576
 0577            if (component == null)
 0578                return;
 579
 0580            var monoBehaviour = component.GetTransform().GetComponent<T>();
 581
 0582            if (monoBehaviour != null)
 583            {
 0584                Utils.SafeDestroy(monoBehaviour);
 585            }
 0586        }
 587
 588        private void RemoveEntityComponent(IDCLEntity entity, string componentName)
 589        {
 590            switch (componentName)
 591            {
 592                case "shape":
 0593                    if (entity.meshesInfo.currentShape is BaseShape baseShape)
 594                    {
 0595                        baseShape.DetachFrom(entity);
 596                    }
 597
 0598                    return;
 599
 600                case OnClick.NAME:
 601                    {
 1602                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_CLICK, out IEntityComponent component
 603                        {
 1604                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1605                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_CLICK );
 606                        }
 607
 1608                        return;
 609                    }
 610                case OnPointerDown.NAME:
 611                    {
 1612                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_DOWN, out IEntityComponent component 
 613                        {
 1614                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1615                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_DOWN );
 616                        }
 617                    }
 1618                    return;
 619                case OnPointerUp.NAME:
 620                    {
 1621                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_UP, out IEntityComponent component ))
 622                        {
 1623                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1624                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_UP );
 625                        }
 626                    }
 1627                    return;
 628            }
 0629        }
 630
 631        public ISharedComponent SharedComponentUpdate(string id, BaseModel model)
 632        {
 27633            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 634            {
 27635                sharedComponent.UpdateFromModel(model);
 27636                return sharedComponent;
 637            }
 638
 0639            if (gameObject == null)
 640            {
 0641                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0642            }
 643            else
 644            {
 0645                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 646            }
 647
 0648            return null;
 649        }
 650
 651        public ISharedComponent SharedComponentUpdate(string id, string json)
 652        {
 560653            if (disposableComponents.TryGetValue(id, out ISharedComponent disposableComponent))
 654            {
 560655                disposableComponent.UpdateFromJSON(json);
 560656                return disposableComponent;
 657            }
 658
 0659            if (gameObject == null)
 660            {
 0661                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0662            }
 663            else
 664            {
 0665                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 666            }
 667
 0668            return null;
 669        }
 670
 671        protected virtual void SendMetricsEvent()
 672        {
 7137673            if (Time.frameCount % 10 == 0)
 727674                metricsController.SendEvent();
 7137675        }
 676
 677        public ISharedComponent GetSharedComponent(string componentId)
 678        {
 469679            if (!disposableComponents.TryGetValue(componentId, out ISharedComponent result))
 680            {
 426681                return null;
 682            }
 683
 43684            return result;
 685        }
 686
 687        private IDCLEntity GetEntityForUpdate(string entityId)
 688        {
 703689            if (string.IsNullOrEmpty(entityId))
 690            {
 0691                Debug.LogError("Null or empty entityId");
 0692                return null;
 693            }
 694
 703695            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 696            {
 2697                return null;
 698            }
 699
 700            //NOTE(Brian): This is for removing stray null references? This should never happen.
 701            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 701702            if (entity == null || entity.gameObject == null)
 703            {
 0704                entities.Remove(entityId);
 0705                return null;
 706            }
 707
 701708            return entity;
 709        }
 710
 711        private void DisposeAllSceneComponents()
 712        {
 1252713            List<string> allDisposableComponents = disposableComponents.Select(x => x.Key).ToList();
 2504714            foreach (string id in allDisposableComponents)
 715            {
 534716                Environment.i.platform.parcelScenesCleaner.MarkDisposableComponentForCleanup(this, id);
 717            }
 718718        }
 719
 720        public string GetStateString()
 721        {
 1373722            string baseState = isPersistent ? "global-scene" : "scene";
 1373723            switch (sceneLifecycleHandler.state)
 724            {
 725                case SceneLifecycleHandler.State.NOT_READY:
 0726                    return $"{baseState}:{prettyName} - not ready...";
 727                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 703728                    return $"{baseState}:{prettyName} - waiting for init messages...";
 729                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0730                    if (disposableComponents != null && disposableComponents.Count > 0)
 0731                        return $"{baseState}:{prettyName} - left to ready:{disposableComponents.Count - sceneLifecycleHa
 732                    else
 0733                        return $"{baseState}:{prettyName} - no components. waiting...";
 734                case SceneLifecycleHandler.State.READY:
 670735                    return $"{baseState}:{prettyName} - ready!";
 736            }
 737
 0738            return $"scene:{prettyName} - no state?";
 739        }
 740
 741        public void RefreshLoadingState()
 742        {
 1373743            CalculateSceneLoadingState();
 744
 745#if UNITY_EDITOR
 1373746            gameObject.name = GetStateString();
 747#endif
 1373748        }
 749
 750        [ContextMenu("Get Waiting Components Debug Info")]
 751        public void GetWaitingComponentsDebugInfo()
 752        {
 0753            switch (sceneLifecycleHandler.state)
 754            {
 755                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 756
 0757                    foreach (string componentId in sceneLifecycleHandler.disposableNotReady)
 758                    {
 0759                        if (disposableComponents.ContainsKey(componentId))
 760                        {
 0761                            var component = disposableComponents[componentId];
 762
 0763                            Debug.Log($"Waiting for: {component.ToString()}");
 764
 0765                            foreach (var entity in component.GetAttachedEntities())
 766                            {
 0767                                var loader = LoadableShape.GetLoaderForEntity(entity);
 768
 0769                                string loadInfo = "No loader";
 770
 0771                                if (loader != null)
 772                                {
 0773                                    loadInfo = loader.ToString();
 774                                }
 775
 0776                                Debug.Log($"This shape is attached to {entity.entityId} entity. Click here for highlight
 777                            }
 778                        }
 779                        else
 780                        {
 0781                            Debug.Log($"Waiting for missing component? id: {componentId}");
 782                        }
 783                    }
 784
 785                    break;
 786
 787                default:
 0788                    Debug.Log("This scene is not waiting for any components. Its current state is " + sceneLifecycleHand
 789                    break;
 790            }
 0791        }
 792
 793        /// <summary>
 794        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 795        /// </summary>
 796        public void CalculateSceneLoadingState()
 797        {
 1373798            loadingProgress = 0f;
 799
 1373800            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 801                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 802            {
 670803                loadingProgress = disposableComponents != null && disposableComponents.Count > 0 ? (disposableComponents
 804            }
 805
 1373806            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0807        }
 808    }
 809}

Methods/Properties

entities()
entities(System.Collections.Generic.Dictionary[String,IDCLEntity])
ParcelScene()
disposableComponents()
disposableComponents(System.Collections.Generic.Dictionary[String,ISharedComponent])
sceneData()
sceneData(DCL.Models.LoadParcelScenesMessage/UnityParcelScene)
metricsController()
metricsController(DCL.ISceneMetricsController)
contentProvider()
contentProvider(DCL.ContentProvider)
isTestScene()
isTestScene(System.Boolean)
isPersistent()
isPersistent(System.Boolean)
loadingProgress()
loadingProgress(System.Single)
isReleased()
isReleased(System.Boolean)
Awake()
OnDestroy()
OnDisable()
Update()
prettyName()
SetEditMode(System.Boolean)
IsEditModeActive()
SetData(DCL.Models.LoadParcelScenesMessage/UnityParcelScene)
OnWorldReposition(UnityEngine.Vector3, UnityEngine.Vector3)
SetUpdateData(DCL.Models.LoadParcelScenesMessage/UnityParcelScene)
InitializeDebugPlane()
RemoveDebugPlane()
Cleanup(System.Boolean)
ToString()
IsInsideSceneBoundaries(UnityEngine.Bounds)
IsInsideSceneBoundaries(UnityEngine.Vector2Int, System.Single)
IsInsideSceneBoundaries(UnityEngine.Vector3, System.Single)
GetSceneTransform()
CreateEntity(System.String)
RemoveEntity(System.String, System.Boolean)
CleanUpEntityRecursively(DCL.Models.IDCLEntity, System.Boolean)
RemoveAllEntities(System.Boolean)
RemoveAllEntitiesImmediate()
SetEntityParent(System.String, System.String)
SharedComponentAttach(System.String, System.String)
EntityComponentCreateOrUpdateWithModel(System.String, DCL.Models.CLASS_ID_COMPONENT, System.Object)
EntityComponentCreateOrUpdate(System.String, DCL.Models.CLASS_ID_COMPONENT, System.String)
EntityComponentUpdate(DCL.Models.IDCLEntity, DCL.Models.CLASS_ID_COMPONENT, System.String)
SharedComponentCreate(System.String, System.Int32)
SharedComponentDispose(System.String)
EntityComponentRemove(System.String, System.String)
GetSharedComponent[T]()
RemoveComponentType[T](DCL.Models.IDCLEntity, DCL.Models.CLASS_ID_COMPONENT)
RemoveEntityComponent(DCL.Models.IDCLEntity, System.String)
SharedComponentUpdate(System.String, BaseModel)
SharedComponentUpdate(System.String, System.String)
SendMetricsEvent()
GetSharedComponent(System.String)
GetEntityForUpdate(System.String)
DisposeAllSceneComponents()
GetStateString()
RefreshLoadingState()
GetWaitingComponentsDebugInfo()
CalculateSceneLoadingState()