< 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:810
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 MainScripts.DCL.WorldRuntime;
 9using UnityEngine;
 10using UnityEngine.Assertions;
 11
 12namespace DCL.Controllers
 13{
 14    public class ParcelScene : MonoBehaviour, IParcelScene, ISceneMessageProcessor
 15    {
 16        public static bool VERBOSE = false;
 72617        public Dictionary<string, IDCLEntity> entities { get; private set; } = new Dictionary<string, IDCLEntity>();
 100518        public Dictionary<string, ISharedComponent> disposableComponents { get; private set; } = new Dictionary<string, 
 511819        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 20
 72621        public HashSet<Vector2Int> parcels = new HashSet<Vector2Int>();
 22        public SceneController ownerController;
 4023        public ISceneMetricsController metricsController { get; set; }
 24        public event System.Action<IDCLEntity> OnEntityAdded;
 25        public event System.Action<IDCLEntity> OnEntityRemoved;
 26        public event System.Action<IComponent> OnComponentAdded;
 27        public event System.Action<IComponent> OnComponentRemoved;
 28        public event System.Action OnChanged;
 29        public event System.Action<LoadParcelScenesMessage.UnityParcelScene> OnSetData;
 30        public event System.Action<string, ISharedComponent> OnAddSharedComponent;
 31        public event System.Action<float> OnLoadingStateUpdated;
 32
 10733        public ContentProvider contentProvider { get; protected set; }
 34
 67035        public bool isTestScene { get; set; } = false;
 230136        public bool isPersistent { get; set; } = false;
 037        public float loadingProgress { get; private set; }
 38
 39        [System.NonSerialized]
 40        public string sceneName;
 41
 42        [System.NonSerialized]
 72643        public bool unloadWithDistance = true;
 44
 45        bool isEditModeActive = false;
 46
 47        SceneDebugPlane sceneDebugPlane = null;
 48
 49        public SceneLifecycleHandler sceneLifecycleHandler;
 50
 051        public bool isReleased { get; private set; }
 52
 53        public void Awake()
 54        {
 72655            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 56
 72657            metricsController = new SceneMetricsController(this);
 72658            metricsController.Enable();
 59
 72660            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 72661        }
 62
 145263        private void OnDestroy() { CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition; }
 64
 145265        void OnDisable() { metricsController.Disable(); }
 66
 67        private void Update()
 68        {
 809769            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY && CommonScriptableObjects.rendererStat
 712470                SendMetricsEvent();
 809771        }
 72
 137373        protected virtual string prettyName => sceneData.basePosition.ToString();
 74
 075        public void SetEditMode(bool isActive) { isEditModeActive = isActive; }
 76
 077        public bool IsEditModeActive() { return isEditModeActive; }
 78
 79        public virtual void SetData(LoadParcelScenesMessage.UnityParcelScene data)
 80        {
 70381            this.sceneData = data;
 82
 70383            contentProvider = new ContentProvider();
 70384            contentProvider.baseUrl = data.baseUrl;
 70385            contentProvider.contents = data.contents;
 70386            contentProvider.BakeHashes();
 87
 70388            parcels.Clear();
 284889            for (int i = 0; i < sceneData.parcels.Length; i++)
 90            {
 72191                parcels.Add(sceneData.parcels[i]);
 92            }
 93
 70394            if (DCLCharacterController.i != null)
 70395                gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(data.basePo
 96
 70397            OnSetData?.Invoke(data);
 70398        }
 99
 100        void OnWorldReposition(Vector3 current, Vector3 previous)
 101        {
 5102            Vector3 sceneWorldPos = Utils.GridToWorldPosition(sceneData.basePosition.x, sceneData.basePosition.y);
 5103            gameObject.transform.position = PositionUtils.WorldToUnityPosition(sceneWorldPos);
 5104        }
 105
 106        public virtual void SetUpdateData(LoadParcelScenesMessage.UnityParcelScene data)
 107        {
 16108            contentProvider = new ContentProvider();
 16109            contentProvider.baseUrl = data.baseUrl;
 16110            contentProvider.contents = data.contents;
 16111            contentProvider.BakeHashes();
 16112        }
 113
 114        public void InitializeDebugPlane()
 115        {
 699116            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 117            {
 697118                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 119            }
 699120        }
 121
 122        public void RemoveDebugPlane()
 123        {
 0124            if (sceneDebugPlane != null)
 125            {
 0126                sceneDebugPlane.Dispose();
 0127                sceneDebugPlane = null;
 128            }
 0129        }
 130
 131        public void Cleanup(bool immediate)
 132        {
 718133            if (isReleased)
 0134                return;
 135
 718136            if (sceneDebugPlane != null)
 137            {
 697138                sceneDebugPlane.Dispose();
 697139                sceneDebugPlane = null;
 140            }
 141
 718142            DisposeAllSceneComponents();
 143
 718144            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 145            {
 1146                RemoveAllEntitiesImmediate();
 1147            }
 148            else
 149            {
 717150                if (entities.Count > 0)
 151                {
 254152                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 254153                    this.gameObject.SetActive(false);
 154
 254155                    RemoveAllEntities();
 254156                }
 157                else
 158                {
 463159                    Destroy(this.gameObject);
 160                }
 161            }
 162
 718163            isReleased = true;
 718164        }
 165
 0166        public override string ToString() { return "Parcel Scene: " + base.ToString() + "\n" + sceneData.ToString(); }
 167
 168        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 169        {
 164170            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 120171                return false;
 44172            if (!IsInsideSceneBoundaries(objectBounds.max + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 14173                return false;
 174
 30175            return true;
 176        }
 177
 178        public virtual bool IsInsideSceneBoundaries(Vector2Int gridPosition, float height = 0f)
 179        {
 1001180            if (parcels.Count == 0)
 0181                return false;
 182
 1001183            float heightLimit = metricsController.GetLimits().sceneHeight;
 184
 1001185            if (height > heightLimit)
 0186                return false;
 187
 1001188            return parcels.Contains(gridPosition);
 189        }
 190
 191        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 192        {
 269193            if (parcels.Count == 0)
 0194                return false;
 195
 269196            float heightLimit = metricsController.GetLimits().sceneHeight;
 269197            if (height > heightLimit)
 24198                return false;
 199
 245200            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 245201            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 202
 203            // We check the target world position
 245204            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 245205            if (parcels.Contains(targetCoordinate))
 120206                return true;
 207
 208            // We need to check using a threshold from the target point, in order to cover correctly the parcel "border/
 125209            Vector2Int coordinateMin = new Vector2Int();
 125210            coordinateMin.x = Mathf.FloorToInt((worldPosition.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 125211            coordinateMin.y = Mathf.FloorToInt((worldPosition.z - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 212
 125213            Vector2Int coordinateMax = new Vector2Int();
 125214            coordinateMax.x = Mathf.FloorToInt((worldPosition.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 125215            coordinateMax.y = Mathf.FloorToInt((worldPosition.z + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 216
 217            // We check the east/north-threshold position
 125218            targetCoordinate.Set(coordinateMax.x, coordinateMax.y);
 125219            if (parcels.Contains(targetCoordinate))
 0220                return true;
 221
 222            // We check the east/south-threshold position
 125223            targetCoordinate.Set(coordinateMax.x, coordinateMin.y);
 125224            if (parcels.Contains(targetCoordinate))
 0225                return true;
 226
 227            // We check the west/north-threshold position
 125228            targetCoordinate.Set(coordinateMin.x, coordinateMax.y);
 125229            if (parcels.Contains(targetCoordinate))
 0230                return true;
 231
 232            // We check the west/south-threshold position
 125233            targetCoordinate.Set(coordinateMin.x, coordinateMin.y);
 125234            if (parcels.Contains(targetCoordinate))
 0235                return true;
 236
 125237            return false;
 238        }
 239
 154240        public Transform GetSceneTransform() { return transform; }
 241
 242        public IDCLEntity CreateEntity(string id)
 243        {
 543244            if (entities.ContainsKey(id))
 245            {
 1246                return entities[id];
 247            }
 248
 542249            var newEntity = new DecentralandEntity();
 542250            newEntity.entityId = id;
 251
 542252            Environment.i.world.sceneController.EnsureEntityPool();
 253
 254            // As we know that the pool already exists, we just get one gameobject from it
 542255            PoolableObject po = PoolManager.i.Get(SceneController.EMPTY_GO_POOL_NAME);
 256
 542257            newEntity.meshesInfo.innerGameObject = po.gameObject;
 542258            newEntity.gameObject = po.gameObject;
 259
 260#if UNITY_EDITOR
 542261            newEntity.gameObject.name = "ENTITY_" + id;
 262#endif
 542263            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 542264            newEntity.gameObject.SetActive(true);
 542265            newEntity.scene = this;
 266
 542267            newEntity.OnCleanupEvent += po.OnCleanup;
 268
 542269            if (Environment.i.world.sceneBoundsChecker.enabled)
 455270                newEntity.OnShapeUpdated += Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 271
 542272            entities.Add(id, newEntity);
 273
 542274            OnEntityAdded?.Invoke(newEntity);
 275
 542276            return newEntity;
 277        }
 278
 279        public void RemoveEntity(string id, bool removeImmediatelyFromEntitiesList = true)
 280        {
 520281            if (entities.ContainsKey(id))
 282            {
 520283                IDCLEntity entity = entities[id];
 284
 520285                if (!entity.markedForCleanup)
 286                {
 287                    // This will also cleanup its children
 520288                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 289                }
 290
 520291                entities.Remove(id);
 520292            }
 293#if UNITY_EDITOR || DEVELOPMENT_BUILD
 294            else
 295            {
 0296                Debug.LogError($"Couldn't remove entity with ID: {id} as it doesn't exist.");
 297            }
 298#endif
 0299        }
 300
 301        void CleanUpEntityRecursively(IDCLEntity entity, bool removeImmediatelyFromEntitiesList)
 302        {
 303            // Iterate through all entity children
 529304            using (var iterator = entity.children.GetEnumerator())
 305            {
 538306                while (iterator.MoveNext())
 307                {
 9308                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 309                }
 529310            }
 311
 529312            OnEntityRemoved?.Invoke(entity);
 313
 529314            if (Environment.i.world.sceneBoundsChecker.enabled)
 315            {
 34316                entity.OnShapeUpdated -= Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 34317                Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(entity);
 318            }
 319
 529320            if (removeImmediatelyFromEntitiesList)
 321            {
 322                // Every entity ends up being removed through here
 33323                entity.Cleanup();
 33324                entities.Remove(entity.entityId);
 33325            }
 326            else
 327            {
 496328                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 329            }
 496330        }
 331
 332        void RemoveAllEntities(bool instant = false)
 333        {
 334            //NOTE(Brian): We need to remove only the rootEntities.
 335            //             If we don't, duplicated entities will get removed when destroying
 336            //             recursively, making this more complicated than it should.
 255337            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 338
 255339            using (var iterator = entities.GetEnumerator())
 340            {
 764341                while (iterator.MoveNext())
 342                {
 509343                    if (iterator.Current.Value.parent == null)
 344                    {
 501345                        if (instant)
 0346                            rootEntities.Add(iterator.Current.Value);
 347                        else
 501348                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 349                    }
 350                }
 255351            }
 352
 255353            if (instant)
 354            {
 1355                int rootEntitiesCount = rootEntities.Count;
 2356                for (int i = 0; i < rootEntitiesCount; i++)
 357                {
 0358                    IDCLEntity entity = rootEntities[i];
 0359                    RemoveEntity(entity.entityId, instant);
 360                }
 361
 1362                entities.Clear();
 363
 1364                Destroy(this.gameObject);
 365            }
 255366        }
 367
 2368        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 369
 370        public void SetEntityParent(string entityId, string parentId)
 371        {
 14372            if (entityId == parentId)
 373            {
 0374                return;
 375            }
 376
 14377            IDCLEntity me = GetEntityForUpdate(entityId);
 378
 14379            if (me == null)
 0380                return;
 381
 14382            if (parentId == "FirstPersonCameraEntityReference" || parentId == "PlayerEntityReference") // PlayerEntityRe
 383            {
 384                // In this case, the entity will attached to the first person camera
 385                // On first person mode, the entity will rotate with the camera. On third person mode, the entity will r
 1386                me.SetParent(DCLCharacterController.i.firstPersonCameraReference);
 1387                Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1388            }
 13389            else if (parentId == "AvatarEntityReference" || parentId == "AvatarPositionEntityReference") // AvatarPositi
 390            {
 391                // In this case, the entity will be attached to the avatar
 392                // It will simply rotate with the avatar, regardless of where the camera is pointing
 1393                me.SetParent(DCLCharacterController.i.avatarReference);
 1394                Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1395            }
 396            else
 397            {
 12398                if (me.parent == DCLCharacterController.i.firstPersonCameraReference || me.parent == DCLCharacterControl
 399                {
 1400                    Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(me);
 401                }
 402
 12403                if (parentId == "0")
 404                {
 405                    // The entity will be child of the scene directly
 2406                    me.SetParent(null);
 2407                    me.gameObject.transform.SetParent(gameObject.transform, false);
 2408                }
 409                else
 410                {
 10411                    IDCLEntity myParent = GetEntityForUpdate(parentId);
 412
 10413                    if (myParent != null)
 414                    {
 10415                        me.SetParent(myParent);
 416                    }
 417                }
 418            }
 419
 14420            Environment.i.platform.cullingController.MarkDirty();
 14421            Environment.i.platform.physicsSyncController.MarkDirty();
 14422        }
 423
 424        /**
 425          * This method is called when we need to attach a disposable component to the entity
 426          */
 427        public void SharedComponentAttach(string entityId, string id)
 428        {
 348429            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 430
 348431            if (decentralandEntity == null)
 432            {
 2433                return;
 434            }
 435
 346436            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 437            {
 344438                sharedComponent.AttachTo(decentralandEntity);
 439            }
 346440        }
 441
 442        public IEntityComponent EntityComponentCreateOrUpdateWithModel(string entityId, CLASS_ID_COMPONENT classId, obje
 443        {
 313444            IDCLEntity entity = GetEntityForUpdate(entityId);
 445
 313446            if (entity == null)
 447            {
 0448                Debug.LogError($"scene '{sceneData.id}': Can't create entity component if the entity {entityId} doesn't 
 0449                return null;
 450            }
 451
 313452            IEntityComponent newComponent = null;
 453
 313454            if (classId == CLASS_ID_COMPONENT.UUID_CALLBACK)
 455            {
 47456                OnPointerEvent.Model model = JsonUtility.FromJson<OnPointerEvent.Model>(data as string);
 47457                classId = model.GetClassIdFromType();
 458            }
 459
 313460            if (!entity.components.ContainsKey(classId))
 461            {
 241462                var factory = Environment.i.world.componentFactory;
 241463                newComponent = factory.CreateComponent((int) classId) as IEntityComponent;
 464
 241465                if (newComponent != null)
 466                {
 241467                    entity.components.Add(classId, newComponent);
 241468                    OnComponentAdded?.Invoke(newComponent);
 469
 241470                    newComponent.Initialize(this, entity);
 471
 241472                    if (data is string json)
 473                    {
 205474                        newComponent.UpdateFromJSON(json);
 205475                    }
 476                    else
 477                    {
 36478                        newComponent.UpdateFromModel(data as BaseModel);
 479                    }
 480                }
 36481            }
 482            else
 483            {
 72484                newComponent = EntityComponentUpdate(entity, classId, data as string);
 485            }
 486
 313487            if (newComponent != null && newComponent is IOutOfSceneBoundariesHandler)
 14488                Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(entity);
 489
 313490            OnChanged?.Invoke();
 313491            Environment.i.platform.physicsSyncController.MarkDirty();
 313492            Environment.i.platform.cullingController.MarkDirty();
 313493            return newComponent;
 494        }
 495
 277496        public IEntityComponent EntityComponentCreateOrUpdate(string entityId, CLASS_ID_COMPONENT classId, string data) 
 497
 498        // The EntityComponentUpdate() parameters differ from other similar methods because there is no EntityComponentU
 499        public IEntityComponent EntityComponentUpdate(IDCLEntity entity, CLASS_ID_COMPONENT classId,
 500            string componentJson)
 501        {
 89502            if (entity == null)
 503            {
 0504                Debug.LogError($"Can't update the {classId} component of a nonexistent entity!", this);
 0505                return null;
 506            }
 507
 89508            if (!entity.components.ContainsKey(classId))
 509            {
 0510                Debug.LogError($"Entity {entity.entityId} doesn't have a {classId} component to update!", this);
 0511                return null;
 512            }
 513
 89514            IComponent targetComponent = entity.components[classId];
 89515            targetComponent.UpdateFromJSON(componentJson);
 516
 89517            return targetComponent as IEntityComponent;
 518        }
 519
 520        public ISharedComponent SharedComponentCreate(string id, int classId)
 521        {
 541522            if (disposableComponents.TryGetValue(id, out ISharedComponent component))
 4523                return component;
 524
 537525            if (classId == (int) CLASS_ID.UI_SCREEN_SPACE_SHAPE || classId == (int) CLASS_ID.UI_FULLSCREEN_SHAPE)
 526            {
 43527                if (GetSharedComponent<UIScreenSpace>() != null)
 0528                    return null;
 529            }
 530
 537531            var factory = Environment.i.world.componentFactory;
 537532            ISharedComponent newComponent = factory.CreateComponent(classId) as ISharedComponent;
 533
 537534            if (newComponent == null)
 0535                return null;
 536
 537537            disposableComponents.Add(id, newComponent);
 537538            OnAddSharedComponent?.Invoke(id, newComponent);
 539
 537540            newComponent.Initialize(this, id);
 541
 537542            return newComponent;
 543        }
 544
 545        public void SharedComponentDispose(string id)
 546        {
 528547            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 548            {
 528549                sharedComponent?.Dispose();
 528550                disposableComponents.Remove(id);
 528551                OnComponentRemoved?.Invoke(sharedComponent);
 552            }
 0553        }
 554
 555        public void EntityComponentRemove(string entityId, string name)
 556        {
 18557            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 558
 18559            if (decentralandEntity == null)
 560            {
 0561                return;
 562            }
 563
 18564            RemoveEntityComponent(decentralandEntity, name);
 18565        }
 566
 567        public T GetSharedComponent<T>()
 568            where T : class
 569        {
 166570            return disposableComponents.Values.FirstOrDefault(x => x is T) as T;
 571        }
 572
 573        private void RemoveComponentType<T>(IDCLEntity entity, CLASS_ID_COMPONENT classId)
 574            where T : MonoBehaviour
 575        {
 0576            var component = entity.components[classId] as IEntityComponent;
 577
 0578            if (component == null)
 0579                return;
 580
 0581            var monoBehaviour = component.GetTransform().GetComponent<T>();
 582
 0583            if (monoBehaviour != null)
 584            {
 0585                Utils.SafeDestroy(monoBehaviour);
 586            }
 0587        }
 588
 589        private void RemoveEntityComponent(IDCLEntity entity, string componentName)
 590        {
 591            switch (componentName)
 592            {
 593                case "shape":
 0594                    if (entity.meshesInfo.currentShape is BaseShape baseShape)
 595                    {
 0596                        baseShape.DetachFrom(entity);
 597                    }
 598
 0599                    return;
 600
 601                case OnClick.NAME:
 602                    {
 1603                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_CLICK, out IEntityComponent component
 604                        {
 1605                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1606                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_CLICK );
 607                        }
 608
 1609                        return;
 610                    }
 611                case OnPointerDown.NAME:
 612                    {
 1613                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_DOWN, out IEntityComponent component 
 614                        {
 1615                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1616                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_DOWN );
 617                        }
 618                    }
 1619                    return;
 620                case OnPointerUp.NAME:
 621                    {
 1622                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_UP, out IEntityComponent component ))
 623                        {
 1624                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1625                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_UP );
 626                        }
 627                    }
 1628                    return;
 629            }
 0630        }
 631
 632        public ISharedComponent SharedComponentUpdate(string id, BaseModel model)
 633        {
 27634            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 635            {
 27636                sharedComponent.UpdateFromModel(model);
 27637                return sharedComponent;
 638            }
 639
 0640            if (gameObject == null)
 641            {
 0642                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0643            }
 644            else
 645            {
 0646                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 647            }
 648
 0649            return null;
 650        }
 651
 652        public ISharedComponent SharedComponentUpdate(string id, string json)
 653        {
 560654            if (disposableComponents.TryGetValue(id, out ISharedComponent disposableComponent))
 655            {
 560656                disposableComponent.UpdateFromJSON(json);
 560657                return disposableComponent;
 658            }
 659
 0660            if (gameObject == null)
 661            {
 0662                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0663            }
 664            else
 665            {
 0666                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 667            }
 668
 0669            return null;
 670        }
 671
 672        protected virtual void SendMetricsEvent()
 673        {
 7124674            if (Time.frameCount % 10 == 0)
 704675                metricsController.SendEvent();
 7124676        }
 677
 678        public ISharedComponent GetSharedComponent(string componentId)
 679        {
 469680            if (!disposableComponents.TryGetValue(componentId, out ISharedComponent result))
 681            {
 426682                return null;
 683            }
 684
 43685            return result;
 686        }
 687
 688        private IDCLEntity GetEntityForUpdate(string entityId)
 689        {
 703690            if (string.IsNullOrEmpty(entityId))
 691            {
 0692                Debug.LogError("Null or empty entityId");
 0693                return null;
 694            }
 695
 703696            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 697            {
 2698                return null;
 699            }
 700
 701            //NOTE(Brian): This is for removing stray null references? This should never happen.
 702            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 701703            if (entity == null || entity.gameObject == null)
 704            {
 0705                entities.Remove(entityId);
 0706                return null;
 707            }
 708
 701709            return entity;
 710        }
 711
 712        private void DisposeAllSceneComponents()
 713        {
 1252714            List<string> allDisposableComponents = disposableComponents.Select(x => x.Key).ToList();
 2504715            foreach (string id in allDisposableComponents)
 716            {
 534717                Environment.i.platform.parcelScenesCleaner.MarkDisposableComponentForCleanup(this, id);
 718            }
 718719        }
 720
 721        public string GetStateString()
 722        {
 1373723            string baseState = isPersistent ? "global-scene" : "scene";
 1373724            switch (sceneLifecycleHandler.state)
 725            {
 726                case SceneLifecycleHandler.State.NOT_READY:
 0727                    return $"{baseState}:{prettyName} - not ready...";
 728                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 703729                    return $"{baseState}:{prettyName} - waiting for init messages...";
 730                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0731                    if (disposableComponents != null && disposableComponents.Count > 0)
 0732                        return $"{baseState}:{prettyName} - left to ready:{disposableComponents.Count - sceneLifecycleHa
 733                    else
 0734                        return $"{baseState}:{prettyName} - no components. waiting...";
 735                case SceneLifecycleHandler.State.READY:
 670736                    return $"{baseState}:{prettyName} - ready!";
 737            }
 738
 0739            return $"scene:{prettyName} - no state?";
 740        }
 741
 742        public void RefreshLoadingState()
 743        {
 1373744            CalculateSceneLoadingState();
 745
 746#if UNITY_EDITOR
 1373747            gameObject.name = GetStateString();
 748#endif
 1373749        }
 750
 751        [ContextMenu("Get Waiting Components Debug Info")]
 752        public void GetWaitingComponentsDebugInfo()
 753        {
 0754            switch (sceneLifecycleHandler.state)
 755            {
 756                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 757
 0758                    foreach (string componentId in sceneLifecycleHandler.disposableNotReady)
 759                    {
 0760                        if (disposableComponents.ContainsKey(componentId))
 761                        {
 0762                            var component = disposableComponents[componentId];
 763
 0764                            Debug.Log($"Waiting for: {component.ToString()}");
 765
 0766                            foreach (var entity in component.GetAttachedEntities())
 767                            {
 0768                                var loader = LoadableShape.GetLoaderForEntity(entity);
 769
 0770                                string loadInfo = "No loader";
 771
 0772                                if (loader != null)
 773                                {
 0774                                    loadInfo = loader.ToString();
 775                                }
 776
 0777                                Debug.Log($"This shape is attached to {entity.entityId} entity. Click here for highlight
 778                            }
 779                        }
 780                        else
 781                        {
 0782                            Debug.Log($"Waiting for missing component? id: {componentId}");
 783                        }
 784                    }
 785
 786                    break;
 787
 788                default:
 0789                    Debug.Log("This scene is not waiting for any components. Its current state is " + sceneLifecycleHand
 790                    break;
 791            }
 0792        }
 793
 794        /// <summary>
 795        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 796        /// </summary>
 797        public void CalculateSceneLoadingState()
 798        {
 1373799            loadingProgress = 0f;
 800
 1373801            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 802                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 803            {
 670804                loadingProgress = disposableComponents != null && disposableComponents.Count > 0 ? (disposableComponents
 805            }
 806
 1373807            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0808        }
 809    }
 810}

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()