< Summary

Class:DCL.DCLTexture
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Textures/DCLTexture.cs
Covered lines:62
Uncovered lines:23
Coverable lines:85
Total lines:212
Line coverage:72.9% (62 of 85)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Model()0%110100%
GetDataFromJSON(...)0%110100%
DCLTexture()0%110100%
GetClassId()0%2100%
FetchFromComponent()0%12300%
FetchTextureComponent()0%5.25080%
ApplyChanges()0%43.9419058.97%
AttachTo(...)0%110100%
AttachTo(...)0%110100%
AttachTo(...)0%110100%
DetachFrom(...)0%2100%
DetachFrom(...)0%110100%
DetachFrom(...)0%2100%
AddReference(...)0%330100%
RemoveReference(...)0%330100%
Dispose()0%440100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Textures/DCLTexture.cs

#LineLine coverage
 1using DCL.Components;
 2using DCL.Controllers;
 3using DCL.Models;
 4using System;
 5using System.Collections;
 6using DCL.Helpers;
 7using UnityEngine;
 8using System.Collections.Generic;
 9using System.Linq;
 10
 11namespace DCL
 12{
 13    public class DCLTexture : BaseDisposable
 14    {
 15        [System.Serializable]
 16        public class Model : BaseModel
 17        {
 18            public string src;
 19            public BabylonWrapMode wrap = BabylonWrapMode.CLAMP;
 6120            public FilterMode samplingMode = FilterMode.Bilinear;
 21            public bool hasAlpha = false;
 22
 5923            public override BaseModel GetDataFromJSON(string json) { return Utils.SafeFromJson<Model>(json); }
 24        }
 25
 26        public enum BabylonWrapMode
 27        {
 28            CLAMP,
 29            WRAP,
 30            MIRROR
 31        }
 32
 33        AssetPromise_Texture texturePromise = null;
 34
 35        public TextureWrapMode unityWrap;
 36        public FilterMode unitySamplingMode;
 37        public Texture2D texture;
 38        protected bool isDisposed;
 39
 7440        public Dictionary<ISharedComponent, HashSet<string>> attachedComponents = new Dictionary<ISharedComponent, HashS
 41
 042        public override int GetClassId() { return (int) CLASS_ID.TEXTURE; }
 43
 22244        public DCLTexture() { model = new Model(); }
 45
 46        public static IEnumerator FetchFromComponent(IParcelScene scene, string componentId,
 47            System.Action<Texture2D> OnFinish)
 48        {
 049            yield return FetchTextureComponent(scene, componentId, (dclTexture) => { OnFinish?.Invoke(dclTexture.texture
 050        }
 51
 52        public static IEnumerator FetchTextureComponent(IParcelScene scene, string componentId,
 53            System.Action<DCLTexture> OnFinish)
 54        {
 7855            if (!scene.disposableComponents.ContainsKey(componentId))
 56            {
 157                Debug.Log($"couldn't fetch texture, the DCLTexture component with id {componentId} doesn't exist");
 158                yield break;
 59            }
 60
 7761            DCLTexture textureComponent = scene.disposableComponents[componentId] as DCLTexture;
 62
 7763            if (textureComponent == null)
 64            {
 065                Debug.Log($"couldn't fetch texture, the shared component with id {componentId} is NOT a DCLTexture");
 066                yield break;
 67            }
 68
 19269            yield return new WaitUntil(() => textureComponent.texture != null);
 70
 7571            OnFinish.Invoke(textureComponent);
 7572        }
 73
 74        public override IEnumerator ApplyChanges(BaseModel newModel)
 75        {
 11876            yield return new WaitUntil(() => CommonScriptableObjects.rendererState.Get());
 77
 78            //If the scene creates and destroy the component before our renderer has been turned on bad things happen!
 79            //TODO: Analyze if we can catch this upstream and stop the IEnumerator
 5980            if (isDisposed)
 081                yield break;
 82
 5983            Model model = (Model) newModel;
 84
 5985            unitySamplingMode = model.samplingMode;
 86
 5987            switch (model.wrap)
 88            {
 89                case BabylonWrapMode.CLAMP:
 5890                    unityWrap = TextureWrapMode.Clamp;
 5891                    break;
 92                case BabylonWrapMode.WRAP:
 093                    unityWrap = TextureWrapMode.Repeat;
 094                    break;
 95                case BabylonWrapMode.MIRROR:
 196                    unityWrap = TextureWrapMode.Mirror;
 97                    break;
 98            }
 99
 59100            if (texture == null && !string.IsNullOrEmpty(model.src))
 101            {
 57102                bool isBase64 = model.src.Contains("image/png;base64");
 103
 57104                if (isBase64)
 105                {
 0106                    string base64Data = model.src.Substring(model.src.IndexOf(',') + 1);
 107
 108                    // The used texture variable can't be null for the ImageConversion.LoadImage to work
 0109                    if (texture == null)
 0110                        texture = new Texture2D(1, 1);
 111
 0112                    if (!ImageConversion.LoadImage(texture, Convert.FromBase64String(base64Data)))
 113                    {
 0114                        Debug.LogError($"DCLTexture with id {id} couldn't parse its base64 image data.");
 115                    }
 116
 0117                    if (texture != null)
 118                    {
 0119                        texture.wrapMode = unityWrap;
 0120                        texture.filterMode = unitySamplingMode;
 0121                        texture.Compress(false);
 0122                        texture.Apply(unitySamplingMode != FilterMode.Point, true);
 123                    }
 0124                }
 125                else
 126                {
 127                    string contentsUrl;
 57128                    bool isExternalURL = model.src.Contains("http://") || model.src.Contains("https://");
 129
 57130                    if (isExternalURL)
 0131                        contentsUrl = model.src;
 132                    else
 57133                        scene.contentProvider.TryGetContentsUrl(model.src, out contentsUrl);
 134
 57135                    if (!string.IsNullOrEmpty(contentsUrl))
 136                    {
 57137                        if (texturePromise != null)
 0138                            AssetPromiseKeeper_Texture.i.Forget(texturePromise);
 139
 57140                        texture = null;
 57141                        texturePromise = new AssetPromise_Texture(contentsUrl, unityWrap, unitySamplingMode, storeDefaul
 111142                        texturePromise.OnSuccessEvent += (x) => texture = x.texture;
 57143                        texturePromise.OnFailEvent += (x, error) => { texture = null; };
 144
 57145                        AssetPromiseKeeper_Texture.i.Keep(texturePromise);
 57146                        yield return texturePromise;
 147                    }
 148                }
 149            }
 56150        }
 151
 25152        public virtual void AttachTo(PBRMaterial component) => AddReference(component);
 153
 41154        public virtual void AttachTo(BasicMaterial component) => AddReference(component);
 155
 9156        public virtual void AttachTo(UIImage component) => AddReference(component);
 157
 0158        public virtual void DetachFrom(PBRMaterial component) => RemoveReference(component);
 159
 42160        public virtual void DetachFrom(BasicMaterial component) => RemoveReference(component);
 161
 0162        public virtual void DetachFrom(UIImage component) => RemoveReference(component);
 163
 164        void AddReference(ISharedComponent component)
 165        {
 75166            if (attachedComponents.ContainsKey(component))
 1167                return;
 168
 74169            attachedComponents.Add(component, new HashSet<string>());
 170
 268171            foreach ( var entity in component.GetAttachedEntities() )
 172            {
 60173                attachedComponents[component].Add(entity.entityId);
 60174                DataStore.i.sceneWorldObjects.AddTexture(scene.sceneData.id, entity.entityId, texture);
 175            }
 74176        }
 177
 178        void RemoveReference(ISharedComponent component)
 179        {
 53180            if (!attachedComponents.ContainsKey(component))
 17181                return;
 182
 140183            foreach ( var entityId in attachedComponents[component] )
 184            {
 34185                DataStore.i.sceneWorldObjects.RemoveTexture(scene.sceneData.id, entityId, texture);
 186            }
 187
 36188            attachedComponents.Remove(component);
 36189        }
 190
 191        public override void Dispose()
 192        {
 52193            if ( isDisposed )
 24194                return;
 195
 28196            isDisposed = true;
 197
 39198            while ( attachedComponents.Count > 0 )
 199            {
 11200                RemoveReference(attachedComponents.First().Key);
 201            }
 202
 28203            if (texturePromise != null)
 204            {
 27205                AssetPromiseKeeper_Texture.i.Forget(texturePromise);
 27206                texturePromise = null;
 207            }
 208
 28209            base.Dispose();
 28210        }
 211    }
 212}