Skip to content

Commit a3fd794

Browse files
committed
fix: preventing duplicates when adding elements to the scene
1 parent 73a7ec9 commit a3fd794

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

src/core/Scene.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,15 @@ export class Scene {
6969
add(body, element, addUniverse = true) {
7070
this.scene.add(body);
7171
if (element) {
72-
this.elements.push(element);
72+
// Prevent duplicate entries in elements array (same element instance
73+
// or same body UUID). Duplicates can occur from double-renders, HMR,
74+
// or race conditions between Importer and ensure* methods.
75+
const alreadyExists = this.elements.some(
76+
e => e === element || (e.hasBody() && e.getBody().uuid === body.uuid),
77+
);
78+
if (!alreadyExists) {
79+
this.elements.push(element);
80+
}
7381
}
7482

7583
if (addUniverse) {
@@ -82,14 +90,24 @@ export class Scene {
8290
// Only include camera in hierarchy if it's serializable (scene camera is not)
8391
const cameraChildren =
8492
camera && camera.isSerializable() ? [camera.getHierarchy(options)] : [];
93+
94+
// Deduplicate elements by UUID to prevent showing the same element twice
95+
// in the hierarchy (can happen from race conditions or double-adds)
96+
const seenUUIDs = new Set();
97+
const deduplicatedElements = this.elements.filter(e => {
98+
if (!e.hasBody()) return false;
99+
const uuid = e.getBody().uuid;
100+
if (seenUUIDs.has(uuid)) return false;
101+
seenUUIDs.add(uuid);
102+
return !e.hasParent() && !e.isHelper() && e.isSerializable();
103+
});
104+
85105
return [
86106
{
87107
element: this.toJSON(options.parseJSON),
88108
children: [
89109
...cameraChildren,
90-
...this.elements
91-
.filter(e => !e.hasParent() && !e.isHelper() && e.isSerializable())
92-
.map(e => e.getHierarchy(options)),
110+
...deduplicatedElements.map(e => e.getHierarchy(options)),
93111
],
94112
},
95113
];

0 commit comments

Comments
 (0)