< Summary

Class:DCL.Controllers.ParcelScene
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScene.cs
Covered lines:267
Uncovered lines:88
Coverable lines:355
Total lines:826
Line coverage:75.2% (267 of 355)
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%12300%
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%12.0712092.31%
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%21.2212060%
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;
 48117        public Dictionary<string, IDCLEntity> entities { get; private set; } = new Dictionary<string, IDCLEntity>();
 75518        public Dictionary<string, ISharedComponent> disposableComponents { get; private set; } = new Dictionary<string, 
 443519        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 20
 47621        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
 10832        public ContentProvider contentProvider { get; set; }
 33
 44134        public bool isTestScene { get; set; } = false;
 182735        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]
 47642        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        {
 47652            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 47653            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 47654        }
 55
 56        private void OnDestroy()
 57        {
 47658            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 47659            metricsCounter?.Dispose();
 47360        }
 61
 94962        void OnDisable() { metricsCounter?.Disable(); }
 63
 64        private void Update()
 65        {
 982966            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 67                && CommonScriptableObjects.rendererState.Get())
 978968                SendMetricsEvent();
 982969        }
 70
 91471        protected virtual string prettyName => sceneData.basePosition.ToString();
 72
 73        public virtual void SetData(LoadParcelScenesMessage.UnityParcelScene data)
 74        {
 47375            Assert.IsTrue( !string.IsNullOrEmpty(data.id), "Scene must have an ID!" );
 76
 47377            this.sceneData = data;
 78
 47379            contentProvider = new ContentProvider();
 47380            contentProvider.baseUrl = data.baseUrl;
 47381            contentProvider.contents = data.contents;
 47382            contentProvider.BakeHashes();
 83
 47384            parcels.Clear();
 85
 192486            for (int i = 0; i < sceneData.parcels.Length; i++)
 87            {
 48988                parcels.Add(sceneData.parcels[i]);
 89            }
 90
 47391            if (DCLCharacterController.i != null)
 92            {
 40093                gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(data.basePo
 94            }
 95
 47396            metricsCounter = new SceneMetricsCounter(this);
 47397            metricsCounter.Enable();
 98
 47399            OnSetData?.Invoke(data);
 473100        }
 101
 102        void OnWorldReposition(Vector3 current, Vector3 previous)
 103        {
 2104            Vector3 sceneWorldPos = Utils.GridToWorldPosition(sceneData.basePosition.x, sceneData.basePosition.y);
 2105            gameObject.transform.position = PositionUtils.WorldToUnityPosition(sceneWorldPos);
 2106        }
 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        {
 396118            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 119            {
 394120                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 121            }
 396122        }
 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        {
 422135            if (isReleased)
 0136                return;
 137
 422138            if (sceneDebugPlane != null)
 139            {
 394140                sceneDebugPlane.Dispose();
 394141                sceneDebugPlane = null;
 142            }
 143
 422144            DisposeAllSceneComponents();
 145
 422146            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 147            {
 0148                RemoveAllEntitiesImmediate();
 0149                PoolManager.i.Cleanup(true, true);
 0150            }
 151            else
 152            {
 422153                if (entities.Count > 0)
 154                {
 218155                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 218156                    this.gameObject.SetActive(false);
 157
 218158                    RemoveAllEntities();
 218159                }
 160                else
 161                {
 204162                    Destroy(this.gameObject);
 163                }
 164            }
 165
 422166            isReleased = true;
 422167        }
 168
 0169        public override string ToString() { return "Parcel Scene: " + base.ToString() + "\n" + sceneData; }
 170
 171        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 172        {
 176173            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 132174                return false;
 44175            if (!IsInsideSceneBoundaries(objectBounds.max + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 14176                return false;
 177
 30178            return true;
 179        }
 180
 181        public virtual bool IsInsideSceneBoundaries(Vector2Int gridPosition, float height = 0f)
 182        {
 87183            if (parcels.Count == 0)
 0184                return false;
 185
 87186            float heightLimit = metricsCounter.GetLimits().sceneHeight;
 187
 87188            if (height > heightLimit)
 0189                return false;
 190
 87191            return parcels.Contains(gridPosition);
 192        }
 193
 194        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 195        {
 257196            if (parcels.Count == 0)
 0197                return false;
 198
 257199            float heightLimit = metricsCounter.GetLimits().sceneHeight;
 257200            if (height > heightLimit)
 22201                return false;
 202
 235203            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 235204            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 205
 206            // We check the target world position
 235207            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 235208            if (parcels.Contains(targetCoordinate))
 92209                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            PoolManagerFactory.EnsureEntityPool(false);
 256
 257            // As we know that the pool already exists, we just get one gameobject from it
 540258            PoolableObject po = PoolManager.i.Get(PoolManagerFactory.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)
 447273                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        {
 478284            if (entities.ContainsKey(id))
 285            {
 478286                IDCLEntity entity = entities[id];
 287
 478288                if (!entity.markedForCleanup)
 289                {
 290                    // This will also cleanup its children
 478291                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 292                }
 293
 478294                entities.Remove(id);
 478295            }
 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
 486307            using (var iterator = entity.children.GetEnumerator())
 308            {
 494309                while (iterator.MoveNext())
 310                {
 8311                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 312                }
 486313            }
 314
 486315            OnEntityRemoved?.Invoke(entity);
 316
 486317            if (Environment.i.world.sceneBoundsChecker.enabled)
 318            {
 38319                entity.OnShapeUpdated -= Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked;
 38320                Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(entity);
 321            }
 322
 486323            if (removeImmediatelyFromEntitiesList)
 324            {
 325                // Every entity ends up being removed through here
 38326                entity.Cleanup();
 38327                entities.Remove(entity.entityId);
 38328            }
 329            else
 330            {
 448331                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 332            }
 448333        }
 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.
 218340            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 341
 218342            using (var iterator = entities.GetEnumerator())
 343            {
 682344                while (iterator.MoveNext())
 345                {
 464346                    if (iterator.Current.Value.parent == null)
 347                    {
 457348                        if (instant)
 0349                            rootEntities.Add(iterator.Current.Value);
 350                        else
 457351                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 352                    }
 353                }
 218354            }
 355
 218356            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            }
 218369        }
 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            Environment.i.platform.cullingController.MarkDirty();
 15386            Environment.i.platform.physicsSyncController.MarkDirty();
 387
 15388            if ( DCLCharacterController.i != null )
 389            {
 13390                if (parentId == "FirstPersonCameraEntityReference" || parentId == "PlayerEntityReference") // PlayerEnti
 391                {
 392                    // In this case, the entity will attached to the first person camera
 393                    // On first person mode, the entity will rotate with the camera. On third person mode, the entity wi
 1394                    me.SetParent(DCLCharacterController.i.firstPersonCameraReference);
 1395                    Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1396                    return;
 397                }
 398
 12399                if (parentId == "AvatarEntityReference" || parentId == "AvatarPositionEntityReference") // AvatarPositio
 400                {
 401                    // In this case, the entity will be attached to the avatar
 402                    // It will simply rotate with the avatar, regardless of where the camera is pointing
 1403                    me.SetParent(DCLCharacterController.i.avatarReference);
 1404                    Environment.i.world.sceneBoundsChecker.AddPersistent(me);
 1405                    return;
 406                }
 407
 11408                if (me.parent == DCLCharacterController.i.firstPersonCameraReference || me.parent == DCLCharacterControl
 409                {
 1410                    Environment.i.world.sceneBoundsChecker.RemoveEntityToBeChecked(me);
 411                }
 412            }
 413
 13414            if (parentId == "0")
 415            {
 416                // The entity will be child of the scene directly
 2417                me.SetParent(null);
 2418                me.gameObject.transform.SetParent(gameObject.transform, false);
 2419            }
 420            else
 421            {
 11422                IDCLEntity myParent = GetEntityForUpdate(parentId);
 423
 11424                if (myParent != null)
 425                {
 11426                    me.SetParent(myParent);
 427                }
 428            }
 11429        }
 430
 431        /**
 432          * This method is called when we need to attach a disposable component to the entity
 433          */
 434        public void SharedComponentAttach(string entityId, string id)
 435        {
 353436            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 437
 353438            if (decentralandEntity == null)
 439            {
 2440                return;
 441            }
 442
 351443            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 444            {
 349445                sharedComponent.AttachTo(decentralandEntity);
 446            }
 351447        }
 448
 449        public IEntityComponent EntityComponentCreateOrUpdateWithModel(string entityId, CLASS_ID_COMPONENT classId, obje
 450        {
 326451            IDCLEntity entity = GetEntityForUpdate(entityId);
 452
 326453            if (entity == null)
 454            {
 0455                Debug.LogError($"scene '{sceneData.id}': Can't create entity component if the entity {entityId} doesn't 
 0456                return null;
 457            }
 458
 326459            IEntityComponent newComponent = null;
 460
 326461            if (classId == CLASS_ID_COMPONENT.UUID_CALLBACK)
 462            {
 50463                OnPointerEvent.Model model = JsonUtility.FromJson<OnPointerEvent.Model>(data as string);
 50464                classId = model.GetClassIdFromType();
 465            }
 466
 326467            if (!entity.components.ContainsKey(classId))
 468            {
 251469                var factory = Environment.i.world.componentFactory;
 251470                newComponent = factory.CreateComponent((int) classId) as IEntityComponent;
 471
 251472                if (newComponent != null)
 473                {
 251474                    entity.components.Add(classId, newComponent);
 251475                    OnComponentAdded?.Invoke(newComponent);
 476
 251477                    newComponent.Initialize(this, entity);
 478
 251479                    if (data is string json)
 480                    {
 216481                        newComponent.UpdateFromJSON(json);
 216482                    }
 483                    else
 484                    {
 35485                        newComponent.UpdateFromModel(data as BaseModel);
 486                    }
 487                }
 35488            }
 489            else
 490            {
 75491                newComponent = EntityComponentUpdate(entity, classId, data as string);
 492            }
 493
 326494            if (newComponent != null && newComponent is IOutOfSceneBoundariesHandler)
 15495                Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(entity);
 496
 326497            OnChanged?.Invoke();
 326498            Environment.i.platform.physicsSyncController.MarkDirty();
 326499            Environment.i.platform.cullingController.MarkDirty();
 326500            return newComponent;
 501        }
 502
 291503        public IEntityComponent EntityComponentCreateOrUpdate(string entityId, CLASS_ID_COMPONENT classId, string data) 
 504
 505        // The EntityComponentUpdate() parameters differ from other similar methods because there is no EntityComponentU
 506        public IEntityComponent EntityComponentUpdate(IDCLEntity entity, CLASS_ID_COMPONENT classId,
 507            string componentJson)
 508        {
 92509            if (entity == null)
 510            {
 0511                Debug.LogError($"Can't update the {classId} component of a nonexistent entity!", this);
 0512                return null;
 513            }
 514
 92515            if (!entity.components.ContainsKey(classId))
 516            {
 0517                Debug.LogError($"Entity {entity.entityId} doesn't have a {classId} component to update!", this);
 0518                return null;
 519            }
 520
 92521            IComponent targetComponent = entity.components[classId];
 92522            targetComponent.UpdateFromJSON(componentJson);
 523
 92524            return targetComponent as IEntityComponent;
 525        }
 526
 527        public ISharedComponent SharedComponentCreate(string id, int classId)
 528        {
 550529            if (disposableComponents.TryGetValue(id, out ISharedComponent component))
 4530                return component;
 531
 546532            if (classId == (int) CLASS_ID.UI_SCREEN_SPACE_SHAPE || classId == (int) CLASS_ID.UI_FULLSCREEN_SHAPE)
 533            {
 44534                if (GetSharedComponent<UIScreenSpace>() != null)
 0535                    return null;
 536            }
 537
 546538            var factory = Environment.i.world.componentFactory;
 546539            ISharedComponent newComponent = factory.CreateComponent(classId) as ISharedComponent;
 540
 546541            if (newComponent == null)
 0542                return null;
 543
 546544            disposableComponents.Add(id, newComponent);
 546545            OnAddSharedComponent?.Invoke(id, newComponent);
 546
 546547            newComponent.Initialize(this, id);
 548
 546549            return newComponent;
 550        }
 551
 552        public void SharedComponentDispose(string id)
 553        {
 424554            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 555            {
 424556                sharedComponent?.Dispose();
 424557                disposableComponents.Remove(id);
 424558                OnComponentRemoved?.Invoke(sharedComponent);
 559            }
 0560        }
 561
 562        public void EntityComponentRemove(string entityId, string name)
 563        {
 18564            IDCLEntity decentralandEntity = GetEntityForUpdate(entityId);
 565
 18566            if (decentralandEntity == null)
 567            {
 0568                return;
 569            }
 570
 18571            RemoveEntityComponent(decentralandEntity, name);
 18572        }
 573
 574        public T GetSharedComponent<T>()
 575            where T : class
 576        {
 507577            return disposableComponents.Values.FirstOrDefault(x => x is T) as T;
 578        }
 579
 580        private void RemoveComponentType<T>(IDCLEntity entity, CLASS_ID_COMPONENT classId)
 581            where T : MonoBehaviour
 582        {
 0583            var component = entity.components[classId] as IEntityComponent;
 584
 0585            if (component == null)
 0586                return;
 587
 0588            var monoBehaviour = component.GetTransform().GetComponent<T>();
 589
 0590            if (monoBehaviour != null)
 591            {
 0592                Utils.SafeDestroy(monoBehaviour);
 593            }
 0594        }
 595
 596        private void RemoveEntityComponent(IDCLEntity entity, string componentName)
 597        {
 598            switch (componentName)
 599            {
 600                case "shape":
 0601                    if (entity.meshesInfo.currentShape is BaseShape baseShape)
 602                    {
 0603                        baseShape.DetachFrom(entity);
 604                    }
 605
 0606                    return;
 607
 608                case OnClick.NAME:
 609                    {
 1610                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_CLICK, out IEntityComponent component
 611                        {
 1612                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1613                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_CLICK );
 614                        }
 615
 1616                        return;
 617                    }
 618                case OnPointerDown.NAME:
 619                    {
 1620                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_DOWN, out IEntityComponent component 
 621                        {
 1622                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1623                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_DOWN );
 624                        }
 625                    }
 1626                    return;
 627                case OnPointerUp.NAME:
 628                    {
 1629                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.UUID_ON_UP, out IEntityComponent component ))
 630                        {
 1631                            Utils.SafeDestroy(component.GetTransform().gameObject);
 1632                            entity.components.Remove( CLASS_ID_COMPONENT.UUID_ON_UP );
 633                        }
 634                    }
 1635                    return;
 636                case "transform":
 637                    {
 0638                        if ( entity.TryGetBaseComponent(CLASS_ID_COMPONENT.AVATAR_ATTACH, out IEntityComponent component
 639                        {
 0640                            component.Cleanup();
 0641                            entity.components.Remove( CLASS_ID_COMPONENT.AVATAR_ATTACH );
 642                        }
 643                    }
 0644                    return;
 645            }
 0646        }
 647
 648        public ISharedComponent SharedComponentUpdate(string id, BaseModel model)
 649        {
 27650            if (disposableComponents.TryGetValue(id, out ISharedComponent sharedComponent))
 651            {
 27652                sharedComponent.UpdateFromModel(model);
 27653                return sharedComponent;
 654            }
 655
 0656            if (gameObject == null)
 657            {
 0658                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0659            }
 660            else
 661            {
 0662                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 663            }
 664
 0665            return null;
 666        }
 667
 668        public ISharedComponent SharedComponentUpdate(string id, string json)
 669        {
 572670            if (disposableComponents.TryGetValue(id, out ISharedComponent disposableComponent))
 671            {
 572672                disposableComponent.UpdateFromJSON(json);
 572673                return disposableComponent;
 674            }
 675
 0676            if (gameObject == null)
 677            {
 0678                Debug.LogError($"Unknown disposableComponent {id} -- scene has been destroyed?");
 0679            }
 680            else
 681            {
 0682                Debug.LogError($"Unknown disposableComponent {id}", gameObject);
 683            }
 684
 0685            return null;
 686        }
 687
 688        protected virtual void SendMetricsEvent()
 689        {
 9789690            if (Time.frameCount % 10 == 0)
 981691                metricsCounter.SendEvent();
 9789692        }
 693
 694        public ISharedComponent GetSharedComponent(string componentId)
 695        {
 483696            if (!disposableComponents.TryGetValue(componentId, out ISharedComponent result))
 697            {
 438698                return null;
 699            }
 700
 45701            return result;
 702        }
 703
 704        private IDCLEntity GetEntityForUpdate(string entityId)
 705        {
 723706            if (string.IsNullOrEmpty(entityId))
 707            {
 0708                Debug.LogError("Null or empty entityId");
 0709                return null;
 710            }
 711
 723712            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 713            {
 2714                return null;
 715            }
 716
 717            //NOTE(Brian): This is for removing stray null references? This should never happen.
 718            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 721719            if (entity == null || entity.gameObject == null)
 720            {
 0721                entities.Remove(entityId);
 0722                return null;
 723            }
 724
 721725            return entity;
 726        }
 727
 728        private void DisposeAllSceneComponents()
 729        {
 868730            List<string> allDisposableComponents = disposableComponents.Select(x => x.Key).ToList();
 1736731            foreach (string id in allDisposableComponents)
 732            {
 446733                Environment.i.platform.parcelScenesCleaner.MarkDisposableComponentForCleanup(this, id);
 734            }
 422735        }
 736
 737        public string GetStateString()
 738        {
 914739            string baseState = isPersistent ? "global-scene" : "scene";
 914740            switch (sceneLifecycleHandler.state)
 741            {
 742                case SceneLifecycleHandler.State.NOT_READY:
 0743                    return $"{baseState}:{prettyName} - not ready...";
 744                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 473745                    return $"{baseState}:{prettyName} - waiting for init messages...";
 746                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0747                    if (disposableComponents != null && disposableComponents.Count > 0)
 0748                        return $"{baseState}:{prettyName} - left to ready:{disposableComponents.Count - sceneLifecycleHa
 749                    else
 0750                        return $"{baseState}:{prettyName} - no components. waiting...";
 751                case SceneLifecycleHandler.State.READY:
 441752                    return $"{baseState}:{prettyName} - ready!";
 753            }
 754
 0755            return $"scene:{prettyName} - no state?";
 756        }
 757
 758        public void RefreshLoadingState()
 759        {
 914760            CalculateSceneLoadingState();
 761
 762#if UNITY_EDITOR
 914763            gameObject.name = GetStateString();
 764#endif
 914765        }
 766
 767        [ContextMenu("Get Waiting Components Debug Info")]
 768        public void GetWaitingComponentsDebugInfo()
 769        {
 0770            switch (sceneLifecycleHandler.state)
 771            {
 772                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 773
 0774                    foreach (string componentId in sceneLifecycleHandler.disposableNotReady)
 775                    {
 0776                        if (disposableComponents.ContainsKey(componentId))
 777                        {
 0778                            var component = disposableComponents[componentId];
 779
 0780                            Debug.Log($"Waiting for: {component.ToString()}");
 781
 0782                            foreach (var entity in component.GetAttachedEntities())
 783                            {
 0784                                var loader = LoadableShape.GetLoaderForEntity(entity);
 785
 0786                                string loadInfo = "No loader";
 787
 0788                                if (loader != null)
 789                                {
 0790                                    loadInfo = loader.ToString();
 791                                }
 792
 0793                                Debug.Log($"This shape is attached to {entity.entityId} entity. Click here for highlight
 794                            }
 795                        }
 796                        else
 797                        {
 0798                            Debug.Log($"Waiting for missing component? id: {componentId}");
 799                        }
 800                    }
 801
 802                    break;
 803
 804                default:
 0805                    Debug.Log("This scene is not waiting for any components. Its current state is " + sceneLifecycleHand
 806                    break;
 807            }
 0808        }
 809
 810        /// <summary>
 811        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 812        /// </summary>
 813        public void CalculateSceneLoadingState()
 814        {
 914815            loadingProgress = 0f;
 816
 914817            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 818                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 819            {
 441820                loadingProgress = disposableComponents != null && disposableComponents.Count > 0 ? (disposableComponents
 821            }
 822
 914823            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0824        }
 825    }
 826}

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