Michael Herzog 1 месяц назад
Родитель
Сommit
ece7ca3640
3 измененных файлов с 71 добавлено и 5 удалено
  1. 44 4
      devtools/bridge.js
  2. 1 0
      devtools/constants.js
  3. 26 1
      devtools/panel/panel.js

+ 44 - 4
devtools/bridge.js

@@ -1,4 +1,4 @@
-/* global MESSAGE_ID, MESSAGE_REQUEST_STATE, MESSAGE_REQUEST_OBJECT_DETAILS, MESSAGE_SCROLL_TO_CANVAS, MESSAGE_HIGHLIGHT_OBJECT, MESSAGE_UNHIGHLIGHT_OBJECT, EVENT_REGISTER, EVENT_OBSERVE, EVENT_RENDERER, EVENT_SCENE, EVENT_OBJECT_DETAILS, EVENT_DEVTOOLS_READY */
+/* global MESSAGE_ID, MESSAGE_REQUEST_STATE, MESSAGE_REQUEST_OBJECT_DETAILS, MESSAGE_SCROLL_TO_CANVAS, MESSAGE_HIGHLIGHT_OBJECT, MESSAGE_UNHIGHLIGHT_OBJECT, EVENT_REGISTER, EVENT_OBSERVE, EVENT_RENDERER, EVENT_SCENE, EVENT_SCENE_REMOVED, EVENT_OBJECT_DETAILS, EVENT_DEVTOOLS_READY */
 
 /**
  * This script injected by the installed three.js developer
@@ -77,6 +77,9 @@
 				// Clear observed arrays
 				observedScenes.length = 0;
 				observedRenderers.length = 0;
+				sceneObjectCountCache.clear();
+				sceneEmptyTicks.clear();
+				removedScenes.clear();
 
 			}
 
@@ -95,6 +98,9 @@
 		const observedScenes = [];
 		const observedRenderers = [];
 		const sceneObjectCountCache = new Map(); // Cache for object counts per scene
+		const sceneEmptyTicks = new Map(); // Consecutive sendState ticks each scene has been empty
+		const removedScenes = new Set(); // Scenes hidden from the panel; tracked so we can resurrect them
+		const SCENE_EMPTY_TICKS_THRESHOLD = 5; // ~5s at 1s polling — hide empty scene from the panel
 
 		// Shared tree traversal function
 		function traverseObjectTree( rootObject, callback, skipDuplicates = false ) {
@@ -430,10 +436,44 @@
 
 			}
 
-			// Send current scenes
-			for ( const observedScene of observedScenes ) {
+			// Send current scenes. Three.js scenes have no dispose() method, so we
+			// approximate disposal: a scene that has stayed empty for several poll
+			// cycles is hidden from the panel; if it gains children again, we
+			// resurrect it (reloadSceneObjects re-dispatches the batch).
+			for ( const scene of observedScenes ) {
+
+				const isEmpty = scene.children.length === 0;
+				const wasRemoved = removedScenes.has( scene.uuid );
+
+				if ( isEmpty ) {
+
+					// Already hidden — nothing to send until children come back
+					if ( wasRemoved ) continue;
+
+					const ticks = ( sceneEmptyTicks.get( scene.uuid ) || 0 ) + 1;
+
+					if ( ticks >= SCENE_EMPTY_TICKS_THRESHOLD ) {
+
+						removedScenes.add( scene.uuid );
+						sceneEmptyTicks.delete( scene.uuid );
+						sceneObjectCountCache.delete( scene.uuid );
+						dispatchEvent( EVENT_SCENE_REMOVED, { uuid: scene.uuid } );
+						continue;
+
+					}
+
+					sceneEmptyTicks.set( scene.uuid, ticks );
+
+				} else {
+
+					sceneEmptyTicks.delete( scene.uuid );
+
+					// Repopulated after removal — bring it back into the panel
+					if ( wasRemoved ) removedScenes.delete( scene.uuid );
+
+				}
 
-				reloadSceneObjects( observedScene );
+				reloadSceneObjects( scene );
 
 			}
 

+ 1 - 0
devtools/constants.js

@@ -21,3 +21,4 @@ var EVENT_SCENE = 'scene';
 var EVENT_OBJECT_DETAILS = 'object-details';
 var EVENT_DEVTOOLS_READY = 'devtools-ready';
 var EVENT_COMMITTED = 'committed';
+var EVENT_SCENE_REMOVED = 'scene-removed';

+ 26 - 1
devtools/panel/panel.js

@@ -1,4 +1,4 @@
-/* global chrome, MESSAGE_ID, MESSAGE_INIT, MESSAGE_REQUEST_STATE, MESSAGE_REQUEST_OBJECT_DETAILS, MESSAGE_SCROLL_TO_CANVAS, MESSAGE_HIGHLIGHT_OBJECT, MESSAGE_UNHIGHLIGHT_OBJECT, EVENT_REGISTER, EVENT_RENDERER, EVENT_OBJECT_DETAILS, EVENT_SCENE, EVENT_COMMITTED */
+/* global chrome, MESSAGE_ID, MESSAGE_INIT, MESSAGE_REQUEST_STATE, MESSAGE_REQUEST_OBJECT_DETAILS, MESSAGE_SCROLL_TO_CANVAS, MESSAGE_HIGHLIGHT_OBJECT, MESSAGE_UNHIGHLIGHT_OBJECT, EVENT_REGISTER, EVENT_RENDERER, EVENT_OBJECT_DETAILS, EVENT_SCENE, EVENT_SCENE_REMOVED, EVENT_COMMITTED */
 
 const CONNECTION_NAME = 'three-devtools';
 const STATE_POLLING_INTERVAL = 1000;
@@ -280,6 +280,26 @@ function processSceneBatch( sceneUuid, batchObjects ) {
 
 }
 
+// Drop a scene and all of its objects (the bridge has determined it was disposed)
+function removeScene( sceneUuid ) {
+
+	state.scenes.delete( sceneUuid );
+
+	state.objects.forEach( ( obj, uuid ) => {
+
+		if ( uuid === sceneUuid || obj._sceneUuid === sceneUuid ) {
+
+			state.objects.delete( uuid );
+			treeExpandedState.delete( uuid );
+
+		}
+
+	} );
+
+	sceneDirty = true;
+
+}
+
 // Clear state when panel is reloaded
 function clearState() {
 
@@ -336,6 +356,11 @@ function handleThreeEvent( message ) {
 			updateSceneTree();
 			break;
 
+		case EVENT_SCENE_REMOVED:
+			removeScene( message.detail.uuid );
+			updateSceneTree();
+			break;
+
 		case EVENT_COMMITTED:
 			clearState();
 			updateRenderers();

粤ICP备19079148号