< Summary

Class:BIWCreatorController
Assembly:BuilderInWorld
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BuilderMode/Controllers/BIWCreatorController.cs
Covered lines:149
Uncovered lines:41
Coverable lines:190
Total lines:406
Line coverage:78.4% (149 of 190)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
BIWCreatorController()0%110100%
Init(...)0%220100%
Dispose()0%220100%
Update()0%220100%
SendAnalytics()0%2.862040%
Clean()0%330100%
IsAnyErrorOnEntities()0%2100%
IsInsideTheLimits(...)0%17.098047.83%
CreateErrorOnEntity(...)0%22090%
DeleteErrorOnEntity(...)0%2.022083.33%
CreateCatalogItem(...)0%110100%
CreateCatalogItem(...)0%9.099089.66%
ExistsLoadingGameObjectForEntity(...)0%110100%
CreateLoadingObject(...)0%220100%
OnShapeLoadFinish(...)0%2100%
RemoveLoadingObject(...)0%2.022083.33%
RemoveLoadingObjectInmediate(...)0%220100%
AddSmartItemComponent(...)0%2100%
AddEntityNameComponent(...)0%110100%
AddLockedComponent(...)0%220100%
AddShape(...)0%2.52050%
AddSceneMappings(...)0%660100%
CreateLastCatalogItem()0%4.074083.33%
OnCatalogItemSelected(...)0%3.333066.67%
OnCatalogItemDropped(...)0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BuilderMode/Controllers/BIWCreatorController.cs

#LineLine coverage
 1using DCL;
 2using DCL.Components;
 3using DCL.Configuration;
 4using DCL.Models;
 5using System;
 6using System.Collections.Generic;
 7using System.Linq;
 8using UnityEngine;
 9using UnityEngine.Serialization;
 10
 11public interface IBIWCreatorController
 12{
 13    event Action OnCatalogItemPlaced;
 14    event Action OnInputDone;
 15    void CreateCatalogItem(CatalogItem catalogItem, bool autoSelect = true, bool isFloor = false);
 16    BIWEntity CreateCatalogItem(CatalogItem catalogItem, Vector3 startPosition, bool autoSelect = true, bool isFloor = f
 17    void CreateErrorOnEntity(BIWEntity entity);
 18    void RemoveLoadingObjectInmediate(string entityId);
 19    bool IsAnyErrorOnEntities();
 20    void CreateLoadingObject(BIWEntity entity);
 21}
 22
 23public class BIWCreatorController : BIWController, IBIWCreatorController
 24{
 25    private const float SECONDS_TO_SEND_ANALYTICS = 5f;
 26
 27    public event Action OnInputDone;
 28
 29    public event Action OnCatalogItemPlaced;
 30
 31    private IBIWModeController modeController;
 32
 33    private IBIWFloorHandler floorHandler;
 34    private IBIWEntityHandler entityHandler;
 35
 36    private GameObject loadingObjectPrefab;
 37    private GameObject errorPrefab;
 38
 39    private CatalogItem lastCatalogItemCreated;
 40
 4041    private readonly Dictionary<string, BIWLoadingPlaceHolder> loadingGameObjects = new Dictionary<string, BIWLoadingPla
 4042    private readonly Dictionary<BIWEntity, GameObject> errorGameObjects = new Dictionary<BIWEntity, GameObject>();
 43
 4044    private readonly List<KeyValuePair<CatalogItem, string>> itemsToSendAnalytics = new List<KeyValuePair<CatalogItem, s
 45
 46    private float lastAnalyticsSentTimestamp = 0;
 47
 48    public override void Init(BIWContext biwContext)
 49    {
 4050        base.Init(biwContext);
 51
 4052        modeController = biwContext.modeController;
 4053        floorHandler = biwContext.floorHandler;
 4054        entityHandler = biwContext.entityHandler;
 55
 4056        loadingObjectPrefab = biwContext.projectReferencesAsset.loadingPrefab;
 4057        errorPrefab = biwContext.projectReferencesAsset.errorPrefab;
 58
 4059        if (HUDController.i.builderInWorldMainHud != null)
 60        {
 2661            HUDController.i.builderInWorldMainHud.OnCatalogItemSelected += OnCatalogItemSelected;
 2662            HUDController.i.builderInWorldMainHud.OnCatalogItemDropped += OnCatalogItemDropped;
 63        }
 4064    }
 65
 66    public override void Dispose()
 67    {
 3468        base.Dispose();
 3469        if (HUDController.i.builderInWorldMainHud != null)
 70        {
 2771            HUDController.i.builderInWorldMainHud.OnCatalogItemSelected -= OnCatalogItemSelected;
 2772            HUDController.i.builderInWorldMainHud.OnCatalogItemDropped -= OnCatalogItemDropped;
 73        }
 74
 3475        Clean();
 3476    }
 77
 78    public override void Update()
 79    {
 280        base.Update();
 281        if (Time.realtimeSinceStartup >= lastAnalyticsSentTimestamp)
 82        {
 283            SendAnalytics();
 284            lastAnalyticsSentTimestamp = Time.realtimeSinceStartup + SECONDS_TO_SEND_ANALYTICS;
 85        }
 286    }
 87
 88    private void SendAnalytics()
 89    {
 290        if (itemsToSendAnalytics.Count == 0)
 291            return;
 92
 093        BIWAnalytics.NewObjectPlacedChunk(itemsToSendAnalytics);
 094        itemsToSendAnalytics.Clear();
 095    }
 96
 97    public void Clean()
 98    {
 15099        foreach (BIWLoadingPlaceHolder placeHolder in loadingGameObjects.Values)
 100        {
 7101            placeHolder.Dispose();
 102        }
 103
 174104        foreach (BIWEntity entity in errorGameObjects.Keys.ToArray())
 105        {
 19106            DeleteErrorOnEntity(entity);
 107        }
 108
 68109        loadingGameObjects.Clear();
 68110        errorGameObjects.Clear();
 68111    }
 112
 0113    public bool IsAnyErrorOnEntities() { return errorGameObjects.Count > 0; }
 114
 115    private bool IsInsideTheLimits(CatalogItem sceneObject)
 116    {
 16117        if (HUDController.i.builderInWorldMainHud == null)
 15118            return false;
 119
 1120        SceneMetricsModel limits = sceneToEdit.metricsController.GetLimits();
 1121        SceneMetricsModel usage = sceneToEdit.metricsController.GetModel();
 122
 1123        if (limits.bodies < usage.bodies + sceneObject.metrics.bodies)
 124        {
 0125            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0126            return false;
 127        }
 128
 1129        if (limits.entities < usage.entities + sceneObject.metrics.entities)
 130        {
 0131            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0132            return false;
 133        }
 134
 1135        if (limits.materials < usage.materials + sceneObject.metrics.materials)
 136        {
 0137            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0138            return false;
 139        }
 140
 1141        if (limits.meshes < usage.meshes + sceneObject.metrics.meshes)
 142        {
 0143            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0144            return false;
 145        }
 146
 1147        if (limits.textures < usage.textures + sceneObject.metrics.textures)
 148        {
 0149            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0150            return false;
 151        }
 152
 1153        if (limits.triangles < usage.triangles + sceneObject.metrics.triangles)
 154        {
 0155            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0156            return false;
 157        }
 158
 1159        return true;
 160    }
 161
 162    public void CreateErrorOnEntity(BIWEntity entity)
 163    {
 21164        if (errorGameObjects.ContainsKey(entity))
 0165            return;
 166
 21167        GameObject instantiatedError = GameObject.Instantiate(errorPrefab, Vector3.zero, errorPrefab.transform.rotation)
 21168        instantiatedError.transform.SetParent(entity.rootEntity.gameObject.transform, true);
 21169        instantiatedError.transform.localPosition = Vector3.zero;
 170
 21171        var missingAsset = instantiatedError.GetComponent<MissingAsset>();
 21172        missingAsset.Configure(entity);
 173
 21174        errorGameObjects.Add(entity, instantiatedError);
 21175        entity.OnDelete += DeleteErrorOnEntity;
 21176    }
 177
 178    public void DeleteErrorOnEntity(BIWEntity entity)
 179    {
 21180        if (!errorGameObjects.ContainsKey(entity))
 0181            return;
 182
 21183        entity.OnDelete -= DeleteErrorOnEntity;
 21184        GameObject.Destroy(errorGameObjects[entity]);
 21185        errorGameObjects.Remove(entity);
 21186    }
 187
 16188    public void CreateCatalogItem(CatalogItem catalogItem, bool autoSelect = true, bool isFloor = false) { CreateCatalog
 189
 190    public BIWEntity CreateCatalogItem(CatalogItem catalogItem, Vector3 startPosition, bool autoSelect = true, bool isFl
 191    {
 16192        if (catalogItem.IsNFT() && BIWNFTController.i.IsNFTInUse(catalogItem.id))
 0193            return null;
 194
 16195        IsInsideTheLimits(catalogItem);
 196
 197        //Note (Adrian): This is a workaround until the mapping is handle by kernel
 16198        AddSceneMappings(catalogItem);
 199
 16200        Vector3 editionPosition = modeController.GetCurrentEditionPosition();
 201
 16202        BIWEntity entity = entityHandler.CreateEmptyEntity(sceneToEdit, startPosition, editionPosition, false);
 16203        entity.isFloor = isFloor;
 16204        entity.SetRotation(Vector3.zero);
 205
 16206        if (!isFloor)
 8207            CreateLoadingObject(entity);
 208
 33209        entity.rootEntity.OnShapeUpdated += (entity) => onFloorLoadedAction?.Invoke(entity);
 16210        AddShape(catalogItem, entity);
 211
 16212        AddEntityNameComponent(catalogItem, entity);
 213
 16214        AddLockedComponent(entity);
 215
 16216        if (catalogItem.IsSmartItem())
 217        {
 0218            AddSmartItemComponent(entity);
 219        }
 220
 16221        if (catalogItem.IsVoxel())
 0222            entity.isVoxel = true;
 223
 16224        if (autoSelect)
 225        {
 8226            entityHandler.DeselectEntities();
 8227            entityHandler.Select(entity.rootEntity);
 228        }
 229
 16230        entity.rootEntity.gameObject.transform.eulerAngles = Vector3.zero;
 231
 16232        modeController.CreatedEntity(entity);
 233
 16234        lastCatalogItemCreated = catalogItem;
 235
 16236        entityHandler.EntityListChanged();
 16237        entityHandler.NotifyEntityIsCreated(entity.rootEntity);
 16238        OnInputDone?.Invoke();
 16239        OnCatalogItemPlaced?.Invoke();
 16240        return entity;
 241    }
 242
 243    #region LoadingObjects
 244
 2245    public bool ExistsLoadingGameObjectForEntity(string entityId) { return loadingGameObjects.ContainsKey(entityId); }
 246
 247    public void CreateLoadingObject(BIWEntity entity)
 248    {
 10249        if (loadingGameObjects.ContainsKey(entity.rootEntity.entityId))
 1250            return;
 251
 9252        BIWLoadingPlaceHolder loadingPlaceHolder = GameObject.Instantiate(loadingObjectPrefab, entity.rootEntity.gameObj
 9253        loadingGameObjects.Add(entity.rootEntity.entityId, loadingPlaceHolder);
 9254        entity.OnShapeFinishLoading += OnShapeLoadFinish;
 9255    }
 256
 257    private void OnShapeLoadFinish(BIWEntity entity)
 258    {
 0259        entity.OnShapeFinishLoading -= OnShapeLoadFinish;
 0260        RemoveLoadingObject(entity.rootEntity.entityId);
 0261    }
 262
 263    public void RemoveLoadingObject(string entityId)
 264    {
 1265        if (!loadingGameObjects.ContainsKey(entityId))
 0266            return;
 1267        BIWLoadingPlaceHolder loadingPlaceHolder = loadingGameObjects[entityId];
 1268        loadingGameObjects.Remove(entityId);
 1269        loadingPlaceHolder.DestroyAfterAnimation();
 1270    }
 271
 272    public void RemoveLoadingObjectInmediate(string entityId)
 273    {
 6274        if (!loadingGameObjects.ContainsKey(entityId))
 5275            return;
 1276        BIWLoadingPlaceHolder loadingPlaceHolder = loadingGameObjects[entityId];
 1277        loadingGameObjects.Remove(entityId);
 1278        loadingPlaceHolder.Dispose();
 1279    }
 280
 281    #endregion
 282
 283    #region Add Components
 284
 285    private void AddSmartItemComponent(BIWEntity entity)
 286    {
 287        //Note (Adrian): This will disable the smart item component until it is implemented in kernel
 288        //TODO: After the implementation in kernel of smart items, we should eliminate this return
 0289        return;
 290        SmartItemComponent.Model model = new SmartItemComponent.Model();
 291        model.values = new Dictionary<object, object>();
 292
 293        sceneToEdit.EntityComponentCreateOrUpdateWithModel(entity.rootEntity.entityId, CLASS_ID_COMPONENT.SMART_ITEM, mo
 294
 295        //Note (Adrian): We can't wait to set the component 1 frame, so we set it
 296        if (entity.rootEntity.TryGetBaseComponent(CLASS_ID_COMPONENT.SMART_ITEM, out IEntityComponent component))
 297            ((SmartItemComponent) component).UpdateFromModel(model);
 298    }
 299
 300    private void AddEntityNameComponent(CatalogItem catalogItem, BIWEntity entity)
 301    {
 16302        DCLName name = (DCLName) sceneToEdit.SharedComponentCreate(Guid.NewGuid().ToString(), Convert.ToInt32(CLASS_ID.N
 16303        sceneToEdit.SharedComponentAttach(entity.rootEntity.entityId, name.id);
 16304        entityHandler.SetEntityName(entity, catalogItem.name, false);
 16305    }
 306
 307    private void AddLockedComponent(BIWEntity entity)
 308    {
 16309        DCLLockedOnEdit entityLocked = (DCLLockedOnEdit) sceneToEdit.SharedComponentCreate(Guid.NewGuid().ToString(), Co
 16310        if (entity.isFloor)
 8311            entityLocked.SetIsLocked(true);
 312        else
 8313            entityLocked.SetIsLocked(false);
 314
 16315        sceneToEdit.SharedComponentAttach(entity.rootEntity.entityId, entityLocked.id);
 16316    }
 317
 318    private void AddShape(CatalogItem catalogItem, BIWEntity entity)
 319    {
 16320        if (catalogItem.IsNFT())
 321        {
 0322            NFTShape nftShape = (NFTShape) sceneToEdit.SharedComponentCreate(catalogItem.id, Convert.ToInt32(CLASS_ID.NF
 0323            nftShape.model = new NFTShape.Model();
 0324            nftShape.model.color = new Color(0.6404918f, 0.611472f, 0.8584906f);
 0325            nftShape.model.src = catalogItem.model;
 0326            nftShape.model.assetId = catalogItem.id;
 0327            sceneToEdit.SharedComponentAttach(entity.rootEntity.entityId, nftShape.id);
 328
 0329            nftShape.CallWhenReady(entity.ShapeLoadFinish);
 0330        }
 331        else
 332        {
 16333            GLTFShape gltfComponent = (GLTFShape) sceneToEdit.SharedComponentCreate(catalogItem.id, Convert.ToInt32(CLAS
 16334            gltfComponent.model = new LoadableShape.Model();
 16335            gltfComponent.model.src = catalogItem.model;
 16336            gltfComponent.model.assetId = catalogItem.id;
 16337            sceneToEdit.SharedComponentAttach(entity.rootEntity.entityId, gltfComponent.id);
 338
 16339            gltfComponent.CallWhenReady(entity.ShapeLoadFinish);
 340        }
 16341    }
 342
 343    #endregion
 344
 345    private void AddSceneMappings(CatalogItem catalogItem)
 346    {
 16347        LoadParcelScenesMessage.UnityParcelScene data = sceneToEdit.sceneData;
 16348        data.baseUrl = BIWUrlUtils.GetUrlSceneObjectContent();
 16349        if (data.contents == null)
 11350            data.contents = new List<ContentServerUtils.MappingPair>();
 94351        foreach (KeyValuePair<string, string> content in catalogItem.contents)
 352        {
 31353            ContentServerUtils.MappingPair mappingPair = new ContentServerUtils.MappingPair();
 31354            mappingPair.file = content.Key;
 31355            mappingPair.hash = content.Value;
 31356            bool found = false;
 167357            foreach (ContentServerUtils.MappingPair mappingPairToCheck in data.contents)
 358            {
 56359                if (mappingPairToCheck.file == mappingPair.file)
 360                {
 7361                    found = true;
 7362                    break;
 363                }
 364            }
 365
 31366            if (!found)
 24367                data.contents.Add(mappingPair);
 368        }
 369
 16370        DCL.Environment.i.world.sceneController.UpdateParcelScenesExecute(data);
 16371    }
 372
 373    public void CreateLastCatalogItem()
 374    {
 1375        if (lastCatalogItemCreated != null)
 376        {
 1377            if (entityHandler.IsAnyEntitySelected())
 1378                entityHandler.DeselectEntities();
 1379            OnCatalogItemSelected(lastCatalogItemCreated);
 1380            OnInputDone?.Invoke();
 381        }
 0382    }
 383
 384    private void OnCatalogItemSelected(CatalogItem catalogItem)
 385    {
 1386        if (floorHandler.IsCatalogItemFloor(catalogItem))
 387        {
 0388            floorHandler.ChangeFloor(catalogItem);
 0389        }
 390        else
 391        {
 1392            CreateCatalogItem(catalogItem);
 393        }
 1394        string catalogSection = "";
 1395        if (HUDController.i.builderInWorldMainHud != null)
 0396            catalogSection =   HUDController.i.builderInWorldMainHud.GetCatalogSectionSelected().ToString();
 397
 1398        itemsToSendAnalytics.Add(new KeyValuePair<CatalogItem, string>(catalogItem, catalogSection));
 1399    }
 400
 401    private void OnCatalogItemDropped(CatalogItem catalogItem)
 402    {
 0403        OnCatalogItemSelected(catalogItem);
 0404        entityHandler.DeselectEntities();
 0405    }
 406}