< Summary

Class:DCL.Components.LoadableShape[LoadWrapperType,LoadWrapperModelType]
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/LoadableShapes/LoadableShape.cs
Covered lines:94
Uncovered lines:23
Coverable lines:117
Total lines:316
Line coverage:80.3% (94 of 117)
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%9.237064.29%
ConfigureVisibility(...)0%220100%
ConfigureColliders(...)0%110100%
OnLoadFailed(...)0%330100%
CleanFailedWrapper(...)0%6.65060%
OnLoadCompleted(...)0%4.044086.67%
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.Controllers;
 3using DCL.Helpers;
 4using DCL.Models;
 5using System.Collections;
 6using UnityEngine;
 7using Object = UnityEngine.Object;
 8using System.Collections.Generic;
 9
 10namespace DCL.Components
 11{
 12    public class LoadableShape : BaseShape, IAssetCatalogReferenceHolder
 13    {
 14        [System.Serializable]
 15        public new class Model : BaseShape.Model
 16        {
 17            public string src;
 18            public string assetId;
 19
 20            public override BaseModel GetDataFromJSON(string json) { return Utils.SafeFromJson<Model>(json); }
 21        }
 22
 23        public bool isLoaded { get; protected set; }
 24
 25        public Action<LoadableShape> OnLoaded;
 26
 27        protected Model previousModel = new Model();
 28
 29        protected static Dictionary<GameObject, LoadWrapper> attachedLoaders = new Dictionary<GameObject, LoadWrapper>()
 30
 31        public static LoadWrapper GetLoaderForEntity(IDCLEntity entity)
 32        {
 33            if (entity.meshRootGameObject == null)
 34            {
 35                Debug.LogWarning("NULL meshRootGameObject at GetLoaderForEntity()");
 36                return null;
 37            }
 38
 39            attachedLoaders.TryGetValue(entity.meshRootGameObject, out LoadWrapper result);
 40            return result;
 41        }
 42
 43        public static T GetOrAddLoaderForEntity<T>(IDCLEntity entity)
 44            where T : LoadWrapper, new()
 45        {
 46            if (!attachedLoaders.TryGetValue(entity.meshRootGameObject, out LoadWrapper result))
 47            {
 48                result = new T();
 49                attachedLoaders.Add(entity.meshRootGameObject, result);
 50            }
 51
 52            return result as T;
 53        }
 54
 55        public LoadableShape() { model = new Model(); }
 56
 57        public override int GetClassId() { return -1; }
 58
 59        public override IEnumerator ApplyChanges(BaseModel newModel) { return null; }
 60
 61        public override bool IsVisible()
 62        {
 63            Model model = (Model) this.model;
 64            return model.visible;
 65        }
 66
 67        public override bool HasCollisions()
 68        {
 69            Model model = (Model) this.model;
 70            return model.withCollisions;
 71        }
 72
 73        public string GetAssetId()
 74        {
 75            Model model = (Model) this.model;
 76            return model.assetId;
 77        }
 78    }
 79
 80    public class LoadableShape<LoadWrapperType, LoadWrapperModelType> : LoadableShape
 81        where LoadWrapperType : LoadWrapper, new()
 82        where LoadWrapperModelType : LoadableShape.Model, new()
 83    {
 84        private bool failed = false;
 85        private event Action<BaseDisposable> OnFinishCallbacks;
 86        public System.Action<IDCLEntity> OnEntityShapeUpdated;
 87
 88        new public LoadWrapperModelType model
 89        {
 90            get
 91            {
 61892                if (base.model == null)
 093                    base.model = new LoadWrapperModelType();
 94
 61895                return base.model as LoadWrapperModelType;
 96            }
 097            set { base.model = value; }
 98        }
 99
 100        new protected LoadWrapperModelType previousModel
 101        {
 102            get
 103            {
 386104                if (base.previousModel == null)
 0105                    base.previousModel = new LoadWrapperModelType();
 106
 386107                return base.previousModel as LoadWrapperModelType;
 108            }
 0109            set { base.previousModel = value; }
 110        }
 111
 86112        public LoadableShape()
 113        {
 86114            OnDetach += DetachShape;
 86115            OnAttach += AttachShape;
 86116        }
 117
 118        public override IEnumerator ApplyChanges(BaseModel newModel)
 119        {
 79120            LoadWrapperModelType model = (LoadWrapperModelType) newModel;
 121
 79122            bool updateVisibility = true;
 79123            bool updateCollisions = true;
 79124            bool triggerAttachment = true;
 125
 79126            if (previousModel != null)
 127            {
 69128                updateVisibility = previousModel.visible != model.visible;
 69129                updateCollisions = previousModel.withCollisions != model.withCollisions || previousModel.isPointerBlocke
 69130                triggerAttachment = (!string.IsNullOrEmpty(model.src) && previousModel.src != model.src) ||
 131                                    (!string.IsNullOrEmpty(model.assetId) && previousModel.assetId != model.assetId);
 132            }
 133
 168134            foreach (var entity in attachedEntities)
 135            {
 5136                if (triggerAttachment)
 2137                    AttachShape(entity);
 138
 5139                if (updateVisibility)
 2140                    ConfigureVisibility(entity);
 141
 5142                if (updateCollisions)
 0143                    ConfigureColliders(entity);
 144
 5145                RaiseOnShapeUpdated(entity);
 146            }
 147
 79148            previousModel = model;
 79149            return null;
 150        }
 151
 152        protected virtual void AttachShape(IDCLEntity entity)
 153        {
 79154            ContentProvider provider = null;
 155
 79156            if (!string.IsNullOrEmpty(model.assetId))
 157            {
 16158                provider = AssetCatalogBridge.i.GetContentProviderForAssetIdInSceneObjectCatalog(model.assetId);
 16159                if (string.IsNullOrEmpty(model.src))
 160                {
 0161                    SceneObject sceneObject = AssetCatalogBridge.i.GetSceneObjectById(model.assetId);
 0162                    if (sceneObject == null)
 163                    {
 164#if UNITY_EDITOR
 0165                        Debug.LogWarning($"LoadableShape '{model.assetId}' not found in catalog, probably asset pack del
 166#endif
 0167                        failed = true;
 0168                        OnLoadFailed(null);
 0169                        return;
 170                    }
 171
 0172                    model.src = sceneObject.model;
 173                }
 174            }
 175
 79176            if (provider == null)
 63177                provider = scene.contentProvider;
 178
 79179            if (provider.HasContentsUrl(model.src))
 180            {
 79181                isLoaded = false;
 79182                entity.EnsureMeshGameObject(componentName + " mesh");
 183
 79184                LoadWrapperType loadableShape = GetOrAddLoaderForEntity<LoadWrapperType>(entity);
 185
 79186                if (loadableShape is LoadWrapper_GLTF gltfLoadWrapper)
 78187                    gltfLoadWrapper.customContentProvider = provider;
 188
 79189                entity.meshesInfo.currentShape = this;
 190
 79191                loadableShape.entity = entity;
 79192                loadableShape.useVisualFeedback = Configuration.ParcelSettings.VISUAL_LOADING_ENABLED;
 79193                loadableShape.initialVisibility = model.visible;
 79194                loadableShape.Load(model.src, OnLoadCompleted, OnLoadFailed);
 79195            }
 196            else
 197            {
 198#if UNITY_EDITOR
 0199                Debug.LogWarning($"LoadableShape '{model.src}' not found in scene '{scene.sceneData.id}' mappings");
 200#endif
 0201                failed = true;
 202            }
 0203        }
 204
 205        void ConfigureVisibility(IDCLEntity entity)
 206        {
 2207            var loadable = GetLoaderForEntity(entity);
 208
 2209            if (loadable != null)
 2210                loadable.initialVisibility = model.visible;
 211
 2212            ConfigureVisibility(entity.meshRootGameObject, model.visible, entity.meshesInfo.renderers);
 2213        }
 214
 140215        protected virtual void ConfigureColliders(IDCLEntity entity) { CollidersManager.i.ConfigureColliders(entity.mesh
 216
 217        protected void OnLoadFailed(LoadWrapper loadWrapper)
 218        {
 3219            if (loadWrapper != null)
 3220                CleanFailedWrapper(loadWrapper);
 221
 3222            failed = true;
 3223            OnFinishCallbacks?.Invoke(this);
 3224            OnFinishCallbacks = null;
 3225        }
 226
 227        void CleanFailedWrapper(LoadWrapper loadWrapper)
 228        {
 3229            if (loadWrapper == null)
 0230                return;
 3231            if (loadWrapper.entity == null)
 0232                return;
 3233            if (loadWrapper.entity.gameObject == null)
 0234                return;
 235
 3236            GameObject go = loadWrapper.entity.gameObject;
 237
 3238            go.name += " - Failed loading";
 239
 3240            MaterialTransitionController[] transitionController =
 241                go.GetComponentsInChildren<MaterialTransitionController>(true);
 242
 6243            for (int i = 0; i < transitionController.Length; i++)
 244            {
 0245                MaterialTransitionController material = transitionController[i];
 0246                Object.Destroy(material);
 247            }
 3248        }
 249
 250        protected void OnLoadCompleted(LoadWrapper loadWrapper)
 251        {
 80252            IDCLEntity entity = loadWrapper.entity;
 253
 80254            if (entity.meshesInfo.currentShape == null)
 255            {
 0256                OnLoadFailed(loadWrapper);
 0257                return;
 258            }
 259
 80260            isLoaded = true;
 80261            OnLoaded?.Invoke(this);
 262
 80263            entity.meshesInfo.renderers = entity.meshRootGameObject.GetComponentsInChildren<Renderer>();
 264
 80265            var model = (Model) (entity.meshesInfo.currentShape as LoadableShape).GetModel();
 266
 80267            ConfigureVisibility(entity.meshRootGameObject, model.visible, loadWrapper.entity.meshesInfo.renderers);
 80268            ConfigureColliders(entity);
 80269            RaiseOnShapeUpdated(entity);
 80270            RaiseOnShapeLoaded(entity);
 271
 80272            OnFinishCallbacks?.Invoke(this);
 80273            OnFinishCallbacks = null;
 80274        }
 275
 276        protected virtual void DetachShape(IDCLEntity entity)
 277        {
 82278            if (entity == null || entity.meshRootGameObject == null)
 3279                return;
 280
 79281            LoadWrapper loadWrapper = GetLoaderForEntity(entity);
 282
 79283            loadWrapper?.Unload();
 284
 79285            entity.meshesInfo.CleanReferences();
 79286        }
 287
 288        public override void CallWhenReady(Action<ISharedComponent> callback)
 289        {
 19290            if (attachedEntities.Count == 0 || isLoaded || failed)
 291            {
 3292                callback.Invoke(this);
 3293            }
 294            else
 295            {
 16296                OnFinishCallbacks += callback;
 297            }
 16298        }
 299
 300        private void RaiseOnShapeUpdated(IDCLEntity entity)
 301        {
 85302            if (!isLoaded)
 3303                return;
 304
 82305            entity.OnShapeUpdated?.Invoke(entity);
 82306        }
 307
 308        private void RaiseOnShapeLoaded(IDCLEntity entity)
 309        {
 80310            if (!isLoaded)
 0311                return;
 312
 80313            entity.OnShapeLoaded?.Invoke(entity);
 5314        }
 315    }
 316}