< Summary

Class:BIWCreatorController
Assembly:BuilderInWorld
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BuilderMode/Controllers/BIWCreatorController.cs
Covered lines:119
Uncovered lines:68
Coverable lines:187
Total lines:398
Line coverage:63.6% (119 of 187)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
BIWCreatorController()0%110100%
Start()0%2100%
OnDestroy()0%6200%
FrameUpdate()0%6200%
SendAnalytics()0%6200%
Clean()0%330100%
Init()0%2.262060%
IsAnyErrorOnEntities()0%2100%
IsInsideTheLimits(...)0%56.71808.7%
CreateErrorOnEntity(...)0%2.012087.5%
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 class BIWCreatorController : BIWController
 12{
 13    [Header("Design variables")]
 19814    public float secondsToSendAnalytics = 5f;
 15
 16    [Header("Prefab references")]
 17    public BIWModeController biwModeController;
 18
 19    public BIWFloorHandler biwFloorHandler;
 20    public BuilderInWorldEntityHandler builderInWorldEntityHandler;
 21
 22    [FormerlySerializedAs("loadingGO")]
 23    [Header("Project references")]
 24    public GameObject loadingObjectPrefab;
 25    public GameObject errorPrefab;
 26
 27    [SerializeField]
 28    internal InputAction_Trigger toggleCreateLastSceneObjectInputAction;
 29
 30    public Action OnInputDone;
 31
 32    public Action OnCatalogItemPlaced;
 33
 34    private CatalogItem lastCatalogItemCreated;
 35
 36    private InputAction_Trigger.Triggered createLastSceneObjectDelegate;
 37
 19838    private readonly Dictionary<string, BIWLoadingPlaceHolder> loadingGameObjects = new Dictionary<string, BIWLoadingPla
 19839    private readonly Dictionary<DCLBuilderInWorldEntity, GameObject> errorGameObjects = new Dictionary<DCLBuilderInWorld
 40
 19841    private readonly List<KeyValuePair<CatalogItem, string>> itemsToSendAnalytics = new List<KeyValuePair<CatalogItem, s
 42
 43    private float lastAnalyticsSentTimestamp = 0;
 44
 45    private void Start()
 46    {
 047        createLastSceneObjectDelegate = (action) => CreateLastCatalogItem();
 048        toggleCreateLastSceneObjectInputAction.OnTriggered += createLastSceneObjectDelegate;
 049    }
 50
 51    private void OnDestroy()
 52    {
 053        toggleCreateLastSceneObjectInputAction.OnTriggered -= createLastSceneObjectDelegate;
 054        if (HUDController.i.builderInWorldMainHud != null)
 55        {
 056            HUDController.i.builderInWorldMainHud.OnCatalogItemSelected -= OnCatalogItemSelected;
 057            HUDController.i.builderInWorldMainHud.OnCatalogItemDropped -= OnCatalogItemDropped;
 58        }
 59
 060        Clean();
 061    }
 62
 63    protected override void FrameUpdate()
 64    {
 065        base.FrameUpdate();
 066        if (Time.realtimeSinceStartup >= lastAnalyticsSentTimestamp)
 67        {
 068            SendAnalytics();
 069            lastAnalyticsSentTimestamp = Time.realtimeSinceStartup + secondsToSendAnalytics;
 70        }
 071    }
 72
 73    private void SendAnalytics()
 74    {
 075        if (itemsToSendAnalytics.Count == 0)
 076            return;
 77
 078        BIWAnalytics.NewObjectPlacedChunk(itemsToSendAnalytics);
 079        itemsToSendAnalytics.Clear();
 080    }
 81
 82    public void Clean()
 83    {
 6884        foreach (BIWLoadingPlaceHolder placeHolder in loadingGameObjects.Values)
 85        {
 786            placeHolder.Dispose();
 87        }
 88
 6489        foreach (DCLBuilderInWorldEntity entity in errorGameObjects.Keys.ToArray())
 90        {
 591            DeleteErrorOnEntity(entity);
 92        }
 93
 2794        loadingGameObjects.Clear();
 2795        errorGameObjects.Clear();
 2796    }
 97
 98    public override void Init()
 99    {
 18100        base.Init();
 18101        if (HUDController.i.builderInWorldMainHud != null)
 102        {
 0103            HUDController.i.builderInWorldMainHud.OnCatalogItemSelected += OnCatalogItemSelected;
 0104            HUDController.i.builderInWorldMainHud.OnCatalogItemDropped += OnCatalogItemDropped;
 105        }
 18106    }
 107
 0108    public bool IsAnyErrorOnEntities() { return errorGameObjects.Count > 0; }
 109
 110    private bool IsInsideTheLimits(CatalogItem sceneObject)
 111    {
 15112        if (HUDController.i.builderInWorldMainHud == null)
 15113            return false;
 114
 0115        SceneMetricsModel limits = sceneToEdit.metricsController.GetLimits();
 0116        SceneMetricsModel usage = sceneToEdit.metricsController.GetModel();
 117
 0118        if (limits.bodies < usage.bodies + sceneObject.metrics.bodies)
 119        {
 0120            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0121            return false;
 122        }
 123
 0124        if (limits.entities < usage.entities + sceneObject.metrics.entities)
 125        {
 0126            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0127            return false;
 128        }
 129
 0130        if (limits.materials < usage.materials + sceneObject.metrics.materials)
 131        {
 0132            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0133            return false;
 134        }
 135
 0136        if (limits.meshes < usage.meshes + sceneObject.metrics.meshes)
 137        {
 0138            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0139            return false;
 140        }
 141
 0142        if (limits.textures < usage.textures + sceneObject.metrics.textures)
 143        {
 0144            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0145            return false;
 146        }
 147
 0148        if (limits.triangles < usage.triangles + sceneObject.metrics.triangles)
 149        {
 0150            HUDController.i.builderInWorldMainHud.ShowSceneLimitsPassed();
 0151            return false;
 152        }
 153
 0154        return true;
 155    }
 156
 157    public void CreateErrorOnEntity(DCLBuilderInWorldEntity entity)
 158    {
 20159        if (errorGameObjects.ContainsKey(entity))
 0160            return;
 161
 20162        GameObject instantiatedError = Instantiate(errorPrefab, Vector3.zero, errorPrefab.transform.rotation);
 20163        instantiatedError.transform.SetParent(entity.transform, true);
 20164        instantiatedError.transform.localPosition = Vector3.zero;
 165
 20166        errorGameObjects.Add(entity, instantiatedError);
 20167        entity.OnDelete += DeleteErrorOnEntity;
 20168    }
 169
 170    public void DeleteErrorOnEntity(DCLBuilderInWorldEntity entity)
 171    {
 7172        if (!errorGameObjects.ContainsKey(entity))
 0173            return;
 174
 7175        entity.OnDelete -= DeleteErrorOnEntity;
 7176        Destroy(errorGameObjects[entity]);
 7177        errorGameObjects.Remove(entity);
 7178    }
 179
 16180    public void CreateCatalogItem(CatalogItem catalogItem, bool autoSelect = true, bool isFloor = false) { CreateCatalog
 181
 182    public DCLBuilderInWorldEntity CreateCatalogItem(CatalogItem catalogItem, Vector3 startPosition, bool autoSelect = t
 183    {
 15184        if (catalogItem.IsNFT() && BuilderInWorldNFTController.i.IsNFTInUse(catalogItem.id))
 0185            return null;
 186
 15187        IsInsideTheLimits(catalogItem);
 188
 189        //Note (Adrian): This is a workaround until the mapping is handle by kernel
 15190        AddSceneMappings(catalogItem);
 191
 15192        Vector3 editionPosition = biwModeController.GetCurrentEditionPosition();
 193
 15194        DCLBuilderInWorldEntity entity = builderInWorldEntityHandler.CreateEmptyEntity(sceneToEdit, startPosition, editi
 15195        entity.isFloor = isFloor;
 15196        entity.SetRotation(Vector3.zero);
 197
 15198        if (!isFloor)
 8199            CreateLoadingObject(entity);
 200
 31201        entity.rootEntity.OnShapeUpdated += (entity) => onFloorLoadedAction?.Invoke(entity);
 15202        AddShape(catalogItem, entity);
 203
 15204        AddEntityNameComponent(catalogItem, entity);
 205
 15206        AddLockedComponent(entity);
 207
 15208        if (catalogItem.IsSmartItem())
 209        {
 0210            AddSmartItemComponent(entity);
 211        }
 212
 15213        if (catalogItem.IsVoxel())
 0214            entity.isVoxel = true;
 215
 15216        if (autoSelect)
 217        {
 8218            builderInWorldEntityHandler.DeselectEntities();
 8219            builderInWorldEntityHandler.Select(entity.rootEntity);
 220        }
 221
 15222        entity.gameObject.transform.eulerAngles = Vector3.zero;
 223
 15224        biwModeController.CreatedEntity(entity);
 225
 15226        lastCatalogItemCreated = catalogItem;
 227
 15228        builderInWorldEntityHandler.EntityListChanged();
 15229        builderInWorldEntityHandler.NotifyEntityIsCreated(entity.rootEntity);
 15230        OnInputDone?.Invoke();
 15231        OnCatalogItemPlaced?.Invoke();
 15232        return entity;
 233    }
 234
 235    #region LoadingObjects
 236
 2237    public bool ExistsLoadingGameObjectForEntity(string entityId) { return loadingGameObjects.ContainsKey(entityId); }
 238
 239    public void CreateLoadingObject(DCLBuilderInWorldEntity entity)
 240    {
 10241        if (loadingGameObjects.ContainsKey(entity.rootEntity.entityId))
 1242            return;
 243
 9244        BIWLoadingPlaceHolder loadingPlaceHolder = GameObject.Instantiate(loadingObjectPrefab, entity.gameObject.transfo
 9245        loadingGameObjects.Add(entity.rootEntity.entityId, loadingPlaceHolder);
 9246        entity.OnShapeFinishLoading += OnShapeLoadFinish;
 9247    }
 248
 249    private void OnShapeLoadFinish(DCLBuilderInWorldEntity entity)
 250    {
 0251        entity.OnShapeFinishLoading -= OnShapeLoadFinish;
 0252        RemoveLoadingObject(entity.rootEntity.entityId);
 0253    }
 254
 255    public void RemoveLoadingObject(string entityId)
 256    {
 1257        if (!loadingGameObjects.ContainsKey(entityId))
 0258            return;
 1259        BIWLoadingPlaceHolder loadingPlaceHolder = loadingGameObjects[entityId];
 1260        loadingGameObjects.Remove(entityId);
 1261        loadingPlaceHolder.DestroyAfterAnimation();
 1262    }
 263
 264    public void RemoveLoadingObjectInmediate(string entityId)
 265    {
 8266        if (!loadingGameObjects.ContainsKey(entityId))
 7267            return;
 1268        BIWLoadingPlaceHolder loadingPlaceHolder = loadingGameObjects[entityId];
 1269        loadingGameObjects.Remove(entityId);
 1270        loadingPlaceHolder.Dispose();
 1271    }
 272
 273    #endregion
 274
 275    #region Add Components
 276
 277    private void AddSmartItemComponent(DCLBuilderInWorldEntity entity)
 278    {
 279        //Note (Adrian): This will disable the smart item component until it is implemented in kernel
 280        //TODO: After the implementation in kernel of smart items, we should eliminate this return
 0281        return;
 282        SmartItemComponent.Model model = new SmartItemComponent.Model();
 283        model.values = new Dictionary<object, object>();
 284
 285        sceneToEdit.EntityComponentCreateOrUpdateWithModel(entity.rootEntity.entityId, CLASS_ID_COMPONENT.SMART_ITEM, mo
 286
 287        //Note (Adrian): We can't wait to set the component 1 frame, so we set it
 288        if (entity.rootEntity.TryGetBaseComponent(CLASS_ID_COMPONENT.SMART_ITEM, out IEntityComponent component))
 289            ((SmartItemComponent) component).UpdateFromModel(model);
 290    }
 291
 292    private void AddEntityNameComponent(CatalogItem catalogItem, DCLBuilderInWorldEntity entity)
 293    {
 15294        DCLName name = (DCLName) sceneToEdit.SharedComponentCreate(Guid.NewGuid().ToString(), Convert.ToInt32(CLASS_ID.N
 15295        sceneToEdit.SharedComponentAttach(entity.rootEntity.entityId, name.id);
 15296        builderInWorldEntityHandler.SetEntityName(entity, catalogItem.name, false);
 15297    }
 298
 299    private void AddLockedComponent(DCLBuilderInWorldEntity entity)
 300    {
 15301        DCLLockedOnEdit entityLocked = (DCLLockedOnEdit) sceneToEdit.SharedComponentCreate(Guid.NewGuid().ToString(), Co
 15302        if (entity.isFloor)
 7303            entityLocked.SetIsLocked(true);
 304        else
 8305            entityLocked.SetIsLocked(false);
 306
 15307        sceneToEdit.SharedComponentAttach(entity.rootEntity.entityId, entityLocked.id);
 15308    }
 309
 310    private void AddShape(CatalogItem catalogItem, DCLBuilderInWorldEntity entity)
 311    {
 15312        if (catalogItem.IsNFT())
 313        {
 0314            NFTShape nftShape = (NFTShape) sceneToEdit.SharedComponentCreate(catalogItem.id, Convert.ToInt32(CLASS_ID.NF
 0315            nftShape.model = new NFTShape.Model();
 0316            nftShape.model.color = new Color(0.6404918f, 0.611472f, 0.8584906f);
 0317            nftShape.model.src = catalogItem.model;
 0318            nftShape.model.assetId = catalogItem.id;
 0319            sceneToEdit.SharedComponentAttach(entity.rootEntity.entityId, nftShape.id);
 320
 0321            nftShape.CallWhenReady(entity.ShapeLoadFinish);
 0322        }
 323        else
 324        {
 15325            GLTFShape gltfComponent = (GLTFShape) sceneToEdit.SharedComponentCreate(catalogItem.id, Convert.ToInt32(CLAS
 15326            gltfComponent.model = new LoadableShape.Model();
 15327            gltfComponent.model.src = catalogItem.model;
 15328            gltfComponent.model.assetId = catalogItem.id;
 15329            sceneToEdit.SharedComponentAttach(entity.rootEntity.entityId, gltfComponent.id);
 330
 15331            gltfComponent.CallWhenReady(entity.ShapeLoadFinish);
 332        }
 15333    }
 334
 335    #endregion
 336
 337    private void AddSceneMappings(CatalogItem catalogItem)
 338    {
 15339        LoadParcelScenesMessage.UnityParcelScene data = sceneToEdit.sceneData;
 15340        data.baseUrl = BIWUrlUtils.GetUrlSceneObjectContent();
 15341        if (data.contents == null)
 10342            data.contents = new List<ContentServerUtils.MappingPair>();
 88343        foreach (KeyValuePair<string, string> content in catalogItem.contents)
 344        {
 29345            ContentServerUtils.MappingPair mappingPair = new ContentServerUtils.MappingPair();
 29346            mappingPair.file = content.Key;
 29347            mappingPair.hash = content.Value;
 29348            bool found = false;
 161349            foreach (ContentServerUtils.MappingPair mappingPairToCheck in data.contents)
 350            {
 55351                if (mappingPairToCheck.file == mappingPair.file)
 352                {
 7353                    found = true;
 7354                    break;
 355                }
 356            }
 357
 29358            if (!found)
 22359                data.contents.Add(mappingPair);
 360        }
 361
 15362        DCL.Environment.i.world.sceneController.UpdateParcelScenesExecute(data);
 15363    }
 364
 365    public void CreateLastCatalogItem()
 366    {
 1367        if (lastCatalogItemCreated != null)
 368        {
 1369            if (builderInWorldEntityHandler.IsAnyEntitySelected())
 1370                builderInWorldEntityHandler.DeselectEntities();
 1371            OnCatalogItemSelected(lastCatalogItemCreated);
 1372            OnInputDone?.Invoke();
 373        }
 0374    }
 375
 376    private void OnCatalogItemSelected(CatalogItem catalogItem)
 377    {
 1378        if (biwFloorHandler.IsCatalogItemFloor(catalogItem))
 379        {
 0380            biwFloorHandler.ChangeFloor(catalogItem);
 0381        }
 382        else
 383        {
 1384            CreateCatalogItem(catalogItem);
 385        }
 1386        string catalogSection = "";
 1387        if (HUDController.i.builderInWorldMainHud != null)
 0388            catalogSection =   HUDController.i.builderInWorldMainHud.GetCatalogSectionSelected().ToString();
 389
 1390        itemsToSendAnalytics.Add(new KeyValuePair<CatalogItem, string>(catalogItem, catalogSection));
 1391    }
 392
 393    private void OnCatalogItemDropped(CatalogItem catalogItem)
 394    {
 0395        OnCatalogItemSelected(catalogItem);
 0396        builderInWorldEntityHandler.DeselectEntities();
 0397    }
 398}