Skip to content

Commit e20665e

Browse files
authored
Merge pull request #2563 from richardTingle/#2562-thread-warden
#2562 thread warden
2 parents ab9af09 + 7b0fe87 commit e20665e

File tree

9 files changed

+934
-1
lines changed

9 files changed

+934
-1
lines changed

jme3-core/src/main/java/com/jme3/app/SimpleApplication.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.jme3.renderer.queue.RenderQueue.Bucket;
4646
import com.jme3.scene.Node;
4747
import com.jme3.scene.Spatial.CullHint;
48+
import com.jme3.scene.threadwarden.SceneGraphThreadWarden;
4849
import com.jme3.system.AppSettings;
4950
import com.jme3.system.JmeContext.Type;
5051
import com.jme3.system.JmeSystem;
@@ -197,6 +198,11 @@ protected BitmapFont loadGuiFont() {
197198
public void initialize() {
198199
super.initialize();
199200

201+
//noinspection AssertWithSideEffects
202+
assert SceneGraphThreadWarden.setup(rootNode);
203+
//noinspection AssertWithSideEffects
204+
assert SceneGraphThreadWarden.setup(guiNode);
205+
200206
// Several things rely on having this
201207
guiFont = loadGuiFont();
202208

@@ -240,6 +246,13 @@ public void initialize() {
240246
simpleInitApp();
241247
}
242248

249+
@Override
250+
public void stop(boolean waitFor) {
251+
//noinspection AssertWithSideEffects
252+
assert SceneGraphThreadWarden.reset();
253+
super.stop(waitFor);
254+
}
255+
243256
@Override
244257
public void update() {
245258
if (prof != null) {

jme3-core/src/main/java/com/jme3/scene/Geometry.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.jme3.renderer.Camera;
4545
import com.jme3.scene.VertexBuffer.Type;
4646
import com.jme3.scene.mesh.MorphTarget;
47+
import com.jme3.scene.threadwarden.SceneGraphThreadWarden;
4748
import com.jme3.util.TempVars;
4849
import com.jme3.util.clone.Cloner;
4950
import com.jme3.util.clone.IdentityCloneFunction;
@@ -183,6 +184,7 @@ public void setIgnoreTransform(boolean ignoreTransform) {
183184
*/
184185
@Override
185186
public void setLodLevel(int lod) {
187+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
186188
if (mesh.getNumLodLevels() == 0) {
187189
throw new IllegalStateException("LOD levels are not set on this mesh");
188190
}
@@ -239,6 +241,7 @@ public int getTriangleCount() {
239241
* @throws IllegalArgumentException If mesh is null
240242
*/
241243
public void setMesh(Mesh mesh) {
244+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
242245
if (mesh == null) {
243246
throw new IllegalArgumentException();
244247
}
@@ -269,6 +272,7 @@ public Mesh getMesh() {
269272
*/
270273
@Override
271274
public void setMaterial(Material material) {
275+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
272276
this.material = material;
273277
nbSimultaneousGPUMorph = -1;
274278
if (isGrouped()) {

jme3-core/src/main/java/com/jme3/scene/Node.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.jme3.export.JmeExporter;
3939
import com.jme3.export.JmeImporter;
4040
import com.jme3.material.Material;
41+
import com.jme3.scene.threadwarden.SceneGraphThreadWarden;
4142
import com.jme3.util.SafeArrayList;
4243
import com.jme3.util.clone.Cloner;
4344
import java.io.IOException;
@@ -201,6 +202,7 @@ private void addUpdateChildren(SafeArrayList<Spatial> results) {
201202
* that would change state.
202203
*/
203204
void invalidateUpdateList() {
205+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
204206
updateListValid = false;
205207
if (parent != null) {
206208
parent.invalidateUpdateList();
@@ -344,6 +346,7 @@ public int attachChild(Spatial child) {
344346
* @throws IllegalArgumentException if child is null or this
345347
*/
346348
public int attachChildAt(Spatial child, int index) {
349+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
347350
if (child == null) {
348351
throw new IllegalArgumentException("child cannot be null");
349352
}
@@ -428,6 +431,7 @@ public int detachChildNamed(String childName) {
428431
* @return the child at the supplied index.
429432
*/
430433
public Spatial detachChildAt(int index) {
434+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
431435
Spatial child = children.remove(index);
432436
if (child != null) {
433437
child.setParent(null);
@@ -455,6 +459,7 @@ public Spatial detachChildAt(int index) {
455459
* node.
456460
*/
457461
public void detachAllChildren() {
462+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
458463
// Note: this could be a bit more efficient if it delegated
459464
// to a private method that avoided setBoundRefresh(), etc.
460465
// for every child and instead did one in here at the end.
@@ -483,6 +488,7 @@ public int getChildIndex(Spatial sp) {
483488
* @param index2 The index of the second child to swap
484489
*/
485490
public void swapChildren(int index1, int index2) {
491+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
486492
Spatial c2 = children.get(index2);
487493
Spatial c1 = children.remove(index1);
488494
children.add(index1, c2);
@@ -562,6 +568,7 @@ public List<Spatial> getChildren() {
562568

563569
@Override
564570
public void setMaterial(Material mat) {
571+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
565572
for (int i = 0; i < children.size(); i++) {
566573
children.get(i).setMaterial(mat);
567574
}
@@ -778,6 +785,7 @@ public void read(JmeImporter importer) throws IOException {
778785

779786
@Override
780787
public void setModelBound(BoundingVolume modelBound) {
788+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
781789
if (children != null) {
782790
for (Spatial child : children.getArray()) {
783791
child.setModelBound(modelBound != null ? modelBound.clone(null) : null);
@@ -787,6 +795,7 @@ public void setModelBound(BoundingVolume modelBound) {
787795

788796
@Override
789797
public void updateModelBound() {
798+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
790799
if (children != null) {
791800
for (Spatial child : children.getArray()) {
792801
child.updateModelBound();

jme3-core/src/main/java/com/jme3/scene/Spatial.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import com.jme3.renderer.queue.RenderQueue.Bucket;
5050
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
5151
import com.jme3.scene.control.Control;
52+
import com.jme3.scene.threadwarden.SceneGraphThreadWarden;
5253
import com.jme3.util.SafeArrayList;
5354
import com.jme3.util.TempVars;
5455
import com.jme3.util.clone.Cloner;
@@ -278,11 +279,13 @@ protected void setRequiresUpdates(boolean f) {
278279
* a refresh is required.
279280
*/
280281
protected void setTransformRefresh() {
282+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
281283
refreshFlags |= RF_TRANSFORM;
282284
setBoundRefresh();
283285
}
284286

285287
protected void setLightListRefresh() {
288+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
286289
refreshFlags |= RF_LIGHTLIST;
287290
// Make sure next updateGeometricState() visits this branch
288291
// to update lights.
@@ -299,6 +302,7 @@ protected void setLightListRefresh() {
299302
}
300303

301304
protected void setMatParamOverrideRefresh() {
305+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
302306
refreshFlags |= RF_MATPARAM_OVERRIDE;
303307
Spatial p = parent;
304308
while (p != null) {
@@ -316,6 +320,7 @@ protected void setMatParamOverrideRefresh() {
316320
* a refresh is required.
317321
*/
318322
protected void setBoundRefresh() {
323+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
319324
refreshFlags |= RF_BOUND;
320325

321326
Spatial p = parent;
@@ -364,7 +369,8 @@ public boolean checkCulling(Camera cam) {
364369
throw new IllegalStateException("Scene graph is not properly updated for rendering.\n"
365370
+ "State was changed after rootNode.updateGeometricState() call. \n"
366371
+ "Make sure you do not modify the scene from another thread!\n"
367-
+ "Problem spatial name: " + getName());
372+
+ "Problem spatial name: " + getName() + "\n" +
373+
SceneGraphThreadWarden.getTurnOnAssertsPrompt());
368374
}
369375

370376
CullHint cm = getCullHint();
@@ -612,6 +618,7 @@ protected void updateMatParamOverrides() {
612618
* @see MatParamOverride
613619
*/
614620
public void addMatParamOverride(MatParamOverride override) {
621+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
615622
if (override == null) {
616623
throw new IllegalArgumentException("override cannot be null");
617624
}
@@ -626,6 +633,7 @@ public void addMatParamOverride(MatParamOverride override) {
626633
* @see MatParamOverride
627634
*/
628635
public void removeMatParamOverride(MatParamOverride override) {
636+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
629637
if (localOverrides.remove(override)) {
630638
setMatParamOverrideRefresh();
631639
}
@@ -637,6 +645,7 @@ public void removeMatParamOverride(MatParamOverride override) {
637645
* @see #addMatParamOverride(com.jme3.material.MatParamOverride)
638646
*/
639647
public void clearMatParamOverrides() {
648+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
640649
if (!localOverrides.isEmpty()) {
641650
setMatParamOverrideRefresh();
642651
}
@@ -772,6 +781,7 @@ public void runControlRender(RenderManager rm, ViewPort vp) {
772781
* @see Spatial#removeControl(java.lang.Class)
773782
*/
774783
public void addControl(Control control) {
784+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
775785
boolean before = requiresUpdates();
776786
controls.add(control);
777787
control.setSpatial(this);
@@ -823,6 +833,7 @@ public void addControlAt(int index, Control control) {
823833
* @see Spatial#addControl(com.jme3.scene.control.Control)
824834
*/
825835
public void removeControl(Class<? extends Control> controlType) {
836+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
826837
boolean before = requiresUpdates();
827838
for (int i = 0; i < controls.size(); i++) {
828839
if (controlType.isAssignableFrom(controls.get(i).getClass())) {
@@ -850,6 +861,7 @@ public void removeControl(Class<? extends Control> controlType) {
850861
* @see Spatial#addControl(com.jme3.scene.control.Control)
851862
*/
852863
public boolean removeControl(Control control) {
864+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
853865
boolean before = requiresUpdates();
854866
boolean result = controls.remove(control);
855867
if (result) {
@@ -1005,6 +1017,7 @@ public Node getParent() {
10051017
* the parent of this node.
10061018
*/
10071019
protected void setParent(Node parent) {
1020+
assert SceneGraphThreadWarden.updateRequirement(this, parent);
10081021
this.parent = parent;
10091022
}
10101023

@@ -1369,6 +1382,7 @@ public RenderQueue.ShadowMode getShadowMode() {
13691382
* @param lod The lod level to set.
13701383
*/
13711384
public void setLodLevel(int lod) {
1385+
assert SceneGraphThreadWarden.assertOnCorrectThread(this);
13721386
}
13731387

13741388
/**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.jme3.scene.threadwarden;
2+
3+
public class IllegalThreadSceneGraphMutation extends IllegalStateException{
4+
public IllegalThreadSceneGraphMutation(String message){
5+
super(message);
6+
}
7+
}

0 commit comments

Comments
 (0)