< 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:86
Coverable lines:352
Total lines:819
Line coverage:75.5% (266 of 352)
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%
SetEditMode(...)0%2100%
IsEditModeActive()0%2100%
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;
 73417        public Dictionary<string, IDCLEntity> entities { get; private set; } = new Dictionary<string, IDCLEntity>();
 101318        public Dictionary<string, ISharedComponent> disposableComponents { get; private set; } = new Dictionary<string, 
 807419        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 20
 73421        public HashSet<Vector2Int> parcels = new HashSet<Vector2Int>();
 4822        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
 10832        public ContentProvider contentProvider { get; set; }
 33
 67834        public bool isTestScene { get; set; } = false;
 230935        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]
 73442        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        {
 73454            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 73455            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 73456        }
 57
 58        private void OnDestroy()
 59        {
 73460            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 73461            metricsCounter?.Dispose();
 71062        }
 63
 144464        void OnDisable() { metricsCounter?.Disable(); }
 65
 66        private void Update()
 67        {
 1137968            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 69                && CommonScriptableObjects.rendererState.Get())
 1037070                SendMetricsEvent();
 1137971        }
 72
 138873        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        {
 71081            Assert.IsTrue( !string.IsNullOrEmpty(data.id), "Scene must have an ID!" );
 82
 71083            this.sceneData = data;
 84
 71085            contentProvider = new ContentProvider();
 71086            contentProvider.baseUrl = data.baseUrl;
 71087            contentProvider.contents = data.contents;
 71088            contentProvider.BakeHashes();
 89
 71090            parcels.Clear();
 91
 287292            for (int i = 0; i < sceneData.parcels.Length; i++)
 93            {
 72694                parcels.Add(sceneData.parcels[i]);
 95            }
 96
 71097            if (DCLCharacterController.i != null)
 98            {
 71099                gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(data.basePo
 100            }
 101
 710102            metricsCounter = new SceneMetricsCounter(this);
 710103            metricsCounter.Enable();
 104
 710105            OnSetData?.Invoke(data);
 710106        }
 107
 108        void OnWorldReposition(Vector3 current, Vector3 previous)
 109        {
 5110            Vector3 sceneWorldPos = Utils.GridToWorldPosition(sceneData.basePosition.x, sceneData.basePosition.y);
 5111            gameObject.transform.position = PositionUtils.WorldToUnityPosition(sceneWorldPos);
 5112        }
 113
 114        public virtual void SetUpdateData(LoadParcelScenesMessage.UnityParcelScene data)
 115        {
 15116            contentProvider = new ContentProvider();
 15117            contentProvider.baseUrl = data.baseUrl;
 15118            contentProvider.contents = data.contents;
 15119            contentProvider.BakeHashes();
 15120        }
 121
 122        public void InitializeDebugPlane()
 123        {
 706124            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 125            {
 704126                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 127            }
 706128        }
 129
 130        public void RemoveDebugPlane()
 131        {
 0132            if (sceneDebugPlane != null)
 133            {
 0134                sceneDebugPlane.Dispose();
 0135                sceneDebugPlane = null;
 136            }
 0137        }
 138
 139        public void Cleanup(bool immediate)
 140        {
 726141            if (isReleased)
 0142                return;
 143
 726144            if (sceneDebugPlane != null)
 145            {
 704146                sceneDebugPlane.Dispose();
 704147                sceneDebugPlane = null;
 148            }
 149
 726150            DisposeAllSceneComponents();
 151
 726152            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 153            {
 0154                RemoveAllEntitiesImmediate();
 0155                PoolManager.i.Cleanup(true, true);
 0156            }
 157            else
 158            {
 726159                if (entities.Count > 0)
 160                {
 254161                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 254162                    this.gameObject.SetActive(false);
 163
 254164                    RemoveAllEntities();
 254165                }
 166                else
 167                {
 472168                    Destroy(this.gameObject);
 169                }
 170            }
 171
 726172            isReleased = true;
 726173        }
 174
 0175        public override string ToString() { return "Parcel Scene: " + base.ToString() + "\n" + sceneData.ToString(); }
 176
 177        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 178        {
 172179            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 128180                return false;
 44181            if (!IsInsideSceneBoundaries(objectBounds.max + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 14182                return false;
 183
 30184            return true;
 185        }
 186
 187        public virtual bool IsInsideSceneBoundaries(Vector2Int gridPosition, float height = 0f)
 188        {
 937189            if (parcels.Count == 0)
 0190                return false;
 191
 937192            float heightLimit = metricsCounter.GetLimits().sceneHeight;
 193
 937194            if (height > heightLimit)
 0195                return false;
 196
 937197            return parcels.Contains(gridPosition);
 198        }
 199
 200        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 201        {
 271202            if (parcels.Count == 0)
 0203                return false;
 204
 271205            float heightLimit = metricsCounter.GetLimits().sceneHeight;
 271206            if (height > heightLimit)
 22207                return false;
 208
 249209            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 249210            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 211
 212            // We check the target world position
 249213            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 249214            if (parcels.Contains(targetCoordinate))
 109215                return true;
 216
 217            // We need to check using a threshold from the target point, in order to cover correctly the parcel "border/
 140218            Vector2Int coordinateMin = new Vector2Int();
 140219            coordinateMin.x = Mathf.FloorToInt((worldPosition.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 140220            coordinateMin.y = Mathf.FloorToInt((worldPosition.z - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 221
 140222            Vector2Int coordinateMax = new Vector2Int();
 140223            coordinateMax.x = Mathf.FloorToInt((worldPosition.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 140224            coordinateMax.y = Mathf.FloorToInt((worldPosition.z + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 225
 226            // We check the east/north-threshold position
 140227            targetCoordinate.Set(coordinateMax.x, coordinateMax.y);
 140228            if (parcels.Contains(targetCoordinate))
 0229                return true;
 230
 231            // We check the east/south-threshold position
 140232            targetCoordinate.Set(coordinateMax.x, coordinateMin.y);
 140233            if (parcels.Contains(targetCoordinate))
 0234                return true;
 235
 236            // We check the west/north-threshold position
 140237            targetCoordinate.Set(coordinateMin.x, coordinateMax.y);
 140238            if (parcels.Contains(targetCoordinate))
 0239                return true;
 240
 241            // We check the west/south-threshold position
 140242            targetCoordinate.Set(coordinateMin.x, coordinateMin.y);
 140243            if (parcels.Contains(targetCoordinate))
 5244                return true;
 245
 135246            return false;
 247        }
 248
 157249        public Transform GetSceneTransform() { return transform; }
 250
 251        public IDCLEntity CreateEntity(string id)
 252        {
 547253            if (entities.ContainsKey(id))
 254            {
 1255                return entities[id];
 256            }
 257
 546258            var newEntity = new DecentralandEntity();
 546259            newEntity.entityId = id;
 260
 546261            Environment.i.world.sceneController.EnsureEntityPool();
 262
 263            // As we know that the pool already exists, we just get one gameobject from it
 546264            PoolableObject po = PoolManager.i.Get(SceneController.EMPTY_GO_POOL_NAME);
 265
 546266            newEntity.meshesInfo.innerGameObject = po.gameObject;
 546267            newEntity.gameObject = po.gameObject;
 268
 269#if UNITY_EDITOR
 546270            newEntity.gameObject.name = "ENTITY_" + id;
 271#endif
 546272            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 546273            newEntity.gameObject.SetActive(true);
 546274            newEntity.scene = this;
 275
 546276            newEntity.OnCleanupEvent += po.OnCleanup;
 277
 546278            if (Environment.i.world.sceneBoundsChecker.enabled)
 460279                newEntity.OnShapeUpdated += Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 280
 546281            entities.Add(id, newEntity);
 282
 546283            OnEntityAdded?.Invoke(newEntity);
 284
 546285            return newEntity;
 286        }
 287
 288        public void RemoveEntity(string id, bool removeImmediatelyFromEntitiesList = true)
 289        {
 522290            if (entities.ContainsKey(id))
 291            {
 522292                IDCLEntity entity = entities[id];
 293
 522294                if (!entity.markedForCleanup)
 295                {
 296                    // This will also cleanup its children
 522297                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 298                }
 299
 522300                entities.Remove(id);
 522301            }
 302#if UNITY_EDITOR || DEVELOPMENT_BUILD
 303            else
 304            {
 0305                Debug.LogWarning($"Couldn't remove entity with ID: {id} as it doesn't exist.");
 306            }
 307#endif
 0308        }
 309
 310        void CleanUpEntityRecursively(IDCLEntity entity, bool removeImmediatelyFromEntitiesList)
 311        {
 312            // Iterate through all entity children
 531313            using (var iterator = entity.children.GetEnumerator())
 314            {
 540315                while (iterator.MoveNext())
 316                {
 9317                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 318                }
 531319            }
 320
 531321            OnEntityRemoved?.Invoke(entity);
 322
 531323            if (Environment.i.world.sceneBoundsChecker.enabled)
 324            {
 38325                entity.OnShapeUpdated -= Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 38326                Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(entity);
 327            }
 328
 531329            if (removeImmediatelyFromEntitiesList)
 330            {
 331                // Every entity ends up being removed through here
 38332                entity.Cleanup();
 38333                entities.Remove(entity.entityId);
 38334            }
 335            else
 336            {
 493337                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 338            }
 493339        }
 340
 341        void RemoveAllEntities(bool instant = false)
 342        {
 343            //NOTE(Brian): We need to remove only the rootEntities.
 344            //             If we don't, duplicated entities will get removed when destroying
 345            //             recursively, making this more complicated than it should.
 254346            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 347
 254348            using (var iterator = entities.GetEnumerator())
 349            {
 762350                while (iterator.MoveNext())
 351                {
 508352                    if (iterator.Current.Value.parent == null)
 353                    {
 500354                        if (instant)
 0355                            rootEntities.Add(iterator.Current.Value);
 356                        else
 500357                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 358                    }
 359                }
 254360            }
 361
 254362            if (instant)
 363            {
 0364                int rootEntitiesCount = rootEntities.Count;
 0365                for (int i = 0; i < rootEntitiesCount; i++)
 366                {
 0367                    IDCLEntity entity = rootEntities[i];
 0368                    RemoveEntity(entity.entityId, instant);
 369                }
 370
 0371                entities.Clear();
 372
 0373                Destroy(this.gameObject);
 374            }
 254375        }
 376
 0377        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 378
 379        public void SetEntityParent(string entityId, string parentId)
 380        {
 14381            if (entityId == parentId)
 382            {
 0383                return;
 384            }
 385
 14386            IDCLEntity me = GetEntityForUpdate(entityId);
 387
 14388            if (me == null)
 0389                return;
 390
 14391            if (parentId == "FirstPersonCameraEntityReference" || parentId == "PlayerEntityReference") // PlayerEntityRe
 392            {
 393                // In this case, the entity will attached to the first person camera
 394                // On first person mode, the entity will rotate with the camera. On third person mode, the entity will r
 1395                me.SetParent(DCLCharacterController.i.firstPersonCameraReference);
 1396                Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1397            }
 13398            else if (parentId == "AvatarEntityReference" || parentId == "AvatarPositionEntityReference") // AvatarPositi
 399            {
 400                // In this case, the entity will be attached to the avatar
 401                // It will simply rotate with the avatar, regardless of where the camera is pointing
 1402                me.SetParent(DCLCharacterController.i.avatarReference);
 1403                Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1404            }
 405            else
 406            {
 12407                if (me.parent == DCLCharacterController.i.firstPersonCameraReference || me.parent == DCLCharacterControl
 408                {
 1409                    Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(me);
 410                }
 411
 12412                if (parentId == "0")
 413                {
 414                    // The entity will be child of the scene directly
 2415                    me.SetParent(null);
 2416                    me.gameObject.transform.SetParent(gameObject.transform, false);
 2417                }
 418                else
 419                {
 10420                    IDCLEntity myParent = GetEntityForUpdate(parentId);
 421
 10422                    if (myParent != null)
 423                    {
 10424                        me.SetParent(myParent);
 425                    }
 426                }
 427            }
 428
 14429            Environment.i.platform.cullingController.MarkDirty();
 14430            Environment.i.platform.physicsSyncController.MarkDirty();
 14431        }
 432
 433        /**
 434          * This method is called when we need to attach a disposable component to the entity
 435          */
 436        public void SharedComponentAttach(string entityId, string id)
 437        {
 350438            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 439
 350440            if (decentralandEntity == null)
 441            {
 2442                return;
 443            }
 444
 348445            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 446            {
 346447                sharedComponent.AttachTo(decentralandEntity);
 448            }
 348449        }
 450
 451        public IEntityComponent EntityComponentCreateOrUpdateWithModel(string entityId, CLASS_ID_COMPONENT classId, obje
 452        {
 319453            IDCLEntity entity = GetEntityForUpdate(entityId);
 454
 319455            if (entity == null)
 456            {
 0457                Debug.LogError($"scene '{sceneData.id}': Can't create entity component if the entity {entityId} doesn't 
 0458                return null;
 459            }
 460
 319461            IEntityComponent newComponent = null;
 462
 319463            if (classId == CLASS_ID_COMPONENT.UUID_CALLBACK)
 464            {
 48465                OnPointerEvent.Model model = JsonUtility.FromJson<OnPointerEvent.Model>(data as string);
 48466                classId = model.GetClassIdFromType();
 467            }
 468
 319469            if (!entity.components.ContainsKey(classId))
 470            {
 246471                var factory = Environment.i.world.componentFactory;
 246472                newComponent = factory.CreateComponent((int) classId) as IEntityComponent;
 473
 246474                if (newComponent != null)
 475                {
 246476                    entity.components.Add(classId, newComponent);
 246477                    OnComponentAdded?.Invoke(newComponent);
 478
 246479                    newComponent.Initialize(this, entity);
 480
 246481                    if (data is string json)
 482                    {
 211483                        newComponent.UpdateFromJSON(json);
 211484                    }
 485                    else
 486                    {
 35487                        newComponent.UpdateFromModel(data as BaseModel);
 488                    }
 489                }
 35490            }
 491            else
 492            {
 73493                newComponent = EntityComponentUpdate(entity, classId, data as string);
 494            }
 495
 319496            if (newComponent != null && newComponent is IOutOfSceneBoundariesHandler)
 14497                Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(entity);
 498
 319499            OnChanged?.Invoke();
 319500            Environment.i.platform.physicsSyncController.MarkDirty();
 319501            Environment.i.platform.cullingController.MarkDirty();
 319502            return newComponent;
 503        }
 504
 284505        public IEntityComponent EntityComponentCreateOrUpdate(string entityId, CLASS_ID_COMPONENT classId, string data) 
 506
 507        // The EntityComponentUpdate() parameters differ from other similar methods because there is no EntityComponentU
 508        public IEntityComponent EntityComponentUpdate(IDCLEntity entity, CLASS_ID_COMPONENT classId,
 509            string componentJson)
 510        {
 90511            if (entity == null)
 512            {
 0513                Debug.LogError($"Can't update the {classId} component of a nonexistent entity!", this);
 0514                return null;
 515            }
 516
 90517            if (!entity.components.ContainsKey(classId))
 518            {
 0519                Debug.LogError($"Entity {entity.entityId} doesn't have a {classId} component to update!", this);
 0520                return null;
 521            }
 522
 90523            IComponent targetComponent = entity.components[classId];
 90524            targetComponent.UpdateFromJSON(componentJson);
 525
 90526            return targetComponent as IEntityComponent;
 527        }
 528
 529        public ISharedComponent SharedComponentCreate(string id, int classId)
 530        {
 547531            if (disposableComponents.TryGetValue(id, out ISharedComponent component))
 4532                return component;
 533
 543534            if (classId == (int) CLASS_ID.UI_SCREEN_SPACE_SHAPE || classId == (int) CLASS_ID.UI_FULLSCREEN_SHAPE)
 535            {
 44536                if (GetSharedComponent<UIScreenSpace>() != null)
 0537                    return null;
 538            }
 539
 543540            var factory = Environment.i.world.componentFactory;
 543541            ISharedComponent newComponent = factory.CreateComponent(classId) as ISharedComponent;
 542
 543543            if (newComponent == null)
 0544                return null;
 545
 543546            disposableComponents.Add(id, newComponent);
 543547            OnAddSharedComponent?.Invoke(id, newComponent);
 548
 543549            newComponent.Initialize(this, id);
 550
 543551            return newComponent;
 552        }
 553
 554        public void SharedComponentDispose(string id)
 555        {
 519556            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 557            {
 519558                sharedComponent?.Dispose();
 519559                disposableComponents.Remove(id);
 519560                OnComponentRemoved?.Invoke(sharedComponent);
 561            }
 0562        }
 563
 564        public void EntityComponentRemove(string entityId, string name)
 565        {
 18566            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 567
 18568            if (decentralandEntity == null)
 569            {
 0570                return;
 571            }
 572
 18573            RemoveEntityComponent(decentralandEntity, name);
 18574        }
 575
 576        public T GetSharedComponent<T>()
 577            where T : class
 578        {
 172579            return disposableComponents.Values.FirstOrDefault(x => x is T) as T;
 580        }
 581
 582        private void RemoveComponentType<T>(IDCLEntity entity, CLASS_ID_COMPONENT classId)
 583            where T : MonoBehaviour
 584        {
 0585            var component = entity.components[classId] as IEntityComponent;
 586
 0587            if (component == null)
 0588                return;
 589
 0590            var monoBehaviour = component.GetTransform().GetComponent<T>();
 591
 0592            if (monoBehaviour != null)
 593            {
 0594                Utils.SafeDestroy(monoBehaviour);
 595            }
 0596        }
 597
 598        private void RemoveEntityComponent(IDCLEntity entity, string componentName)
 599        {
 600            switch (componentName)
 601            {
 602                case "shape":
 0603                    if (entity.meshesInfo.currentShape is BaseShape baseShape)
 604                    {
 0605                        baseShape.DetachFrom(entity);
 606                    }
 607
 0608                    return;
 609
 610                case OnClick.NAME:
 611                    {
 1612                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_CLICK, out IEntityComponent component
 613                        {
 1614                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1615                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_CLICK );
 616                        }
 617
 1618                        return;
 619                    }
 620                case OnPointerDown.NAME:
 621                    {
 1622                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_DOWN, out IEntityComponent component 
 623                        {
 1624                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1625                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_DOWN );
 626                        }
 627                    }
 1628                    return;
 629                case OnPointerUp.NAME:
 630                    {
 1631                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_UP, out IEntityComponent component ))
 632                        {
 1633                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1634                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_UP );
 635                        }
 636                    }
 1637                    return;
 638            }
 0639        }
 640
 641        public ISharedComponent SharedComponentUpdate(string id, BaseModel model)
 642        {
 27643            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 644            {
 27645                sharedComponent.UpdateFromModel(model);
 27646                return sharedComponent;
 647            }
 648
 0649            if (gameObject == null)
 650            {
 0651                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0652            }
 653            else
 654            {
 0655                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 656            }
 657
 0658            return null;
 659        }
 660
 661        public ISharedComponent SharedComponentUpdate(string id, string json)
 662        {
 568663            if (disposableComponents.TryGetValue(id, out ISharedComponent disposableComponent))
 664            {
 568665                disposableComponent.UpdateFromJSON(json);
 568666                return disposableComponent;
 667            }
 668
 0669            if (gameObject == null)
 670            {
 0671                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0672            }
 673            else
 674            {
 0675                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 676            }
 677
 0678            return null;
 679        }
 680
 681        protected virtual void SendMetricsEvent()
 682        {
 10370683            if (Time.frameCount % 10 == 0)
 1031684                metricsCounter.SendEvent();
 10370685        }
 686
 687        public ISharedComponent GetSharedComponent(string componentId)
 688        {
 480689            if (!disposableComponents.TryGetValue(componentId, out ISharedComponent result))
 690            {
 436691                return null;
 692            }
 693
 44694            return result;
 695        }
 696
 697        private IDCLEntity GetEntityForUpdate(string entityId)
 698        {
 711699            if (string.IsNullOrEmpty(entityId))
 700            {
 0701                Debug.LogError("Null or empty entityId");
 0702                return null;
 703            }
 704
 711705            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 706            {
 2707                return null;
 708            }
 709
 710            //NOTE(Brian): This is for removing stray null references? This should never happen.
 711            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 709712            if (entity == null || entity.gameObject == null)
 713            {
 0714                entities.Remove(entityId);
 0715                return null;
 716            }
 717
 709718            return entity;
 719        }
 720
 721        private void DisposeAllSceneComponents()
 722        {
 1266723            List<string> allDisposableComponents = disposableComponents.Select(x => x.Key).ToList();
 2532724            foreach (string id in allDisposableComponents)
 725            {
 540726                Environment.i.platform.parcelScenesCleaner.MarkDisposableComponentForCleanup(this, id);
 727            }
 726728        }
 729
 730        public string GetStateString()
 731        {
 1388732            string baseState = isPersistent ? "global-scene" : "scene";
 1388733            switch (sceneLifecycleHandler.state)
 734            {
 735                case SceneLifecycleHandler.State.NOT_READY:
 0736                    return $"{baseState}:{prettyName} - not ready...";
 737                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 710738                    return $"{baseState}:{prettyName} - waiting for init messages...";
 739                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0740                    if (disposableComponents != null && disposableComponents.Count > 0)
 0741                        return $"{baseState}:{prettyName} - left to ready:{disposableComponents.Count - sceneLifecycleHa
 742                    else
 0743                        return $"{baseState}:{prettyName} - no components. waiting...";
 744                case SceneLifecycleHandler.State.READY:
 678745                    return $"{baseState}:{prettyName} - ready!";
 746            }
 747
 0748            return $"scene:{prettyName} - no state?";
 749        }
 750
 751        public void RefreshLoadingState()
 752        {
 1388753            CalculateSceneLoadingState();
 754
 755#if UNITY_EDITOR
 1388756            gameObject.name = GetStateString();
 757#endif
 1388758        }
 759
 760        [ContextMenu("Get Waiting Components Debug Info")]
 761        public void GetWaitingComponentsDebugInfo()
 762        {
 0763            switch (sceneLifecycleHandler.state)
 764            {
 765                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 766
 0767                    foreach (string componentId in sceneLifecycleHandler.disposableNotReady)
 768                    {
 0769                        if (disposableComponents.ContainsKey(componentId))
 770                        {
 0771                            var component = disposableComponents[componentId];
 772
 0773                            Debug.Log($"Waiting for: {component.ToString()}");
 774
 0775                            foreach (var entity in component.GetAttachedEntities())
 776                            {
 0777                                var loader = LoadableShape.GetLoaderForEntity(entity);
 778
 0779                                string loadInfo = "No loader";
 780
 0781                                if (loader != null)
 782                                {
 0783                                    loadInfo = loader.ToString();
 784                                }
 785
 0786                                Debug.Log($"This shape is attached to {entity.entityId} entity. Click here for highlight
 787                            }
 788                        }
 789                        else
 790                        {
 0791                            Debug.Log($"Waiting for missing component? id: {componentId}");
 792                        }
 793                    }
 794
 795                    break;
 796
 797                default:
 0798                    Debug.Log("This scene is not waiting for any components. Its current state is " + sceneLifecycleHand
 799                    break;
 800            }
 0801        }
 802
 803        /// <summary>
 804        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 805        /// </summary>
 806        public void CalculateSceneLoadingState()
 807        {
 1388808            loadingProgress = 0f;
 809
 1388810            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 811                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 812            {
 678813                loadingProgress = disposableComponents != null && disposableComponents.Count > 0 ? (disposableComponents
 814            }
 815
 1388816            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0817        }
 818    }
 819}

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