From 133ac0662a57f8c35505fbd8327ba84b101aa705 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Aug 2018 16:06:08 -0700 Subject: [PATCH 01/11] Move entity list qml to scripts dir --- scripts/system/libraries/EditEntityList.qml | 11 +++++++++++ scripts/system/libraries/entityList.js | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 scripts/system/libraries/EditEntityList.qml diff --git a/scripts/system/libraries/EditEntityList.qml b/scripts/system/libraries/EditEntityList.qml new file mode 100644 index 0000000000..d8099cb670 --- /dev/null +++ b/scripts/system/libraries/EditEntityList.qml @@ -0,0 +1,11 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtWebChannel 1.0 +import QtGraphicalEffects 1.0 +import "qrc:///qml/controls" as HifiControls + +HifiControls.WebView { + id: entityListToolWebView + url: Qt.resolvedUrl("../html/entityList.html") + enabled: true +} diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 678b2eeb0b..cd0c712148 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -20,7 +20,7 @@ EntityListTool = function(shouldUseEditTabletApp) { var ENTITY_LIST_WIDTH = 495; var MAX_DEFAULT_CREATE_TOOLS_HEIGHT = 778; var entityListWindow = new CreateWindow( - Script.resourcesPath() + "qml/hifi/tablet/EditEntityList.qml", + Script.resolvePath("EditEntityList.qml"), 'Entity List', 'com.highfidelity.create.entityListWindow', function () { From f6ac755bae0a6ce47b49d6445afb07fabefa40de Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Aug 2018 08:47:37 -0700 Subject: [PATCH 02/11] Add profiling to edit.js fof the entity list --- scripts/system/html/js/entityList.js | 54 ++++++---- scripts/system/libraries/entityList.js | 130 ++++++++++++++----------- 2 files changed, 109 insertions(+), 75 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 5cd5f6d610..779100affb 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -23,6 +23,18 @@ const DELETE = 46; // Key code for the delete key. const KEY_P = 80; // Key code for letter p used for Parenting hotkey. const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities. +var profileIndent = ''; +PROFILE = function(name, fn, args) { + EventBridge.emitWebEvent("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); + var previousIndent = profileIndent; + profileIndent += ' '; + var before = Date.now(); + fn.apply(this, args); + var delta = Date.now() - before; + profileIndent = previousIndent; + EventBridge.emitWebEvent("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); +} + debugPrint = function (message) { console.log(message); }; @@ -363,27 +375,29 @@ function loaded() { refreshEntities(); } } else if (data.type === "update" && data.selectedIDs !== undefined) { - var newEntities = data.entities; - if (newEntities && newEntities.length == 0) { - elNoEntitiesMessage.style.display = "block"; - elFooter.firstChild.nodeValue = "0 entities found"; - } else if (newEntities) { - elNoEntitiesMessage.style.display = "none"; - for (var i = 0; i < newEntities.length; i++) { - var id = newEntities[i].id; - addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url, - newEntities[i].locked ? LOCKED_GLYPH : null, - newEntities[i].visible ? VISIBLE_GLYPH : null, - newEntities[i].verticesCount, newEntities[i].texturesCount, newEntities[i].texturesSize, - newEntities[i].hasTransparent ? TRANSPARENCY_GLYPH : null, - newEntities[i].isBaked ? BAKED_GLYPH : null, - newEntities[i].drawCalls, - newEntities[i].hasScript ? SCRIPT_GLYPH : null); + PROFILE("update", function() { + var newEntities = data.entities; + if (newEntities && newEntities.length == 0) { + elNoEntitiesMessage.style.display = "block"; + elFooter.firstChild.nodeValue = "0 entities found"; + } else if (newEntities) { + elNoEntitiesMessage.style.display = "none"; + for (var i = 0; i < newEntities.length; i++) { + var id = newEntities[i].id; + addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url, + newEntities[i].locked ? LOCKED_GLYPH : null, + newEntities[i].visible ? VISIBLE_GLYPH : null, + newEntities[i].verticesCount, newEntities[i].texturesCount, newEntities[i].texturesSize, + newEntities[i].hasTransparent ? TRANSPARENCY_GLYPH : null, + newEntities[i].isBaked ? BAKED_GLYPH : null, + newEntities[i].drawCalls, + newEntities[i].hasScript ? SCRIPT_GLYPH : null); + } + updateSelectedEntities(data.selectedIDs); + scheduleRefreshEntityList(); + resize(); } - updateSelectedEntities(data.selectedIDs); - scheduleRefreshEntityList(); - resize(); - } + }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { removeEntities(data.deletedIDs); updateSelectedEntities(data.selectedIDs); diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index cd0c712148..b52a31760f 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -11,6 +11,18 @@ /* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages, cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible */ +var profileIndent = ''; +PROFILE = function(name, fn, args) { + console.log("PROFILE-Script " + profileIndent + "(" + name + ") Begin"); + var previousIndent = profileIndent; + profileIndent += ' '; + var before = Date.now(); + fn.apply(this, args); + var delta = Date.now() - before; + profileIndent = previousIndent; + console.log("PROFILE-Script " + profileIndent + "(" + name + ") End " + delta + "ms"); +} + EntityListTool = function(shouldUseEditTabletApp) { var that = {}; @@ -66,11 +78,16 @@ EntityListTool = function(shouldUseEditTabletApp) { that.setVisible(false); function emitJSONScriptEvent(data) { - var dataString = JSON.stringify(data); - webView.emitScriptEvent(dataString); - if (entityListWindow.window) { - entityListWindow.window.emitScriptEvent(dataString); - } + var dataString; + PROFILE("Script-JSON.stringify", function() { + dataString = JSON.stringify(data); + }); + PROFILE("Script-emitScriptEvent", function() { + webView.emitScriptEvent(dataString); + if (entityListWindow.window) { + entityListWindow.window.emitScriptEvent(dataString); + } + }); } that.toggleVisible = function() { @@ -116,59 +133,61 @@ EntityListTool = function(shouldUseEditTabletApp) { } that.sendUpdate = function() { - var entities = []; + PROFILE('Script-sendUpdate', function() { + var entities = []; - var ids; - if (filterInView) { - ids = Entities.findEntitiesInFrustum(Camera.frustum); - } else { - ids = Entities.findEntities(MyAvatar.position, searchRadius); - } - - var cameraPosition = Camera.position; - for (var i = 0; i < ids.length; i++) { - var id = ids[i]; - var properties = Entities.getEntityProperties(id); - - if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) { - var url = ""; - if (properties.type === "Model") { - url = properties.modelURL; - } else if (properties.type === "Material") { - url = properties.materialURL; - } - entities.push({ - id: id, - name: properties.name, - type: properties.type, - url: url, - locked: properties.locked, - visible: properties.visible, - verticesCount: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.verticesCount) : ""), - texturesCount: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.texturesCount) : ""), - texturesSize: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.texturesSize) : ""), - hasTransparent: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.hasTransparent) : ""), - isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false, - drawCalls: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.drawCalls) : ""), - hasScript: properties.script !== "" - }); + var ids; + if (filterInView) { + ids = Entities.findEntitiesInFrustum(Camera.frustum); + } else { + ids = Entities.findEntities(MyAvatar.position, searchRadius); } - } - var selectedIDs = []; - for (var j = 0; j < selectionManager.selections.length; j++) { - selectedIDs.push(selectionManager.selections[j]); - } + var cameraPosition = Camera.position; + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + var properties = Entities.getEntityProperties(id); - emitJSONScriptEvent({ - type: "update", - entities: entities, - selectedIDs: selectedIDs, + if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) { + var url = ""; + if (properties.type === "Model") { + url = properties.modelURL; + } else if (properties.type === "Material") { + url = properties.materialURL; + } + entities.push({ + id: id, + name: properties.name, + type: properties.type, + url: url, + locked: properties.locked, + visible: properties.visible, + verticesCount: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.verticesCount) : ""), + texturesCount: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.texturesCount) : ""), + texturesSize: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.texturesSize) : ""), + hasTransparent: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.hasTransparent) : ""), + isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false, + drawCalls: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.drawCalls) : ""), + hasScript: properties.script !== "" + }); + } + } + + var selectedIDs = []; + for (var j = 0; j < selectionManager.selections.length; j++) { + selectedIDs.push(selectionManager.selections[j]); + } + + emitJSONScriptEvent({ + type: "update", + entities: entities, + selectedIDs: selectedIDs, + }); }); }; @@ -186,7 +205,8 @@ EntityListTool = function(shouldUseEditTabletApp) { try { data = JSON.parse(data); } catch(e) { - print("entityList.js: Error parsing JSON: " + e.name + " data " + data); + console.log(data); + //print("entityList.js: Error parsing JSON: " + e.name + " data " + data); return; } From f2cc2f148597ecaff79ab5ab85c920fde9ad1a11 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Aug 2018 13:21:00 -0700 Subject: [PATCH 03/11] Update entity list UI to be updated in a single batch --- scripts/system/html/entityList.html | 3 +- scripts/system/html/js/entityList.js | 127 ++++++++++++++++++--------- 2 files changed, 86 insertions(+), 44 deletions(-) diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 7906a3c97f..0802c23b71 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -10,8 +10,9 @@ - + + diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 779100affb..17a1b26bbf 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -23,16 +23,22 @@ const DELETE = 46; // Key code for the delete key. const KEY_P = 80; // Key code for letter p used for Parenting hotkey. const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities. +log = function(msg) { + EventBridge.emitWebEvent(msg); +} + var profileIndent = ''; PROFILE = function(name, fn, args) { - EventBridge.emitWebEvent("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); + log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); + console.log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' '; var before = Date.now(); fn.apply(this, args); var delta = Date.now() - before; profileIndent = previousIndent; - EventBridge.emitWebEvent("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); + log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); + console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); } debugPrint = function (message) { @@ -168,44 +174,89 @@ function loaded() { return number ? number : ""; } - function addEntity(id, name, type, url, locked, visible, verticesCount, texturesCount, texturesSize, hasTransparent, - isBaked, drawCalls, hasScript) { + function getFilename(url) { + let urlParts = url.split('/'); + return urlParts[urlParts.length - 1]; + } - var urlParts = url.split('/'); - var filename = urlParts[urlParts.length - 1]; + //function addEntity( + //id, name, type, url, locked, visible, verticesCount, + //texturesCount, texturesSize, hasTransparent, + //isBaked, drawCalls, hasScript) { + function addEntities(entityData) { + const IMAGE_MODEL_NAME = 'default-image-model.fbx'; - var IMAGE_MODEL_NAME = 'default-image-model.fbx'; + let newEntities = entityData.filter(function(entity) { + if (entity.id in entities) { + var item = entities[entity.id].item; + item.values({ + name: entity.name, + url: getFilename(entity.url), + locked: entity.locked, + visible: entity.visible + }); + return false; + } + return true; + }); - if (filename === IMAGE_MODEL_NAME) { - type = "Image"; + if (newEntities.length === 0) { + return; } - if (entities[id] === undefined) { - entityList.add([{ - id: id, name: name, type: type, url: filename, locked: locked, visible: visible, - verticesCount: displayIfNonZero(verticesCount), texturesCount: displayIfNonZero(texturesCount), - texturesSize: decimalMegabytes(texturesSize), hasTransparent: hasTransparent, - isBaked: isBaked, drawCalls: displayIfNonZero(drawCalls), hasScript: hasScript - }], + newEntities = newEntities.map(function(entity) { + let type = entity.type; + let filename = getFilename(entity.url); + if (filename === IMAGE_MODEL_NAME) { + type = "Image"; + } + return { + id: entity.id, + name: entity.name, + type: type, + url: filename, + fullUrl: entity.url, + locked: entity.locked ? LOCKED_GLYPH : null, + visible: entity.visible ? VISIBLE_GLYPH : null, + verticesCount: displayIfNonZero(entity.verticesCount), + texturesCount: displayIfNonZero(entity.texturesCount), + texturesSize: decimalMegabytes(entity.texturesSize), + hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, + isBaked: entity.isBaked ? BAKED_GLYPH : null, + drawCalls: displayIfNonZero(entity.drawCalls), + hasScript: entity.hasScript ? SCRIPT_GLYPH : null + } + }); + //newEntities = newEntities.splice(newEntities.length - 10); + console.log("Adding: " + newEntities.length); + + let size = 2000; + let sets = Math.ceil(newEntities.length / size); + for (let i = 0; i < sets; i++) { + + console.log(Date.now(), "Adding", i * size, (i + 1) * size); + entityList.add(newEntities.splice(i * size, (i + 1) * size), function (items) { - var currentElement = items[0].elm; - var id = items[0]._values.id; - entities[id] = { - id: id, - name: name, - el: currentElement, - item: items[0] - }; - currentElement.setAttribute('id', 'entity_' + id); - currentElement.setAttribute('title', url); - currentElement.dataset.entityId = id; - currentElement.onclick = onRowClicked; - currentElement.ondblclick = onRowDoubleClicked; + console.log(Date.now(), "added: " + items.length); + items.forEach(function(item) { + var currentElement = item.elm; + var values = item._values; + + entities[values.id] = { + id: values.id, + name: values.name, + el: currentElement, + item: item + }; + currentElement.setAttribute('id', 'entity_' + values.id); + currentElement.setAttribute('title', values.fullUrl); + currentElement.dataset.entityId = values.id; + currentElement.onclick = onRowClicked; + currentElement.ondblclick = onRowDoubleClicked; + }); }); - } else { - var item = entities[id].item; - item.values({ name: name, url: filename, locked: locked, visible: visible }); } + console.log(Date.now(), "DONE"); } function removeEntities(deletedIDs) { @@ -382,17 +433,7 @@ function loaded() { elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { elNoEntitiesMessage.style.display = "none"; - for (var i = 0; i < newEntities.length; i++) { - var id = newEntities[i].id; - addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url, - newEntities[i].locked ? LOCKED_GLYPH : null, - newEntities[i].visible ? VISIBLE_GLYPH : null, - newEntities[i].verticesCount, newEntities[i].texturesCount, newEntities[i].texturesSize, - newEntities[i].hasTransparent ? TRANSPARENCY_GLYPH : null, - newEntities[i].isBaked ? BAKED_GLYPH : null, - newEntities[i].drawCalls, - newEntities[i].hasScript ? SCRIPT_GLYPH : null); - } + addEntities(newEntities); updateSelectedEntities(data.selectedIDs); scheduleRefreshEntityList(); resize(); From a9a5bf1e972cf654e34d4949348720ad9b9e28b8 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Aug 2018 13:11:22 -0700 Subject: [PATCH 04/11] Replace entity list UI with custom, brute-force solution --- scripts/system/html/js/entityList.js | 243 ++++++++++++++----------- scripts/system/libraries/entityList.js | 4 + 2 files changed, 140 insertions(+), 107 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 17a1b26bbf..c30aac2a7f 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -6,12 +6,8 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -var entities = {}; -var selectedEntities = []; -var currentSortColumn = 'type'; -var currentSortOrder = 'des'; -var entityList = null; -var refreshEntityListTimer = null; +const ASCENDING_SORT = 1; +const DESCENDING_SORT = -1; const ASCENDING_STRING = '▴'; const DESCENDING_STRING = '▾'; const LOCKED_GLYPH = ""; @@ -23,6 +19,30 @@ const DELETE = 46; // Key code for the delete key. const KEY_P = 80; // Key code for letter p used for Parenting hotkey. const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities. +const COMPARE_ASCENDING = function(a, b) { + let va = a[currentSortColumn]; + let vb = b[currentSortColumn]; + + if (va < vb) { + return -1; + } else if (va > vb) { + return 1; + } + return 0; +} +const COMPARE_DESCENDING = function(a, b) { + return COMPARE_ASCENDING(b, a); +} + +var entities = {}; +var entityCount = 0; +// Raw entity data sent from script +let entityData = [] +var selectedEntities = []; +var currentSortColumn = 'type'; +var currentSortOrder = ASCENDING_SORT; +var refreshEntityListTimer = null; + log = function(msg) { EventBridge.emitWebEvent(msg); } @@ -47,8 +67,6 @@ debugPrint = function (message) { function loaded() { openEventBridge(function() { - entityList = new List('entity-list', { valueNames: ['name', 'type', 'url', 'locked', 'visible'], page: MAX_ITEMS}); - entityList.clear(); elEntityTable = document.getElementById("entity-table"); elEntityTableBody = document.getElementById("entity-table-body"); elRefresh = document.getElementById("refresh"); @@ -107,10 +125,12 @@ function loaded() { }; function onRowClicked(clickEvent) { - var id = this.dataset.entityId; - var selection = [this.dataset.entityId]; + let entityID = this.dataset.entityID; + console.log("CLICKED", entityID, this); + //return; + var selection = [entityID]; if (clickEvent.ctrlKey) { - var selectedIndex = selectedEntities.indexOf(id); + var selectedIndex = selectedEntities.indexOf(entityID); if (selectedIndex >= 0) { selection = selectedEntities; selection.splice(selectedIndex, 1) @@ -121,7 +141,7 @@ function loaded() { var previousItemFound = -1; var clickedItemFound = -1; for (var entity in entityList.visibleItems) { - if (clickedItemFound === -1 && this.dataset.entityId == entityList.visibleItems[entity].values().id) { + if (clickedItemFound === -1 && entityID == entityList.visibleItems[entity].values().id) { clickedItemFound = entity; } else if(previousItemFound === -1 && selectedEntities[0] == entityList.visibleItems[entity].values().id) { previousItemFound = entity; @@ -143,6 +163,12 @@ function loaded() { } } + selectedEntities.forEach(function(entityID) { + if (selection.indexOf(entityID) === -1) { + entities[entityID].el.className = ''; + } + }); + selectedEntities = selection; this.className = 'selected'; @@ -160,7 +186,7 @@ function loaded() { EventBridge.emitWebEvent(JSON.stringify({ type: "selectionUpdate", focus: true, - entityIds: [this.dataset.entityId], + entityIds: [this.dataset.entityID], })); } @@ -179,90 +205,88 @@ function loaded() { return urlParts[urlParts.length - 1]; } - //function addEntity( - //id, name, type, url, locked, visible, verticesCount, - //texturesCount, texturesSize, hasTransparent, - //isBaked, drawCalls, hasScript) { - function addEntities(entityData) { + function refreshEntityList() { const IMAGE_MODEL_NAME = 'default-image-model.fbx'; - let newEntities = entityData.filter(function(entity) { - if (entity.id in entities) { - var item = entities[entity.id].item; - item.values({ + PROFILE("sort", function() { + let cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; + console.log("Doing sort", currentSortColumn, currentSortOrder); + entityData.sort(cmp); + }); + + entities = {}; + + let newEntities; + PROFILE("map-data", function() { + newEntities = entityData.map(function(entity) { + let type = entity.type; + let filename = getFilename(entity.url); + if (filename === IMAGE_MODEL_NAME) { + type = "Image"; + } + return { + id: entity.id, name: entity.name, - url: getFilename(entity.url), - locked: entity.locked, - visible: entity.visible - }); - return false; - } - return true; - }); - - if (newEntities.length === 0) { - return; - } - - newEntities = newEntities.map(function(entity) { - let type = entity.type; - let filename = getFilename(entity.url); - if (filename === IMAGE_MODEL_NAME) { - type = "Image"; - } - return { - id: entity.id, - name: entity.name, - type: type, - url: filename, - fullUrl: entity.url, - locked: entity.locked ? LOCKED_GLYPH : null, - visible: entity.visible ? VISIBLE_GLYPH : null, - verticesCount: displayIfNonZero(entity.verticesCount), - texturesCount: displayIfNonZero(entity.texturesCount), - texturesSize: decimalMegabytes(entity.texturesSize), - hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, - isBaked: entity.isBaked ? BAKED_GLYPH : null, - drawCalls: displayIfNonZero(entity.drawCalls), - hasScript: entity.hasScript ? SCRIPT_GLYPH : null - } - }); - //newEntities = newEntities.splice(newEntities.length - 10); - console.log("Adding: " + newEntities.length); - - let size = 2000; - let sets = Math.ceil(newEntities.length / size); - for (let i = 0; i < sets; i++) { - - console.log(Date.now(), "Adding", i * size, (i + 1) * size); - entityList.add(newEntities.splice(i * size, (i + 1) * size), - function (items) { - console.log(Date.now(), "added: " + items.length); - items.forEach(function(item) { - var currentElement = item.elm; - var values = item._values; - - entities[values.id] = { - id: values.id, - name: values.name, - el: currentElement, - item: item - }; - currentElement.setAttribute('id', 'entity_' + values.id); - currentElement.setAttribute('title', values.fullUrl); - currentElement.dataset.entityId = values.id; - currentElement.onclick = onRowClicked; - currentElement.ondblclick = onRowDoubleClicked; - }); + type: type, + url: filename, + fullUrl: entity.url, + locked: entity.locked ? LOCKED_GLYPH : null, + visible: entity.visible ? VISIBLE_GLYPH : null, + verticesCount: displayIfNonZero(entity.verticesCount), + texturesCount: displayIfNonZero(entity.texturesCount), + texturesSize: decimalMegabytes(entity.texturesSize), + hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, + isBaked: entity.isBaked ? BAKED_GLYPH : null, + drawCalls: displayIfNonZero(entity.drawCalls), + hasScript: entity.hasScript ? SCRIPT_GLYPH : null + } }); - } - console.log(Date.now(), "DONE"); + }); + + console.log("Adding: " + newEntities.length); + + elEntityTableBody.innerHTML = ''; + + entities = {}; + + PROFILE("update-dom", function() { + newEntities.forEach(function(entity) { + let row = document.createElement('tr'); + row.dataset.entityID = entity.id; + row.attributes.title = entity.fullUrl; + function addColumn(cls, text) { + let col = document.createElement('td'); + col.className = cls; + col.innerText = text; + row.append(col); + } + addColumn('type', entity.type); + addColumn('name', entity.name); + addColumn('url', entity.url); + addColumn('locked glyph', entity.locked); + addColumn('visible glyph', entity.visible); + addColumn('verticesCount', entity.verticesCount); + addColumn('texturesCount', entity.texturesCount); + addColumn('texturesSize', entity.texturesSize); + addColumn('hasTransparent glyph', entity.hasTransparent); + addColumn('isBaked glyph', entity.isBaked); + addColumn('drawCalls', entity.drawCalls); + addColumn('hasScript glyph', entity.hasScript); + elEntityTableBody.append(row); + row.addEventListener('click', onRowClicked); + row.addEventListener('dblclick', onRowDoubleClicked); + entities[entity.id] = { el: row }; + }); + + }); } function removeEntities(deletedIDs) { + return; for (i = 0, length = deletedIDs.length; i < length; i++) { - delete entities[deletedIDs[i]]; - entityList.remove("id", deletedIDs[i]); + let id = deletedIDs[i]; + entities[id].el.remove(); + delete entities[id]; } } @@ -276,7 +300,6 @@ function loaded() { function clearEntities() { entities = {}; - entityList.clear(); refreshFooter(); } @@ -295,15 +318,19 @@ function loaded() { hasScript: document.querySelector('#entity-hasScript .sort-order'), } function setSortColumn(column) { - if (currentSortColumn == column) { - currentSortOrder = currentSortOrder == "asc" ? "desc" : "asc"; - } else { - elSortOrder[currentSortColumn].innerHTML = ""; - currentSortColumn = column; - currentSortOrder = "asc"; - } - elSortOrder[column].innerHTML = currentSortOrder == "asc" ? ASCENDING_STRING : DESCENDING_STRING; - entityList.sort(currentSortColumn, { order: currentSortOrder }); + PROFILE("set-sort-column", function() { + if (currentSortColumn == column) { + currentSortOrder *= -1; + } else { + elSortOrder[currentSortColumn].innerHTML = ""; + currentSortColumn = column; + currentSortOrder = ASCENDING_SORT; + } + elSortOrder[column].innerHTML = currentSortOrder == ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; + + //entityList.sort(currentSortColumn, { order: currentSortOrder }); + refreshEntityList(); + }); } setSortColumn('type'); @@ -313,21 +340,22 @@ function loaded() { } function refreshFooter() { + return; if (selectedEntities.length > 1) { elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected"; } else if (selectedEntities.length === 1) { elFooter.firstChild.nodeValue = "1 entity selected"; - } else if (entityList.visibleItems.length === 1) { + } else if (entityCount === 1) { elFooter.firstChild.nodeValue = "1 entity found"; } else { - elFooter.firstChild.nodeValue = entityList.visibleItems.length + " entities found"; + elFooter.firstChild.nodeValue = entityCount + " entities found"; } } function refreshEntityListObject() { refreshEntityListTimer = null; - entityList.sort(currentSortColumn, { order: currentSortOrder }); - entityList.search(elFilter.value); + //entityList.sort(currentSortColumn, { order: currentSortOrder }); + //entityList.search(elFilter.value); refreshFooter(); } @@ -433,10 +461,11 @@ function loaded() { elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { elNoEntitiesMessage.style.display = "none"; - addEntities(newEntities); - updateSelectedEntities(data.selectedIDs); - scheduleRefreshEntityList(); - resize(); + entityData = newEntities; + refreshEntityList(); + //updateSelectedEntities(data.selectedIDs); + //scheduleRefreshEntityList(); + //resize(); } }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index b52a31760f..1651eaedcc 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -137,13 +137,16 @@ EntityListTool = function(shouldUseEditTabletApp) { var entities = []; var ids; + PROFILE("findEntities", function() { if (filterInView) { ids = Entities.findEntitiesInFrustum(Camera.frustum); } else { ids = Entities.findEntities(MyAvatar.position, searchRadius); } + }); var cameraPosition = Camera.position; + PROFILE("getProperties", function() { for (var i = 0; i < ids.length; i++) { var id = ids[i]; var properties = Entities.getEntityProperties(id); @@ -177,6 +180,7 @@ EntityListTool = function(shouldUseEditTabletApp) { }); } } + }); var selectedIDs = []; for (var j = 0; j < selectionManager.selections.length; j++) { From 739530cb85c75344e18732cd6a057cfe6b40191f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Aug 2018 09:30:19 -0700 Subject: [PATCH 05/11] Limit Entity List to only getting the properties it needs --- scripts/system/libraries/entityList.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 1651eaedcc..3900260d0c 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -82,6 +82,7 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("Script-JSON.stringify", function() { dataString = JSON.stringify(data); }); + console.log("Length: ", dataString.length, data.type); PROFILE("Script-emitScriptEvent", function() { webView.emitScriptEvent(dataString); if (entityListWindow.window) { @@ -149,7 +150,9 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("getProperties", function() { for (var i = 0; i < ids.length; i++) { var id = ids[i]; - var properties = Entities.getEntityProperties(id); + //var properties = Entities.getEntityProperties(id); + var properties = Entities.getEntityProperties(id, ['name', 'type', 'locked', + 'visible', 'renderInfo', 'type', 'modelURL', 'materialURL', 'script']); if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) { var url = ""; From 335f66d165f2c533def5f10e17ca17f3395117a0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 5 Sep 2018 14:28:57 -0700 Subject: [PATCH 06/11] Add filtering support to entity list --- scripts/system/html/entityList.html | 1 + scripts/system/html/js/entityList.js | 237 +++++++++++++++------------ 2 files changed, 131 insertions(+), 107 deletions(-) diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 0802c23b71..cb95dffc5f 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -9,6 +9,7 @@ --> + diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index c30aac2a7f..ebf31d5d36 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -34,22 +34,24 @@ const COMPARE_DESCENDING = function(a, b) { return COMPARE_ASCENDING(b, a); } -var entities = {}; -var entityCount = 0; -// Raw entity data sent from script -let entityData = [] +//console.log = function() { }; + + + +// List of all entities +let entities = [] +// List of all entities, indexed by Entity ID +var entitiesByID = {}; +// The filtered and sorted list of entities +var visibleEntities = []; + var selectedEntities = []; var currentSortColumn = 'type'; var currentSortOrder = ASCENDING_SORT; -var refreshEntityListTimer = null; - -log = function(msg) { - EventBridge.emitWebEvent(msg); -} +const ENABLE_PROFILING = true; var profileIndent = ''; -PROFILE = function(name, fn, args) { - log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); +const PROFILE = !ENABLE_PROFILING ? function() { } : function(name, fn, args) { console.log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' '; @@ -57,9 +59,8 @@ PROFILE = function(name, fn, args) { fn.apply(this, args); var delta = Date.now() - before; profileIndent = previousIndent; - log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); -} +}; debugPrint = function (message) { console.log(message); @@ -127,10 +128,9 @@ function loaded() { function onRowClicked(clickEvent) { let entityID = this.dataset.entityID; console.log("CLICKED", entityID, this); - //return; - var selection = [entityID]; + let selection = [entityID]; if (clickEvent.ctrlKey) { - var selectedIndex = selectedEntities.indexOf(entityID); + let selectedIndex = selectedEntities.indexOf(entityID); if (selectedIndex >= 0) { selection = selectedEntities; selection.splice(selectedIndex, 1) @@ -138,22 +138,23 @@ function loaded() { selection = selection.concat(selectedEntities); } } else if (clickEvent.shiftKey && selectedEntities.length > 0) { - var previousItemFound = -1; - var clickedItemFound = -1; - for (var entity in entityList.visibleItems) { - if (clickedItemFound === -1 && entityID == entityList.visibleItems[entity].values().id) { - clickedItemFound = entity; - } else if(previousItemFound === -1 && selectedEntities[0] == entityList.visibleItems[entity].values().id) { - previousItemFound = entity; + let previousItemFound = -1; + let clickedItemFound = -1; + for (let i = 0, len = visibleEntities.length; i < len; ++i) { + let entity = visibleEntities[i]; + if (clickedItemFound === -1 && entityID == entity.id) { + clickedItemFound = i; + } else if (previousItemFound === -1 && selectedEntities[0] === entity.id) { + previousItemFound = i; } - } + }; if (previousItemFound !== -1 && clickedItemFound !== -1) { - var betweenItems = []; - var toItem = Math.max(previousItemFound, clickedItemFound); + let betweenItems = []; + let toItem = Math.max(previousItemFound, clickedItemFound); // skip first and last item in this loop, we add them to selection after the loop - for (var i = (Math.min(previousItemFound, clickedItemFound) + 1); i < toItem; i++) { - entityList.visibleItems[i].elm.className = 'selected'; - betweenItems.push(entityList.visibleItems[i].values().id); + for (let i = (Math.min(previousItemFound, clickedItemFound) + 1); i < toItem; i++) { + visibleEntities[i].el.className = 'selected'; + betweenItems.push(visibleEntities[i].id); } if (previousItemFound > clickedItemFound) { // always make sure that we add the items in the right order @@ -165,7 +166,7 @@ function loaded() { selectedEntities.forEach(function(entityID) { if (selection.indexOf(entityID) === -1) { - entities[entityID].el.className = ''; + entitiesByID[entityID].el.className = ''; } }); @@ -205,26 +206,28 @@ function loaded() { return urlParts[urlParts.length - 1]; } - function refreshEntityList() { + elFilter.onkeyup = refreshEntityList; + elFilter.onpaste = refreshEntityList; + elFilter.onchange = refreshEntityList; + + // Update the entity list with the new set of data sent from edit.js + function updateEntityList(entityData) { + console.warn("updating entity list"); const IMAGE_MODEL_NAME = 'default-image-model.fbx'; - PROFILE("sort", function() { - let cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; - console.log("Doing sort", currentSortColumn, currentSortOrder); - entityData.sort(cmp); - }); + entities = [] + entitiesByID = {}; + visibleEntities = []; - entities = {}; - - let newEntities; PROFILE("map-data", function() { - newEntities = entityData.map(function(entity) { + entityData.forEach(function(entity) { let type = entity.type; let filename = getFilename(entity.url); if (filename === IMAGE_MODEL_NAME) { type = "Image"; } - return { + + let entityData = { id: entity.id, name: entity.name, type: type, @@ -238,46 +241,83 @@ function loaded() { hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, isBaked: entity.isBaked ? BAKED_GLYPH : null, drawCalls: displayIfNonZero(entity.drawCalls), - hasScript: entity.hasScript ? SCRIPT_GLYPH : null + hasScript: entity.hasScript ? SCRIPT_GLYPH : null, } + + entities.push(entityData); + entitiesByID[entityData.id] = entityData; }); }); - console.log("Adding: " + newEntities.length); + PROFILE("create-rows", function() { + entities.forEach(function(entity) { + let row = document.createElement('tr'); + row.dataset.entityID = entity.id; + row.attributes.title = entity.fullUrl; + function addColumn(cls, text) { + let col = document.createElement('td'); + col.className = cls; + col.innerText = text; + row.append(col); + } + function addColumnHTML(cls, text) { + let col = document.createElement('td'); + col.className = cls; + col.innerHTML = text; + row.append(col); + } + addColumn('type', entity.type); + addColumn('name', entity.name); + addColumn('url', entity.url); + addColumnHTML('locked glyph', entity.locked); + addColumnHTML('visible glyph', entity.visible); + addColumn('verticesCount', entity.verticesCount); + addColumn('texturesCount', entity.texturesCount); + addColumn('texturesSize', entity.texturesSize); + addColumnHTML('hasTransparent glyph', entity.hasTransparent); + addColumnHTML('isBaked glyph', entity.isBaked); + addColumn('drawCalls', entity.drawCalls); + addColumn('hasScript glyph', entity.hasScript); + row.addEventListener('click', onRowClicked); + row.addEventListener('dblclick', onRowDoubleClicked); - elEntityTableBody.innerHTML = ''; - - entities = {}; - - PROFILE("update-dom", function() { - newEntities.forEach(function(entity) { - let row = document.createElement('tr'); - row.dataset.entityID = entity.id; - row.attributes.title = entity.fullUrl; - function addColumn(cls, text) { - let col = document.createElement('td'); - col.className = cls; - col.innerText = text; - row.append(col); - } - addColumn('type', entity.type); - addColumn('name', entity.name); - addColumn('url', entity.url); - addColumn('locked glyph', entity.locked); - addColumn('visible glyph', entity.visible); - addColumn('verticesCount', entity.verticesCount); - addColumn('texturesCount', entity.texturesCount); - addColumn('texturesSize', entity.texturesSize); - addColumn('hasTransparent glyph', entity.hasTransparent); - addColumn('isBaked glyph', entity.isBaked); - addColumn('drawCalls', entity.drawCalls); - addColumn('hasScript glyph', entity.hasScript); - elEntityTableBody.append(row); - row.addEventListener('click', onRowClicked); - row.addEventListener('dblclick', onRowDoubleClicked); - entities[entity.id] = { el: row }; + entity.el = row; + }); }); - + + refreshEntityList(); + updateSelectedEntities(selectedEntities); + } + + function refreshEntityList() { + PROFILE("refresh-entity-list", function() { + console.warn("refreshing entity list"); + PROFILE("filter", function() { + let searchTerm = elFilter.value; + if (searchTerm === '') { + visibleEntities = entities.slice(0); + } else { + console.log("Filtering on: ", searchTerm); + visibleEntities = entities.filter(function(e) { + return e.name.indexOf(searchTerm) > -1 + || e.type.indexOf(searchTerm) > -1 + || e.fullUrl.indexOf(searchTerm) > -1; + }); + } + }); + + PROFILE("sort", function() { + let cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; + console.log("Doing sort", currentSortColumn, currentSortOrder); + visibleEntities.sort(cmp); + }); + + PROFILE("update-dom", function() { + elEntityTableBody.innerHTML = ''; + for (let i = 0, len = visibleEntities.length; i < len; ++i) { + elEntityTableBody.append(visibleEntities[i].el); + } + }); }); } @@ -290,14 +330,6 @@ function loaded() { } } - function scheduleRefreshEntityList() { - var REFRESH_DELAY = 50; - if (refreshEntityListTimer) { - clearTimeout(refreshEntityListTimer); - } - refreshEntityListTimer = setTimeout(refreshEntityListObject, REFRESH_DELAY); - } - function clearEntities() { entities = {}; refreshFooter(); @@ -327,8 +359,6 @@ function loaded() { currentSortOrder = ASCENDING_SORT; } elSortOrder[column].innerHTML = currentSortOrder == ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; - - //entityList.sort(currentSortColumn, { order: currentSortOrder }); refreshEntityList(); }); } @@ -340,37 +370,31 @@ function loaded() { } function refreshFooter() { - return; if (selectedEntities.length > 1) { elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected"; } else if (selectedEntities.length === 1) { elFooter.firstChild.nodeValue = "1 entity selected"; - } else if (entityCount === 1) { + } else if (visibleEntities.length === 1) { elFooter.firstChild.nodeValue = "1 entity found"; } else { - elFooter.firstChild.nodeValue = entityCount + " entities found"; + elFooter.firstChild.nodeValue = visibleEntities.length + " entities found"; } } - function refreshEntityListObject() { - refreshEntityListTimer = null; - //entityList.sort(currentSortColumn, { order: currentSortOrder }); - //entityList.search(elFilter.value); - refreshFooter(); - } function updateSelectedEntities(selectedIDs) { - var notFound = false; - for (var id in entities) { - entities[id].el.className = ''; - } + let notFound = false; + + selectedEntities.forEach(function(id) { + entitiesByID[id].el.className = ''; + }); selectedEntities = []; - for (var i = 0; i < selectedIDs.length; i++) { - var id = selectedIDs[i]; + for (let i = 0; i < selectedIDs.length; i++) { + let id = selectedIDs[i]; selectedEntities.push(id); - if (id in entities) { - var entity = entities[id]; + if (id in entitiesByID) { + let entity = entitiesByID[id]; entity.el.className = 'selected'; } else { notFound = true; @@ -461,17 +485,16 @@ function loaded() { elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { elNoEntitiesMessage.style.display = "none"; - entityData = newEntities; - refreshEntityList(); - //updateSelectedEntities(data.selectedIDs); - //scheduleRefreshEntityList(); + //entityData = newEntities; + updateEntityList(newEntities); + //refreshEntityList(); + updateSelectedEntities(data.selectedIDs); //resize(); } }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { removeEntities(data.deletedIDs); updateSelectedEntities(data.selectedIDs); - scheduleRefreshEntityList(); } else if (data.type === "deleted" && data.ids) { removeEntities(data.ids); refreshFooter(); From 9b9785d250620a5982c84a817540c7c4ddf5f95f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 7 Sep 2018 10:35:41 -0700 Subject: [PATCH 07/11] Fix entity list not handling deleted entities --- scripts/system/html/js/entityList.js | 44 +++++++++++++--------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index ebf31d5d36..8358ceba4b 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -34,9 +34,6 @@ const COMPARE_DESCENDING = function(a, b) { return COMPARE_ASCENDING(b, a); } -//console.log = function() { }; - - // List of all entities let entities = [] @@ -49,7 +46,7 @@ var selectedEntities = []; var currentSortColumn = 'type'; var currentSortOrder = ASCENDING_SORT; -const ENABLE_PROFILING = true; +const ENABLE_PROFILING = false; var profileIndent = ''; const PROFILE = !ENABLE_PROFILING ? function() { } : function(name, fn, args) { console.log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); @@ -62,10 +59,6 @@ const PROFILE = !ENABLE_PROFILING ? function() { } : function(name, fn, args) { console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); }; -debugPrint = function (message) { - console.log(message); -}; - function loaded() { openEventBridge(function() { elEntityTable = document.getElementById("entity-table"); @@ -127,7 +120,6 @@ function loaded() { function onRowClicked(clickEvent) { let entityID = this.dataset.entityID; - console.log("CLICKED", entityID, this); let selection = [entityID]; if (clickEvent.ctrlKey) { let selectedIndex = selectedEntities.indexOf(entityID); @@ -212,7 +204,6 @@ function loaded() { // Update the entity list with the new set of data sent from edit.js function updateEntityList(entityData) { - console.warn("updating entity list"); const IMAGE_MODEL_NAME = 'default-image-model.fbx'; entities = [] @@ -291,13 +282,11 @@ function loaded() { function refreshEntityList() { PROFILE("refresh-entity-list", function() { - console.warn("refreshing entity list"); PROFILE("filter", function() { let searchTerm = elFilter.value; if (searchTerm === '') { visibleEntities = entities.slice(0); } else { - console.log("Filtering on: ", searchTerm); visibleEntities = entities.filter(function(e) { return e.name.indexOf(searchTerm) > -1 || e.type.indexOf(searchTerm) > -1 @@ -308,7 +297,6 @@ function loaded() { PROFILE("sort", function() { let cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; - console.log("Doing sort", currentSortColumn, currentSortOrder); visibleEntities.sort(cmp); }); @@ -322,16 +310,27 @@ function loaded() { } function removeEntities(deletedIDs) { - return; - for (i = 0, length = deletedIDs.length; i < length; i++) { - let id = deletedIDs[i]; - entities[id].el.remove(); - delete entities[id]; + // Loop from the back so we can pop items off while iterating + for (let j = entities.length - 1; j >= 0; --j) { + let id = entities[j]; + for (let i = 0, length = deletedIDs.length; i < length; ++i) { + if (id === deletedIDs[i]) { + entities.splice(j, 1); + entitiesByID[id].el.remove(); + delete entitiesByID[id]; + break; + } + } } + refreshEntities(); } function clearEntities() { - entities = {}; + entities = [] + entitiesByID = {}; + visibleEntities = []; + elEntityTableBody.innerHTML = ''; + refreshFooter(); } @@ -351,14 +350,14 @@ function loaded() { } function setSortColumn(column) { PROFILE("set-sort-column", function() { - if (currentSortColumn == column) { + if (currentSortColumn === column) { currentSortOrder *= -1; } else { elSortOrder[currentSortColumn].innerHTML = ""; currentSortColumn = column; currentSortOrder = ASCENDING_SORT; } - elSortOrder[column].innerHTML = currentSortOrder == ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; + elSortOrder[column].innerHTML = currentSortOrder === ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; refreshEntityList(); }); } @@ -485,11 +484,8 @@ function loaded() { elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { elNoEntitiesMessage.style.display = "none"; - //entityData = newEntities; updateEntityList(newEntities); - //refreshEntityList(); updateSelectedEntities(data.selectedIDs); - //resize(); } }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { From 3cc90d3c80f9696276902d97e616cb7ec9596d2a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 7 Sep 2018 12:07:19 -0700 Subject: [PATCH 08/11] Disable profiling in entityList.js --- scripts/system/libraries/entityList.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 3900260d0c..06255e38ae 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -11,8 +11,9 @@ /* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages, cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible */ +var PROFILING_ENABLED = false; var profileIndent = ''; -PROFILE = function(name, fn, args) { +PROFILE = !PROFILING_ENABLED ? function() { } : function(name, fn, args) { console.log("PROFILE-Script " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' '; @@ -21,7 +22,7 @@ PROFILE = function(name, fn, args) { var delta = Date.now() - before; profileIndent = previousIndent; console.log("PROFILE-Script " + profileIndent + "(" + name + ") End " + delta + "ms"); -} +}; EntityListTool = function(shouldUseEditTabletApp) { var that = {}; @@ -82,7 +83,6 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("Script-JSON.stringify", function() { dataString = JSON.stringify(data); }); - console.log("Length: ", dataString.length, data.type); PROFILE("Script-emitScriptEvent", function() { webView.emitScriptEvent(dataString); if (entityListWindow.window) { @@ -90,7 +90,7 @@ EntityListTool = function(shouldUseEditTabletApp) { } }); } - + that.toggleVisible = function() { that.setVisible(!visible); }; @@ -121,7 +121,7 @@ EntityListTool = function(shouldUseEditTabletApp) { selectedIDs: selectedIDs }); }; - + that.deleteEntities = function (deletedIDs) { emitJSONScriptEvent({ type: "deleted", @@ -150,7 +150,6 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("getProperties", function() { for (var i = 0; i < ids.length; i++) { var id = ids[i]; - //var properties = Entities.getEntityProperties(id); var properties = Entities.getEntityProperties(id, ['name', 'type', 'locked', 'visible', 'renderInfo', 'type', 'modelURL', 'materialURL', 'script']); @@ -168,16 +167,16 @@ EntityListTool = function(shouldUseEditTabletApp) { url: url, locked: properties.locked, visible: properties.visible, - verticesCount: (properties.renderInfo !== undefined ? + verticesCount: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.verticesCount) : ""), - texturesCount: (properties.renderInfo !== undefined ? + texturesCount: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.texturesCount) : ""), - texturesSize: (properties.renderInfo !== undefined ? + texturesSize: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.texturesSize) : ""), - hasTransparent: (properties.renderInfo !== undefined ? + hasTransparent: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.hasTransparent) : ""), isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false, - drawCalls: (properties.renderInfo !== undefined ? + drawCalls: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.drawCalls) : ""), hasScript: properties.script !== "" }); @@ -212,8 +211,7 @@ EntityListTool = function(shouldUseEditTabletApp) { try { data = JSON.parse(data); } catch(e) { - console.log(data); - //print("entityList.js: Error parsing JSON: " + e.name + " data " + data); + print("entityList.js: Error parsing JSON: " + e.name + " data " + data); return; } From 0fadfd2f4cd17830b5b0e0401ef2ac3bd6fd9d7d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 10 Sep 2018 12:14:07 -0700 Subject: [PATCH 09/11] Remove list.js in entityList.html --- scripts/system/html/entityList.html | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index cb95dffc5f..89974f9409 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -11,7 +11,6 @@ - From 5aa5552727f93ac74e86dcc280adb8e63a1063f3 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 10 Sep 2018 14:07:25 -0700 Subject: [PATCH 10/11] Fix PROFILE not forwarding calls when disabled --- scripts/system/html/js/entityList.js | 5 ++++- scripts/system/libraries/entityList.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 8358ceba4b..21132fa968 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -48,7 +48,10 @@ var currentSortOrder = ASCENDING_SORT; const ENABLE_PROFILING = false; var profileIndent = ''; -const PROFILE = !ENABLE_PROFILING ? function() { } : function(name, fn, args) { +const PROFILE_NOOP = function(_name, fn, args) { + fn.apply(this, args); +} ; +const PROFILE = !ENABLE_PROFILING ? PROFILE_NOOP : function(name, fn, args) { console.log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' '; diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 06255e38ae..b53bbbd372 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -13,7 +13,10 @@ var PROFILING_ENABLED = false; var profileIndent = ''; -PROFILE = !PROFILING_ENABLED ? function() { } : function(name, fn, args) { +const PROFILE_NOOP = function(_name, fn, args) { + fn.apply(this, args); +} ; +PROFILE = !PROFILING_ENABLED ? PROFILE_NOOP : function(name, fn, args) { console.log("PROFILE-Script " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' '; From 4b8f5ea6b9e3b558436659a59b02f16150c3f9b0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 10 Sep 2018 16:44:13 -0700 Subject: [PATCH 11/11] Fix syntax and duplicate event handlers in entityList.js --- scripts/system/html/js/entityList.js | 16 +++--- scripts/system/libraries/entityList.js | 72 +++++++++++++------------- 2 files changed, 45 insertions(+), 43 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 21132fa968..615a3c8ddb 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -137,7 +137,7 @@ function loaded() { let clickedItemFound = -1; for (let i = 0, len = visibleEntities.length; i < len; ++i) { let entity = visibleEntities[i]; - if (clickedItemFound === -1 && entityID == entity.id) { + if (clickedItemFound === -1 && entityID === entity.id) { clickedItemFound = i; } else if (previousItemFound === -1 && selectedEntities[0] === entity.id) { previousItemFound = i; @@ -201,10 +201,6 @@ function loaded() { return urlParts[urlParts.length - 1]; } - elFilter.onkeyup = refreshEntityList; - elFilter.onpaste = refreshEntityList; - elFilter.onchange = refreshEntityList; - // Update the entity list with the new set of data sent from edit.js function updateEntityList(entityData) { const IMAGE_MODEL_NAME = 'default-image-model.fbx'; @@ -482,7 +478,7 @@ function loaded() { } else if (data.type === "update" && data.selectedIDs !== undefined) { PROFILE("update", function() { var newEntities = data.entities; - if (newEntities && newEntities.length == 0) { + if (newEntities && newEntities.length === 0) { elNoEntitiesMessage.style.display = "block"; elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { @@ -540,7 +536,13 @@ function loaded() { }; window.onresize = resize; - elFilter.onchange = resize; + + elFilter.onkeyup = refreshEntityList; + elFilter.onpaste = refreshEntityList; + elFilter.onchange = function() { + refreshEntityList(); + resize(); + }; elFilter.onblur = refreshFooter; diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index b53bbbd372..27e079589b 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -142,49 +142,49 @@ EntityListTool = function(shouldUseEditTabletApp) { var ids; PROFILE("findEntities", function() { - if (filterInView) { - ids = Entities.findEntitiesInFrustum(Camera.frustum); - } else { - ids = Entities.findEntities(MyAvatar.position, searchRadius); - } + if (filterInView) { + ids = Entities.findEntitiesInFrustum(Camera.frustum); + } else { + ids = Entities.findEntities(MyAvatar.position, searchRadius); + } }); var cameraPosition = Camera.position; PROFILE("getProperties", function() { - for (var i = 0; i < ids.length; i++) { - var id = ids[i]; - var properties = Entities.getEntityProperties(id, ['name', 'type', 'locked', - 'visible', 'renderInfo', 'type', 'modelURL', 'materialURL', 'script']); + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + var properties = Entities.getEntityProperties(id, ['name', 'type', 'locked', + 'visible', 'renderInfo', 'type', 'modelURL', 'materialURL', 'script']); - if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) { - var url = ""; - if (properties.type === "Model") { - url = properties.modelURL; - } else if (properties.type === "Material") { - url = properties.materialURL; + if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) { + var url = ""; + if (properties.type === "Model") { + url = properties.modelURL; + } else if (properties.type === "Material") { + url = properties.materialURL; + } + entities.push({ + id: id, + name: properties.name, + type: properties.type, + url: url, + locked: properties.locked, + visible: properties.visible, + verticesCount: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.verticesCount) : ""), + texturesCount: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.texturesCount) : ""), + texturesSize: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.texturesSize) : ""), + hasTransparent: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.hasTransparent) : ""), + isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false, + drawCalls: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.drawCalls) : ""), + hasScript: properties.script !== "" + }); } - entities.push({ - id: id, - name: properties.name, - type: properties.type, - url: url, - locked: properties.locked, - visible: properties.visible, - verticesCount: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.verticesCount) : ""), - texturesCount: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.texturesCount) : ""), - texturesSize: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.texturesSize) : ""), - hasTransparent: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.hasTransparent) : ""), - isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false, - drawCalls: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.drawCalls) : ""), - hasScript: properties.script !== "" - }); } - } }); var selectedIDs = [];