< Summary

Class:DCL.Controllers.ParcelScene
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScene.cs
Covered lines:266
Uncovered lines:84
Coverable lines:350
Total lines:813
Line coverage:76% (266 of 350)
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%220100%
OnDisable()0%220100%
Update()0%330100%
SetData(...)0%440100%
OnWorldReposition(...)0%110100%
SetUpdateData(...)0%110100%
InitializeDebugPlane()0%440100%
RemoveDebugPlane()0%6200%
Cleanup(...)0%5.275077.78%
ToString()0%2100%
IsInsideSceneBoundaries(...)0%330100%
IsInsideSceneBoundaries(...)0%3.333066.67%
IsInsideSceneBoundaries(...)0%8.178086.21%
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%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;
 74717        public Dictionary<string, IDCLEntity> entities { get; private set; } = new Dictionary<string, IDCLEntity>();
 102118        public Dictionary<string, ISharedComponent> disposableComponents { get; private set; } = new Dictionary<string, 
 864919        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 20
 74221        public HashSet<Vector2Int> parcels = new HashSet<Vector2Int>();
 2022        public ISceneMetricsCounter metricsCounter { 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
 10932        public ContentProvider contentProvider { get; set; }
 33
 68634        public bool isTestScene { get; set; } = false;
 233935        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]
 74242        public bool unloadWithDistance = true;
 43
 44        SceneDebugPlane sceneDebugPlane = null;
 45
 46        public SceneLifecycleHandler sceneLifecycleHandler;
 47
 048        public bool isReleased { get; private set; }
 49
 50        public void Awake()
 51        {
 74252            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 74253            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 74254        }
 55
 56        private void OnDestroy()
 57        {
 74258            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 74259            metricsCounter?.Dispose();
 71860        }
 61
 146062        void OnDisable() { metricsCounter?.Disable(); }
 63
 64        private void Update()
 65        {
 1140866            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 67                && CommonScriptableObjects.rendererState.Get())
 1039868                SendMetricsEvent();
 1140869        }
 70
 140471        protected virtual string prettyName => sceneData.basePosition.ToString();
 72
 73        public virtual void SetData(LoadParcelScenesMessage.UnityParcelScene data)
 74        {
 71875            Assert.IsTrue( !string.IsNullOrEmpty(data.id), "Scene must have an ID!" );
 76
 71877            this.sceneData = data;
 78
 71879            contentProvider = new ContentProvider();
 71880            contentProvider.baseUrl = data.baseUrl;
 71881            contentProvider.contents = data.contents;
 71882            contentProvider.BakeHashes();
 83
 71884            parcels.Clear();
 85
 290486            for (int i = 0; i < sceneData.parcels.Length; i++)
 87            {
 73488                parcels.Add(sceneData.parcels[i]);
 89            }
 90
 71891            if (DCLCharacterController.i != null)
 92            {
 71893                gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(data.basePo
 94            }
 95
 71896            metricsCounter = new SceneMetricsCounter(this);
 71897            metricsCounter.Enable();
 98
 71899            OnSetData?.Invoke(data);
 718100        }
 101
 102        void OnWorldReposition(Vector3 current, Vector3 previous)
 103        {
 3104            Vector3 sceneWorldPos = Utils.GridToWorldPosition(sceneData.basePosition.x, sceneData.basePosition.y);
 3105            gameObject.transform.position = PositionUtils.WorldToUnityPosition(sceneWorldPos);
 3106        }
 107
 108        public virtual void SetUpdateData(LoadParcelScenesMessage.UnityParcelScene data)
 109        {
 15110            contentProvider = new ContentProvider();
 15111            contentProvider.baseUrl = data.baseUrl;
 15112            contentProvider.contents = data.contents;
 15113            contentProvider.BakeHashes();
 15114        }
 115
 116        public void InitializeDebugPlane()
 117        {
 714118            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 119            {
 712120                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 121            }
 714122        }
 123
 124        public void RemoveDebugPlane()
 125        {
 0126            if (sceneDebugPlane != null)
 127            {
 0128                sceneDebugPlane.Dispose();
 0129                sceneDebugPlane = null;
 130            }
 0131        }
 132
 133        public void Cleanup(bool immediate)
 134        {
 734135            if (isReleased)
 0136                return;
 137
 734138            if (sceneDebugPlane != null)
 139            {
 712140                sceneDebugPlane.Dispose();
 712141                sceneDebugPlane = null;
 142            }
 143
 734144            DisposeAllSceneComponents();
 145
 734146            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 147            {
 0148                RemoveAllEntitiesImmediate();
 0149                PoolManager.i.Cleanup(true, true);
 0150            }
 151            else
 152            {
 734153                if (entities.Count > 0)
 154                {
 252155                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 252156                    this.gameObject.SetActive(false);
 157
 252158                    RemoveAllEntities();
 252159                }
 160                else
 161                {
 482162                    Destroy(this.gameObject);
 163                }
 164            }
 165
 734166            isReleased = true;
 734167        }
 168
 0169        public override string ToString() { return "Parcel Scene: " + base.ToString() + "\n" + sceneData.ToString(); }
 170
 171        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 172        {
 177173            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 132174                return false;
 45175            if (!IsInsideSceneBoundaries(objectBounds.max + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 14176                return false;
 177
 31178            return true;
 179        }
 180
 181        public virtual bool IsInsideSceneBoundaries(Vector2Int gridPosition, float height = 0f)
 182        {
 958183            if (parcels.Count == 0)
 0184                return false;
 185
 958186            float heightLimit = metricsCounter.GetLimits().sceneHeight;
 187
 958188            if (height > heightLimit)
 0189                return false;
 190
 958191            return parcels.Contains(gridPosition);
 192        }
 193
 194        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 195        {
 267196            if (parcels.Count == 0)
 0197                return false;
 198
 267199            float heightLimit = metricsCounter.GetLimits().sceneHeight;
 267200            if (height > heightLimit)
 22201                return false;
 202
 245203            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 245204            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 205
 206            // We check the target world position
 245207            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 245208            if (parcels.Contains(targetCoordinate))
 102209                return true;
 210
 211            // We need to check using a threshold from the target point, in order to cover correctly the parcel "border/
 143212            Vector2Int coordinateMin = new Vector2Int();
 143213            coordinateMin.x = Mathf.FloorToInt((worldPosition.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 143214            coordinateMin.y = Mathf.FloorToInt((worldPosition.z - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 215
 143216            Vector2Int coordinateMax = new Vector2Int();
 143217            coordinateMax.x = Mathf.FloorToInt((worldPosition.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 143218            coordinateMax.y = Mathf.FloorToInt((worldPosition.z + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 219
 220            // We check the east/north-threshold position
 143221            targetCoordinate.Set(coordinateMax.x, coordinateMax.y);
 143222            if (parcels.Contains(targetCoordinate))
 0223                return true;
 224
 225            // We check the east/south-threshold position
 143226            targetCoordinate.Set(coordinateMax.x, coordinateMin.y);
 143227            if (parcels.Contains(targetCoordinate))
 0228                return true;
 229
 230            // We check the west/north-threshold position
 143231            targetCoordinate.Set(coordinateMin.x, coordinateMax.y);
 143232            if (parcels.Contains(targetCoordinate))
 0233                return true;
 234
 235            // We check the west/south-threshold position
 143236            targetCoordinate.Set(coordinateMin.x, coordinateMin.y);
 143237            if (parcels.Contains(targetCoordinate))
 5238                return true;
 239
 138240            return false;
 241        }
 242
 53243        public Transform GetSceneTransform() { return transform; }
 244
 245        public IDCLEntity CreateEntity(string id)
 246        {
 541247            if (entities.ContainsKey(id))
 248            {
 1249                return entities[id];
 250            }
 251
 540252            var newEntity = new DecentralandEntity();
 540253            newEntity.entityId = id;
 254
 540255            Environment.i.world.sceneController.EnsureEntityPool();
 256
 257            // As we know that the pool already exists, we just get one gameobject from it
 540258            PoolableObject po = PoolManager.i.Get(SceneController.EMPTY_GO_POOL_NAME);
 259
 540260            newEntity.meshesInfo.innerGameObject = po.gameObject;
 540261            newEntity.gameObject = po.gameObject;
 262
 263#if UNITY_EDITOR
 540264            newEntity.gameObject.name = "ENTITY_" + id;
 265#endif
 540266            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 540267            newEntity.gameObject.SetActive(true);
 540268            newEntity.scene = this;
 269
 540270            newEntity.OnCleanupEvent += po.OnCleanup;
 271
 540272            if (Environment.i.world.sceneBoundsChecker.enabled)
 453273                newEntity.OnShapeUpdated += Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 274
 540275            entities.Add(id, newEntity);
 276
 540277            OnEntityAdded?.Invoke(newEntity);
 278
 540279            return newEntity;
 280        }
 281
 282        public void RemoveEntity(string id, bool removeImmediatelyFromEntitiesList = true)
 283        {
 514284            if (entities.ContainsKey(id))
 285            {
 514286                IDCLEntity entity = entities[id];
 287
 514288                if (!entity.markedForCleanup)
 289                {
 290                    // This will also cleanup its children
 514291                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 292                }
 293
 514294                entities.Remove(id);
 514295            }
 296#if UNITY_EDITOR || DEVELOPMENT_BUILD
 297            else
 298            {
 0299                Debug.LogWarning($"Couldn't remove entity with ID: {id} as it doesn't exist.");
 300            }
 301#endif
 0302        }
 303
 304        void CleanUpEntityRecursively(IDCLEntity entity, bool removeImmediatelyFromEntitiesList)
 305        {
 306            // Iterate through all entity children
 524307            using (var iterator = entity.children.GetEnumerator())
 308            {
 534309                while (iterator.MoveNext())
 310                {
 10311                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 312                }
 524313            }
 314
 524315            OnEntityRemoved?.Invoke(entity);
 316
 524317            if (Environment.i.world.sceneBoundsChecker.enabled)
 318            {
 38319                entity.OnShapeUpdated -= Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 38320                Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(entity);
 321            }
 322
 524323            if (removeImmediatelyFromEntitiesList)
 324            {
 325                // Every entity ends up being removed through here
 38326                entity.Cleanup();
 38327                entities.Remove(entity.entityId);
 38328            }
 329            else
 330            {
 486331                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 332            }
 486333        }
 334
 335        void RemoveAllEntities(bool instant = false)
 336        {
 337            //NOTE(Brian): We need to remove only the rootEntities.
 338            //             If we don't, duplicated entities will get removed when destroying
 339            //             recursively, making this more complicated than it should.
 252340            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 341
 252342            using (var iterator = entities.GetEnumerator())
 343            {
 754344                while (iterator.MoveNext())
 345                {
 502346                    if (iterator.Current.Value.parent == null)
 347                    {
 493348                        if (instant)
 0349                            rootEntities.Add(iterator.Current.Value);
 350                        else
 493351                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 352                    }
 353                }
 252354            }
 355
 252356            if (instant)
 357            {
 0358                int rootEntitiesCount = rootEntities.Count;
 0359                for (int i = 0; i < rootEntitiesCount; i++)
 360                {
 0361                    IDCLEntity entity = rootEntities[i];
 0362                    RemoveEntity(entity.entityId, instant);
 363                }
 364
 0365                entities.Clear();
 366
 0367                Destroy(this.gameObject);
 368            }
 252369        }
 370
 0371        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 372
 373        public void SetEntityParent(string entityId, string parentId)
 374        {
 15375            if (entityId == parentId)
 376            {
 0377                return;
 378            }
 379
 15380            IDCLEntity me = GetEntityForUpdate(entityId);
 381
 15382            if (me == null)
 0383                return;
 384
 15385            if (parentId == "FirstPersonCameraEntityReference" || parentId == "PlayerEntityReference") // PlayerEntityRe
 386            {
 387                // In this case, the entity will attached to the first person camera
 388                // On first person mode, the entity will rotate with the camera. On third person mode, the entity will r
 1389                me.SetParent(DCLCharacterController.i.firstPersonCameraReference);
 1390                Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1391            }
 14392            else if (parentId == "AvatarEntityReference" || parentId == "AvatarPositionEntityReference") // AvatarPositi
 393            {
 394                // In this case, the entity will be attached to the avatar
 395                // It will simply rotate with the avatar, regardless of where the camera is pointing
 1396                me.SetParent(DCLCharacterController.i.avatarReference);
 1397                Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1398            }
 399            else
 400            {
 13401                if (me.parent == DCLCharacterController.i.firstPersonCameraReference || me.parent == DCLCharacterControl
 402                {
 1403                    Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(me);
 404                }
 405
 13406                if (parentId == "0")
 407                {
 408                    // The entity will be child of the scene directly
 2409                    me.SetParent(null);
 2410                    me.gameObject.transform.SetParent(gameObject.transform, false);
 2411                }
 412                else
 413                {
 11414                    IDCLEntity myParent = GetEntityForUpdate(parentId);
 415
 11416                    if (myParent != null)
 417                    {
 11418                        me.SetParent(myParent);
 419                    }
 420                }
 421            }
 422
 15423            Environment.i.platform.cullingController.MarkDirty();
 15424            Environment.i.platform.physicsSyncController.MarkDirty();
 15425        }
 426
 427        /**
 428          * This method is called when we need to attach a disposable component to the entity
 429          */
 430        public void SharedComponentAttach(string entityId, string id)
 431        {
 353432            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 433
 353434            if (decentralandEntity == null)
 435            {
 2436                return;
 437            }
 438
 351439            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 440            {
 349441                sharedComponent.AttachTo(decentralandEntity);
 442            }
 351443        }
 444
 445        public IEntityComponent EntityComponentCreateOrUpdateWithModel(string entityId, CLASS_ID_COMPONENT classId, obje
 446        {
 326447            IDCLEntity entity = GetEntityForUpdate(entityId);
 448
 326449            if (entity == null)
 450            {
 0451                Debug.LogError($"scene '{sceneData.id}': Can't create entity component if the entity {entityId} doesn't 
 0452                return null;
 453            }
 454
 326455            IEntityComponent newComponent = null;
 456
 326457            if (classId == CLASS_ID_COMPONENT.UUID_CALLBACK)
 458            {
 50459                OnPointerEvent.Model model = JsonUtility.FromJson<OnPointerEvent.Model>(data as string);
 50460                classId = model.GetClassIdFromType();
 461            }
 462
 326463            if (!entity.components.ContainsKey(classId))
 464            {
 251465                var factory = Environment.i.world.componentFactory;
 251466                newComponent = factory.CreateComponent((int) classId) as IEntityComponent;
 467
 251468                if (newComponent != null)
 469                {
 251470                    entity.components.Add(classId, newComponent);
 251471                    OnComponentAdded?.Invoke(newComponent);
 472
 251473                    newComponent.Initialize(this, entity);
 474
 251475                    if (data is string json)
 476                    {
 216477                        newComponent.UpdateFromJSON(json);
 216478                    }
 479                    else
 480                    {
 35481                        newComponent.UpdateFromModel(data as BaseModel);
 482                    }
 483                }
 35484            }
 485            else
 486            {
 75487                newComponent = EntityComponentUpdate(entity, classId, data as string);
 488            }
 489
 326490            if (newComponent != null && newComponent is IOutOfSceneBoundariesHandler)
 15491                Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(entity);
 492
 326493            OnChanged?.Invoke();
 326494            Environment.i.platform.physicsSyncController.MarkDirty();
 326495            Environment.i.platform.cullingController.MarkDirty();
 326496            return newComponent;
 497        }
 498
 291499        public IEntityComponent EntityComponentCreateOrUpdate(string entityId, CLASS_ID_COMPONENT classId, string data) 
 500
 501        // The EntityComponentUpdate() parameters differ from other similar methods because there is no EntityComponentU
 502        public IEntityComponent EntityComponentUpdate(IDCLEntity entity, CLASS_ID_COMPONENT classId,
 503            string componentJson)
 504        {
 92505            if (entity == null)
 506            {
 0507                Debug.LogError($"Can't update the {classId} component of a nonexistent entity!", this);
 0508                return null;
 509            }
 510
 92511            if (!entity.components.ContainsKey(classId))
 512            {
 0513                Debug.LogError($"Entity {entity.entityId} doesn't have a {classId} component to update!", this);
 0514                return null;
 515            }
 516
 92517            IComponent targetComponent = entity.components[classId];
 92518            targetComponent.UpdateFromJSON(componentJson);
 519
 92520            return targetComponent as IEntityComponent;
 521        }
 522
 523        public ISharedComponent SharedComponentCreate(string id, int classId)
 524        {
 551525            if (disposableComponents.TryGetValue(id, out ISharedComponent component))
 4526                return component;
 527
 547528            if (classId == (int) CLASS_ID.UI_SCREEN_SPACE_SHAPE || classId == (int) CLASS_ID.UI_FULLSCREEN_SHAPE)
 529            {
 44530                if (GetSharedComponent<UIScreenSpace>() != null)
 0531                    return null;
 532            }
 533
 547534            var factory = Environment.i.world.componentFactory;
 547535            ISharedComponent newComponent = factory.CreateComponent(classId) as ISharedComponent;
 536
 547537            if (newComponent == null)
 0538                return null;
 539
 547540            disposableComponents.Add(id, newComponent);
 547541            OnAddSharedComponent?.Invoke(id, newComponent);
 542
 547543            newComponent.Initialize(this, id);
 544
 547545            return newComponent;
 546        }
 547
 548        public void SharedComponentDispose(string id)
 549        {
 522550            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 551            {
 522552                sharedComponent?.Dispose();
 522553                disposableComponents.Remove(id);
 522554                OnComponentRemoved?.Invoke(sharedComponent);
 555            }
 0556        }
 557
 558        public void EntityComponentRemove(string entityId, string name)
 559        {
 18560            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 561
 18562            if (decentralandEntity == null)
 563            {
 0564                return;
 565            }
 566
 18567            RemoveEntityComponent(decentralandEntity, name);
 18568        }
 569
 570        public T GetSharedComponent<T>()
 571            where T : class
 572        {
 181573            return disposableComponents.Values.FirstOrDefault(x => x is T) as T;
 574        }
 575
 576        private void RemoveComponentType<T>(IDCLEntity entity, CLASS_ID_COMPONENT classId)
 577            where T : MonoBehaviour
 578        {
 0579            var component = entity.components[classId] as IEntityComponent;
 580
 0581            if (component == null)
 0582                return;
 583
 0584            var monoBehaviour = component.GetTransform().GetComponent<T>();
 585
 0586            if (monoBehaviour != null)
 587            {
 0588                Utils.SafeDestroy(monoBehaviour);
 589            }
 0590        }
 591
 592        private void RemoveEntityComponent(IDCLEntity entity, string componentName)
 593        {
 594            switch (componentName)
 595            {
 596                case "shape":
 0597                    if (entity.meshesInfo.currentShape is BaseShape baseShape)
 598                    {
 0599                        baseShape.DetachFrom(entity);
 600                    }
 601
 0602                    return;
 603
 604                case OnClick.NAME:
 605                    {
 1606                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_CLICK, out IEntityComponent component
 607                        {
 1608                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1609                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_CLICK );
 610                        }
 611
 1612                        return;
 613                    }
 614                case OnPointerDown.NAME:
 615                    {
 1616                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_DOWN, out IEntityComponent component 
 617                        {
 1618                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1619                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_DOWN );
 620                        }
 621                    }
 1622                    return;
 623                case OnPointerUp.NAME:
 624                    {
 1625                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_UP, out IEntityComponent component ))
 626                        {
 1627                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1628                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_UP );
 629                        }
 630                    }
 1631                    return;
 632            }
 0633        }
 634
 635        public ISharedComponent SharedComponentUpdate(string id, BaseModel model)
 636        {
 27637            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 638            {
 27639                sharedComponent.UpdateFromModel(model);
 27640                return sharedComponent;
 641            }
 642
 0643            if (gameObject == null)
 644            {
 0645                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0646            }
 647            else
 648            {
 0649                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 650            }
 651
 0652            return null;
 653        }
 654
 655        public ISharedComponent SharedComponentUpdate(string id, string json)
 656        {
 573657            if (disposableComponents.TryGetValue(id, out ISharedComponent disposableComponent))
 658            {
 573659                disposableComponent.UpdateFromJSON(json);
 573660                return disposableComponent;
 661            }
 662
 0663            if (gameObject == null)
 664            {
 0665                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0666            }
 667            else
 668            {
 0669                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 670            }
 671
 0672            return null;
 673        }
 674
 675        protected virtual void SendMetricsEvent()
 676        {
 10398677            if (Time.frameCount % 10 == 0)
 1033678                metricsCounter.SendEvent();
 10398679        }
 680
 681        public ISharedComponent GetSharedComponent(string componentId)
 682        {
 484683            if (!disposableComponents.TryGetValue(componentId, out ISharedComponent result))
 684            {
 439685                return null;
 686            }
 687
 45688            return result;
 689        }
 690
 691        private IDCLEntity GetEntityForUpdate(string entityId)
 692        {
 723693            if (string.IsNullOrEmpty(entityId))
 694            {
 0695                Debug.LogError("Null or empty entityId");
 0696                return null;
 697            }
 698
 723699            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 700            {
 2701                return null;
 702            }
 703
 704            //NOTE(Brian): This is for removing stray null references? This should never happen.
 705            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 721706            if (entity == null || entity.gameObject == null)
 707            {
 0708                entities.Remove(entityId);
 0709                return null;
 710            }
 711
 721712            return entity;
 713        }
 714
 715        private void DisposeAllSceneComponents()
 716        {
 1278717            List<string> allDisposableComponents = disposableComponents.Select(x => x.Key).ToList();
 2556718            foreach (string id in allDisposableComponents)
 719            {
 544720                Environment.i.platform.parcelScenesCleaner.MarkDisposableComponentForCleanup(this, id);
 721            }
 734722        }
 723
 724        public string GetStateString()
 725        {
 1404726            string baseState = isPersistent ? "global-scene" : "scene";
 1404727            switch (sceneLifecycleHandler.state)
 728            {
 729                case SceneLifecycleHandler.State.NOT_READY:
 0730                    return $"{baseState}:{prettyName} - not ready...";
 731                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 718732                    return $"{baseState}:{prettyName} - waiting for init messages...";
 733                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0734                    if (disposableComponents != null && disposableComponents.Count > 0)
 0735                        return $"{baseState}:{prettyName} - left to ready:{disposableComponents.Count - sceneLifecycleHa
 736                    else
 0737                        return $"{baseState}:{prettyName} - no components. waiting...";
 738                case SceneLifecycleHandler.State.READY:
 686739                    return $"{baseState}:{prettyName} - ready!";
 740            }
 741
 0742            return $"scene:{prettyName} - no state?";
 743        }
 744
 745        public void RefreshLoadingState()
 746        {
 1404747            CalculateSceneLoadingState();
 748
 749#if UNITY_EDITOR
 1404750            gameObject.name = GetStateString();
 751#endif
 1404752        }
 753
 754        [ContextMenu("Get Waiting Components Debug Info")]
 755        public void GetWaitingComponentsDebugInfo()
 756        {
 0757            switch (sceneLifecycleHandler.state)
 758            {
 759                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 760
 0761                    foreach (string componentId in sceneLifecycleHandler.disposableNotReady)
 762                    {
 0763                        if (disposableComponents.ContainsKey(componentId))
 764                        {
 0765                            var component = disposableComponents[componentId];
 766
 0767                            Debug.Log($"Waiting for: {component.ToString()}");
 768
 0769                            foreach (var entity in component.GetAttachedEntities())
 770                            {
 0771                                var loader = LoadableShape.GetLoaderForEntity(entity);
 772
 0773                                string loadInfo = "No loader";
 774
 0775                                if (loader != null)
 776                                {
 0777                                    loadInfo = loader.ToString();
 778                                }
 779
 0780                                Debug.Log($"This shape is attached to {entity.entityId} entity. Click here for highlight
 781                            }
 782                        }
 783                        else
 784                        {
 0785                            Debug.Log($"Waiting for missing component? id: {componentId}");
 786                        }
 787                    }
 788
 789                    break;
 790
 791                default:
 0792                    Debug.Log("This scene is not waiting for any components. Its current state is " + sceneLifecycleHand
 793                    break;
 794            }
 0795        }
 796
 797        /// <summary>
 798        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 799        /// </summary>
 800        public void CalculateSceneLoadingState()
 801        {
 1404802            loadingProgress = 0f;
 803
 1404804            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 805                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 806            {
 686807                loadingProgress = disposableComponents != null && disposableComponents.Count > 0 ? (disposableComponents
 808            }
 809
 1404810            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0811        }
 812    }
 813}

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)
metricsCounter()
metricsCounter(DCL.ISceneMetricsCounter)
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()
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()