< Summary

Class:DCL.Controllers.ParcelScene
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScene.cs
Covered lines:259
Uncovered lines:89
Coverable lines:348
Total lines:809
Line coverage:74.4% (259 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.145082.35%
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%10.56050%
RemoveAllEntitiesImmediate()0%2100%
SetEntityParent(...)0%11.0611092%
SharedComponentAttach(...)0%3.043083.33%
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%9.295044.44%
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;
 55916        public Dictionary<string, IDCLEntity> entities { get; private set; } = new Dictionary<string, IDCLEntity>();
 80417        public Dictionary<string, ISharedComponent> disposableComponents { get; private set; } = new Dictionary<string, 
 347018        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 19
 55920        public HashSet<Vector2Int> parcels = new HashSet<Vector2Int>();
 21        public SceneController ownerController;
 022        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
 9832        public ContentProvider contentProvider { get; protected set; }
 33
 52234        public bool isTestScene { get; set; } = false;
 192035        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]
 55942        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        {
 55954            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 55
 55956            metricsController = new SceneMetricsController(this);
 55957            metricsController.Enable();
 58
 55959            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 55960        }
 61
 111862        private void OnDestroy() { CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition; }
 63
 111864        void OnDisable() { metricsController.Disable(); }
 65
 66        private void Update()
 67        {
 685068            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY && CommonScriptableObjects.rendererStat
 591369                SendMetricsEvent();
 685070        }
 71
 107172        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        {
 54980            this.sceneData = data;
 81
 54982            contentProvider = new ContentProvider();
 54983            contentProvider.baseUrl = data.baseUrl;
 54984            contentProvider.contents = data.contents;
 54985            contentProvider.BakeHashes();
 86
 54987            parcels.Clear();
 221688            for (int i = 0; i < sceneData.parcels.Length; i++)
 89            {
 55990                parcels.Add(sceneData.parcels[i]);
 91            }
 92
 54993            if (DCLCharacterController.i != null)
 54994                gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(data.basePo
 95
 54996            OnSetData?.Invoke(data);
 54997        }
 98
 99        void OnWorldReposition(Vector3 current, Vector3 previous)
 100        {
 3101            Vector3 sceneWorldPos = Utils.GridToWorldPosition(sceneData.basePosition.x, sceneData.basePosition.y);
 3102            gameObject.transform.position = PositionUtils.WorldToUnityPosition(sceneWorldPos);
 3103        }
 104
 105        public virtual void SetUpdateData(LoadParcelScenesMessage.UnityParcelScene data)
 106        {
 15107            contentProvider = new ContentProvider();
 15108            contentProvider.baseUrl = data.baseUrl;
 15109            contentProvider.contents = data.contents;
 15110            contentProvider.BakeHashes();
 15111        }
 112
 113        public void InitializeDebugPlane()
 114        {
 551115            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 116            {
 549117                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 118            }
 551119        }
 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        {
 555132            if (isReleased)
 0133                return;
 134
 555135            if (sceneDebugPlane != null)
 136            {
 548137                sceneDebugPlane.Dispose();
 548138                sceneDebugPlane = null;
 139            }
 140
 555141            DisposeAllSceneComponents();
 142
 555143            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 144            {
 0145                RemoveAllEntitiesImmediate();
 0146            }
 147            else
 148            {
 555149                if (entities.Count > 0)
 150                {
 197151                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 197152                    this.gameObject.SetActive(false);
 153
 197154                    RemoveAllEntities();
 197155                }
 156                else
 157                {
 358158                    Destroy(this.gameObject);
 159                }
 160            }
 161
 555162            isReleased = true;
 555163        }
 164
 0165        public override string ToString() { return "Parcel Scene: " + base.ToString() + "\n" + sceneData.ToString(); }
 166
 167        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 168        {
 111169            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 80170                return false;
 31171            if (!IsInsideSceneBoundaries(objectBounds.max + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 12172                return false;
 173
 19174            return true;
 175        }
 176
 177        public virtual bool IsInsideSceneBoundaries(Vector2Int gridPosition, float height = 0f)
 178        {
 946179            if (parcels.Count == 0)
 0180                return false;
 181
 946182            float heightLimit = metricsController.GetLimits().sceneHeight;
 183
 946184            if (height > heightLimit)
 0185                return false;
 186
 946187            return parcels.Contains(gridPosition);
 188        }
 189
 190        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 191        {
 170192            if (parcels.Count == 0)
 0193                return false;
 194
 170195            float heightLimit = metricsController.GetLimits().sceneHeight;
 170196            if (height > heightLimit)
 14197                return false;
 198
 156199            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 156200            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 201
 202            // We check the target world position
 156203            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 156204            if (parcels.Contains(targetCoordinate))
 69205                return true;
 206
 207            // We need to check using a threshold from the target point, in order to cover correctly the parcel "border/
 87208            Vector2Int coordinateMin = new Vector2Int();
 87209            coordinateMin.x = Mathf.FloorToInt((worldPosition.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 87210            coordinateMin.y = Mathf.FloorToInt((worldPosition.z - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 211
 87212            Vector2Int coordinateMax = new Vector2Int();
 87213            coordinateMax.x = Mathf.FloorToInt((worldPosition.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 87214            coordinateMax.y = Mathf.FloorToInt((worldPosition.z + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 215
 216            // We check the east/north-threshold position
 87217            targetCoordinate.Set(coordinateMax.x, coordinateMax.y);
 87218            if (parcels.Contains(targetCoordinate))
 0219                return true;
 220
 221            // We check the east/south-threshold position
 87222            targetCoordinate.Set(coordinateMax.x, coordinateMin.y);
 87223            if (parcels.Contains(targetCoordinate))
 0224                return true;
 225
 226            // We check the west/north-threshold position
 87227            targetCoordinate.Set(coordinateMin.x, coordinateMax.y);
 87228            if (parcels.Contains(targetCoordinate))
 0229                return true;
 230
 231            // We check the west/south-threshold position
 87232            targetCoordinate.Set(coordinateMin.x, coordinateMin.y);
 87233            if (parcels.Contains(targetCoordinate))
 0234                return true;
 235
 87236            return false;
 237        }
 238
 49239        public Transform GetSceneTransform() { return transform; }
 240
 241        public IDCLEntity CreateEntity(string id)
 242        {
 471243            if (entities.ContainsKey(id))
 244            {
 1245                return entities[id];
 246            }
 247
 470248            var newEntity = new DecentralandEntity();
 470249            newEntity.entityId = id;
 250
 470251            Environment.i.world.sceneController.EnsureEntityPool();
 252
 253            // As we know that the pool already exists, we just get one gameobject from it
 470254            PoolableObject po = PoolManager.i.Get(SceneController.EMPTY_GO_POOL_NAME);
 255
 470256            newEntity.meshesInfo.innerGameObject = po.gameObject;
 470257            newEntity.gameObject = po.gameObject;
 258
 259#if UNITY_EDITOR
 470260            newEntity.gameObject.name = "ENTITY_" + id;
 261#endif
 470262            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 470263            newEntity.gameObject.SetActive(true);
 470264            newEntity.scene = this;
 265
 470266            newEntity.OnCleanupEvent += po.OnCleanup;
 267
 470268            if (Environment.i.world.sceneBoundsChecker.enabled)
 393269                newEntity.OnShapeUpdated += Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 270
 470271            entities.Add(id, newEntity);
 272
 470273            OnEntityAdded?.Invoke(newEntity);
 274
 470275            return newEntity;
 276        }
 277
 278        public void RemoveEntity(string id, bool removeImmediatelyFromEntitiesList = true)
 279        {
 447280            if (entities.ContainsKey(id))
 281            {
 447282                IDCLEntity entity = entities[id];
 283
 447284                if (!entity.markedForCleanup)
 285                {
 286                    // This will also cleanup its children
 447287                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 288                }
 289
 447290                entities.Remove(id);
 447291            }
 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
 457303            using (var iterator = entity.children.GetEnumerator())
 304            {
 467305                while (iterator.MoveNext())
 306                {
 10307                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 308                }
 457309            }
 310
 457311            OnEntityRemoved?.Invoke(entity);
 312
 457313            if (Environment.i.world.sceneBoundsChecker.enabled)
 314            {
 29315                entity.OnShapeUpdated -= Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 29316                Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(entity);
 317            }
 318
 457319            if (removeImmediatelyFromEntitiesList)
 320            {
 321                // Every entity ends up being removed through here
 28322                entity.Cleanup();
 28323                entities.Remove(entity.entityId);
 28324            }
 325            else
 326            {
 429327                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 328            }
 429329        }
 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.
 197336            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 337
 197338            using (var iterator = entities.GetEnumerator())
 339            {
 639340                while (iterator.MoveNext())
 341                {
 442342                    if (iterator.Current.Value.parent == null)
 343                    {
 433344                        if (instant)
 0345                            rootEntities.Add(iterator.Current.Value);
 346                        else
 433347                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 348                    }
 349                }
 197350            }
 351
 197352            if (instant)
 353            {
 0354                int rootEntitiesCount = rootEntities.Count;
 0355                for (int i = 0; i < rootEntitiesCount; i++)
 356                {
 0357                    IDCLEntity entity = rootEntities[i];
 0358                    RemoveEntity(entity.entityId, instant);
 359                }
 360
 0361                entities.Clear();
 362
 0363                Destroy(this.gameObject);
 364            }
 197365        }
 366
 0367        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 368
 369        public void SetEntityParent(string entityId, string parentId)
 370        {
 15371            if (entityId == parentId)
 372            {
 0373                return;
 374            }
 375
 15376            IDCLEntity me = GetEntityForUpdate(entityId);
 377
 15378            if (me == null)
 0379                return;
 380
 15381            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            }
 14388            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            {
 13397                if (me.parent == DCLCharacterController.i.firstPersonCameraReference || me.parent == DCLCharacterControl
 398                {
 1399                    Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(me);
 400                }
 401
 13402                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                {
 11410                    IDCLEntity myParent = GetEntityForUpdate(parentId);
 411
 11412                    if (myParent != null)
 413                    {
 11414                        me.SetParent(myParent);
 415                    }
 416                }
 417            }
 418
 15419            Environment.i.platform.cullingController.MarkDirty();
 15420            Environment.i.platform.physicsSyncController.MarkDirty();
 15421        }
 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        {
 280428            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 429
 280430            if (decentralandEntity == null)
 431            {
 0432                return;
 433            }
 434
 280435            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 436            {
 280437                sharedComponent.AttachTo(decentralandEntity);
 438            }
 280439        }
 440
 441        public IEntityComponent EntityComponentCreateOrUpdateWithModel(string entityId, CLASS_ID_COMPONENT classId, obje
 442        {
 282443            IDCLEntity entity = GetEntityForUpdate(entityId);
 444
 282445            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
 282451            IEntityComponent newComponent = null;
 452
 282453            if (classId == CLASS_ID_COMPONENT.UUID_CALLBACK)
 454            {
 48455                OnPointerEvent.Model model = JsonUtility.FromJson<OnPointerEvent.Model>(data as string);
 48456                classId = model.GetClassIdFromType();
 457            }
 458
 282459            if (!entity.components.ContainsKey(classId))
 460            {
 221461                var factory = Environment.i.world.componentFactory;
 221462                newComponent = factory.CreateComponent((int) classId) as IEntityComponent;
 463
 221464                if (newComponent != null)
 465                {
 221466                    entity.components.Add(classId, newComponent);
 221467                    OnComponentAdded?.Invoke(newComponent);
 468
 221469                    newComponent.Initialize(this, entity);
 470
 221471                    if (data is string json)
 472                    {
 191473                        newComponent.UpdateFromJSON(json);
 191474                    }
 475                    else
 476                    {
 30477                        newComponent.UpdateFromModel(data as BaseModel);
 478                    }
 479                }
 30480            }
 481            else
 482            {
 61483                newComponent = EntityComponentUpdate(entity, classId, data as string);
 484            }
 485
 282486            if (newComponent != null && newComponent is IOutOfSceneBoundariesHandler)
 15487                Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(entity);
 488
 282489            OnChanged?.Invoke();
 282490            Environment.i.platform.physicsSyncController.MarkDirty();
 282491            Environment.i.platform.cullingController.MarkDirty();
 282492            return newComponent;
 493        }
 494
 252495        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        {
 78501            if (entity == null)
 502            {
 0503                Debug.LogError($"Can't update the {classId} component of a nonexistent entity!", this);
 0504                return null;
 505            }
 506
 78507            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
 78513            IComponent targetComponent = entity.components[classId];
 78514            targetComponent.UpdateFromJSON(componentJson);
 515
 78516            return targetComponent as IEntityComponent;
 517        }
 518
 519        public ISharedComponent SharedComponentCreate(string id, int classId)
 520        {
 455521            if (disposableComponents.TryGetValue(id, out ISharedComponent component))
 4522                return component;
 523
 451524            if (classId == (int) CLASS_ID.UI_SCREEN_SPACE_SHAPE || classId == (int) CLASS_ID.UI_FULLSCREEN_SHAPE)
 525            {
 42526                if (GetSharedComponent<UIScreenSpace>() != null)
 0527                    return null;
 528            }
 529
 451530            var factory = Environment.i.world.componentFactory;
 451531            ISharedComponent newComponent = factory.CreateComponent(classId) as ISharedComponent;
 532
 451533            if (newComponent == null)
 0534                return null;
 535
 451536            disposableComponents.Add(id, newComponent);
 451537            OnAddSharedComponent?.Invoke(id, newComponent);
 538
 451539            newComponent.Initialize(this, id);
 540
 451541            return newComponent;
 542        }
 543
 544        public void SharedComponentDispose(string id)
 545        {
 442546            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 547            {
 442548                sharedComponent?.Dispose();
 442549                disposableComponents.Remove(id);
 442550                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        {
 167569            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        {
 510653            if (disposableComponents.TryGetValue(id, out ISharedComponent disposableComponent))
 654            {
 510655                disposableComponent.UpdateFromJSON(json);
 510656                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        {
 5913673            if (Time.frameCount % 10 == 0)
 587674                metricsController.SendEvent();
 5913675        }
 676
 677        public ISharedComponent GetSharedComponent(string componentId)
 678        {
 415679            if (!disposableComponents.TryGetValue(componentId, out ISharedComponent result))
 680            {
 374681                return null;
 682            }
 683
 41684            return result;
 685        }
 686
 687        private IDCLEntity GetEntityForUpdate(string entityId)
 688        {
 606689            if (string.IsNullOrEmpty(entityId))
 690            {
 0691                Debug.LogError("Null or empty entityId");
 0692                return null;
 693            }
 694
 606695            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 696            {
 0697                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?
 606702            if (entity == null || entity.gameObject == null)
 703            {
 0704                entities.Remove(entityId);
 0705                return null;
 706            }
 707
 606708            return entity;
 709        }
 710
 711        private void DisposeAllSceneComponents()
 712        {
 1003713            List<string> allDisposableComponents = disposableComponents.Select(x => x.Key).ToList();
 2006714            foreach (string id in allDisposableComponents)
 715            {
 448716                Environment.i.platform.parcelScenesCleaner.MarkDisposableComponentForCleanup(this, id);
 717            }
 555718        }
 719
 720        public string GetStateString()
 721        {
 1071722            string baseState = isPersistent ? "global-scene" : "scene";
 1071723            switch (sceneLifecycleHandler.state)
 724            {
 725                case SceneLifecycleHandler.State.NOT_READY:
 0726                    return $"{baseState}:{prettyName} - not ready...";
 727                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 549728                    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:
 522735                    return $"{baseState}:{prettyName} - ready!";
 736            }
 737
 0738            return $"scene:{prettyName} - no state?";
 739        }
 740
 741        public void RefreshLoadingState()
 742        {
 1071743            CalculateSceneLoadingState();
 744
 745#if UNITY_EDITOR
 1071746            gameObject.name = GetStateString();
 747#endif
 1071748        }
 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        {
 1071798            loadingProgress = 0f;
 799
 1071800            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 801                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 802            {
 522803                loadingProgress = disposableComponents != null && disposableComponents.Count > 0 ? (disposableComponents
 804            }
 805
 1071806            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()