< Summary

Class:DCL.Components.LoadableShape[LoadWrapperType,LoadWrapperModelType]
Assembly:DCL.Components.LoadableShapes
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/LoadableShapes/LoadableShape.cs
Covered lines:97
Uncovered lines:23
Coverable lines:120
Total lines:292
Line coverage:80.8% (97 of 120)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
LoadableShape()0%110100%
ApplyChanges(...)0%11.0211095%
AttachShape(...)0%10.918064.29%
ConfigureVisibility(...)0%770100%
ConfigureColliders(...)0%220100%
OnLoadFailed(...)0%330100%
CleanFailedWrapper(...)0%6.65060%
OnLoadCompleted(...)0%4.054085.71%
DetachShape(...)0%440100%
CallWhenReady(...)0%440100%
RaiseOnShapeUpdated(...)0%330100%
RaiseOnShapeLoaded(...)0%3.143075%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/LoadableShapes/LoadableShape.cs

#LineLine coverage
 1using System;
 2using DCL.Helpers;
 3using DCL.Models;
 4using System.Collections;
 5using UnityEngine;
 6using Object = UnityEngine.Object;
 7
 8namespace DCL.Components
 9{
 10    public class LoadableShape : BaseShape, IAssetCatalogReferenceHolder
 11    {
 12        [System.Serializable]
 13        public new class Model : BaseShape.Model
 14        {
 15            public string src;
 16            public string assetId;
 17
 18            public override BaseModel GetDataFromJSON(string json) { return Utils.SafeFromJson<Model>(json); }
 19        }
 20
 21        public bool isLoaded { get; protected set; }
 22
 23        public Action<LoadableShape> OnLoaded;
 24
 25        protected Model previousModel = new Model();
 26
 27        protected LoadableShape() { model = new Model(); }
 28
 29        public override int GetClassId() { return -1; }
 30
 31        public override IEnumerator ApplyChanges(BaseModel newModel) { return null; }
 32
 33        public override bool IsVisible()
 34        {
 35            Model model = (Model) this.model;
 36            return model.visible;
 37        }
 38
 39        public override bool HasCollisions()
 40        {
 41            Model model = (Model) this.model;
 42            return model.withCollisions;
 43        }
 44
 45        public string GetAssetId()
 46        {
 47            Model model = (Model) this.model;
 48            return model.assetId;
 49        }
 50    }
 51
 52    public class LoadableShape<LoadWrapperType, LoadWrapperModelType> : LoadableShape
 53        where LoadWrapperType : LoadWrapper, new()
 54        where LoadWrapperModelType : LoadableShape.Model, new()
 55    {
 56        private bool failed = false;
 57        private event Action<BaseDisposable> OnFinishCallbacks;
 58        public System.Action<IDCLEntity> OnEntityShapeUpdated;
 59
 60        new public LoadWrapperModelType model
 61        {
 62            get
 63            {
 83564                if (base.model == null)
 065                    base.model = new LoadWrapperModelType();
 66
 83567                return base.model as LoadWrapperModelType;
 68            }
 069            set { base.model = value; }
 70        }
 71
 72        new protected LoadWrapperModelType previousModel
 73        {
 74            get
 75            {
 48976                if (base.previousModel == null)
 077                    base.previousModel = new LoadWrapperModelType();
 78
 48979                return base.previousModel as LoadWrapperModelType;
 80            }
 081            set { base.previousModel = value; }
 82        }
 83
 10184        public LoadableShape()
 85        {
 10186            OnDetach += DetachShape;
 10187            OnAttach += AttachShape;
 10188        }
 89
 90        public override IEnumerator ApplyChanges(BaseModel newModel)
 91        {
 9992            LoadWrapperModelType model = (LoadWrapperModelType) newModel;
 93
 9994            bool updateVisibility = true;
 9995            bool updateCollisions = true;
 9996            bool triggerAttachment = true;
 97
 9998            if (previousModel != null)
 99            {
 91100                updateVisibility = previousModel.visible != model.visible;
 91101                updateCollisions = previousModel.withCollisions != model.withCollisions || previousModel.isPointerBlocke
 91102                triggerAttachment = (!string.IsNullOrEmpty(model.src) && previousModel.src != model.src) ||
 103                                    (!string.IsNullOrEmpty(model.assetId) && previousModel.assetId != model.assetId);
 104            }
 105
 218106            foreach (var entity in attachedEntities)
 107            {
 10108                if (triggerAttachment)
 2109                    AttachShape(entity);
 110
 10111                if (updateVisibility)
 7112                    ConfigureVisibility(entity);
 113
 10114                if (updateCollisions)
 0115                    ConfigureColliders(entity);
 116
 10117                RaiseOnShapeUpdated(entity);
 118            }
 119
 99120            previousModel = model;
 99121            return null;
 122        }
 123
 124        protected virtual void AttachShape(IDCLEntity entity)
 125        {
 96126            ContentProvider provider = null;
 127
 96128            if (!string.IsNullOrEmpty(model.assetId))
 129            {
 16130                provider = AssetCatalogBridge.i.GetContentProviderForAssetIdInSceneObjectCatalog(model.assetId);
 16131                if (string.IsNullOrEmpty(model.src))
 132                {
 0133                    SceneObject sceneObject = AssetCatalogBridge.i.GetSceneObjectById(model.assetId);
 0134                    if (sceneObject == null)
 135                    {
 136#if UNITY_EDITOR
 0137                        Debug.LogWarning($"LoadableShape '{model.assetId}' not found in catalog, probably asset pack del
 138#endif
 0139                        failed = true;
 0140                        OnLoadFailed(null, new Exception($"LoadableShape '{model.assetId}' not found in catalog, probabl
 0141                        return;
 142                    }
 143
 0144                    model.src = sceneObject.model;
 145                }
 146            }
 147
 96148            if (provider == null)
 80149                provider = scene.contentProvider;
 150
 96151            if (provider.HasContentsUrl(model.src))
 152            {
 96153                isLoaded = false;
 96154                entity.EnsureMeshGameObject(componentName + " mesh");
 155
 96156                LoadWrapperType loadableShape =
 157                    Environment.i.world.state.GetOrAddLoaderForEntity<LoadWrapperType>(entity);
 158
 96159                if (loadableShape is LoadWrapper_GLTF gltfLoadWrapper)
 95160                    gltfLoadWrapper.customContentProvider = provider;
 161
 96162                entity.meshesInfo.currentShape = this;
 163
 96164                loadableShape.entity = entity;
 96165                loadableShape.useVisualFeedback = Configuration.ParcelSettings.VISUAL_LOADING_ENABLED;
 96166                loadableShape.initialVisibility = model.visible && entity.isInsideSceneBoundaries;
 96167                loadableShape.Load(model.src, OnLoadCompleted, OnLoadFailed);
 96168            }
 169            else
 170            {
 171#if UNITY_EDITOR
 0172                Debug.LogWarning($"LoadableShape '{model.src}' not found in scene '{scene.sceneData.id}' mappings");
 173#endif
 0174                failed = true;
 175            }
 0176        }
 177
 178        void ConfigureVisibility(IDCLEntity entity)
 179        {
 91180            var loadable = Environment.i.world.state.GetLoaderForEntity(entity);
 181
 91182            if (loadable != null)
 91183                loadable.initialVisibility = model.visible && entity.isInsideSceneBoundaries;
 184
 91185            ConfigureVisibility(entity.meshRootGameObject, model.visible && entity.isInsideSceneBoundaries, entity.meshe
 186
 91187            if(!scene.componentsManagerLegacy.HasComponent(entity, CLASS_ID_COMPONENT.ANIMATOR) && entity.meshesInfo.ani
 8188                entity.meshesInfo.animation.enabled = model.visible && entity.isInsideSceneBoundaries;
 91189        }
 190
 191        protected virtual void ConfigureColliders(IDCLEntity entity)
 192        {
 76193            CollidersManager.i.ConfigureColliders(entity.meshRootGameObject, model.withCollisions && entity.isInsideScen
 76194        }
 195
 196        protected void OnLoadFailed(LoadWrapper loadWrapper, Exception exception)
 197        {
 3198            if (loadWrapper != null)
 3199                CleanFailedWrapper(loadWrapper);
 200
 3201            failed = true;
 3202            OnFinishCallbacks?.Invoke(this);
 3203            OnFinishCallbacks = null;
 3204        }
 205
 206        void CleanFailedWrapper(LoadWrapper loadWrapper)
 207        {
 3208            if (loadWrapper == null)
 0209                return;
 3210            if (loadWrapper.entity == null)
 0211                return;
 3212            if (loadWrapper.entity.gameObject == null)
 0213                return;
 214
 3215            GameObject go = loadWrapper.entity.gameObject;
 216
 3217            go.name += " - Failed loading";
 218
 3219            MaterialTransitionController[] transitionController =
 220                go.GetComponentsInChildren<MaterialTransitionController>(true);
 221
 6222            for (int i = 0; i < transitionController.Length; i++)
 223            {
 0224                MaterialTransitionController material = transitionController[i];
 0225                Object.Destroy(material);
 226            }
 3227        }
 228
 229        protected void OnLoadCompleted(LoadWrapper loadWrapper)
 230        {
 84231            IDCLEntity entity = loadWrapper.entity;
 232
 84233            if (entity.meshesInfo.currentShape == null)
 234            {
 0235                OnLoadFailed(loadWrapper, new Exception($"Entity {entity.entityId} current shape of mesh information is 
 0236                return;
 237            }
 238
 84239            isLoaded = true;
 84240            OnLoaded?.Invoke(this);
 241
 84242            entity.meshesInfo.meshRootGameObject = entity.meshRootGameObject;
 243
 84244            ConfigureVisibility(entity);
 84245            ConfigureColliders(entity);
 84246            RaiseOnShapeUpdated(entity);
 84247            RaiseOnShapeLoaded(entity);
 248
 84249            OnFinishCallbacks?.Invoke(this);
 84250            OnFinishCallbacks = null;
 84251        }
 252
 253        protected virtual void DetachShape(IDCLEntity entity)
 254        {
 84255            if (entity == null || entity.meshRootGameObject == null)
 3256                return;
 257
 81258            LoadWrapper loadWrapper = Environment.i.world.state.GetLoaderForEntity(entity);
 81259            loadWrapper?.Unload();
 81260            Environment.i.world.state.RemoveLoaderForEntity(entity);
 81261            entity.meshesInfo.CleanReferences();
 81262        }
 263
 264        public override void CallWhenReady(Action<ISharedComponent> callback)
 265        {
 19266            if (attachedEntities.Count == 0 || isLoaded || failed)
 267            {
 2268                callback.Invoke(this);
 2269            }
 270            else
 271            {
 17272                OnFinishCallbacks += callback;
 273            }
 17274        }
 275
 276        private void RaiseOnShapeUpdated(IDCLEntity entity)
 277        {
 94278            if (!isLoaded)
 4279                return;
 280
 90281            entity.OnShapeUpdated?.Invoke(entity);
 90282        }
 283
 284        private void RaiseOnShapeLoaded(IDCLEntity entity)
 285        {
 84286            if (!isLoaded)
 0287                return;
 288
 84289            entity.OnShapeLoaded?.Invoke(entity);
 5290        }
 291    }
 292}