Skip to content

Commit 992282f

Browse files
committed
Merge branch 'master' into add_game_template
2 parents 9f1cded + ae2a1eb commit 992282f

36 files changed

+1883
-851
lines changed

BasicGameTemplate/nbproject/project.properties

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ javac.classpath=\
4444
${libs.jme3-terrain.classpath}:\
4545
${libs.jme3-jbullet.classpath}:\
4646
${libs.jme3-awt-dialogs.classpath}:\
47-
${libs.jme3-plugins-json.classpath}
47+
${libs.jme3-plugins-json.classpath}:\
48+
${libs.jme3-plugins-json-gson.classpath}
4849
# Space-separated list of extra javac options
4950
javac.compilerargs=
5051
javac.deprecation=false

JME3TestsTemplate/nbproject/project.properties

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ jar.compress=false
2727
javac.classpath=\
2828
${libs.jme3-jogg.classpath}:\
2929
${libs.jme3-plugins-json.classpath}:\
30+
${libs.jme3-plugins-json-gson.classpath}:\
3031
${libs.jme3-networking.classpath}:\
3132
${libs.jme3-plugins.classpath}:\
3233
${libs.jme3-core.classpath}:\

build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ dependencies {
4040
corelibs dep("org.jmonkeyengine:jme3-desktop:$jmeVersion-$jmeVersionTag", true, true)
4141
corelibs dep("org.jmonkeyengine:jme3-awt-dialogs:$jmeVersion-$jmeVersionTag", true, true)
4242
corelibs dep("org.jmonkeyengine:jme3-plugins-json:$jmeVersion-$jmeVersionTag", true, true)
43+
corelibs dep("org.jmonkeyengine:jme3-plugins-json-gson:$jmeVersion-$jmeVersionTag", true, true)
4344
corelibs dep("org.jmonkeyengine:jme3-lwjgl:$jmeVersion-$jmeVersionTag", true, true)
4445
corelibs dep("org.jmonkeyengine:jme3-effects:$jmeVersion-$jmeVersionTag", true, true)
4546
corelibs dep("com.github.stephengold:Minie:8.2.0", true, true) // replacement for bullet-native

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ jmeVersionTag = stable
88
#jmeVersionTagID = 0
99

1010
# Path for downloading NetBeans Base
11-
netbeansUrl = https://archive.apache.org/dist/netbeans/netbeans/23/netbeans-23-bin.zip
11+
netbeansUrl = https://archive.apache.org/dist/netbeans/netbeans/24/netbeans-24-bin.zip

jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java

+97-48
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2010 jMonkeyEngine
2+
* Copyright (c) 2009-2024 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -31,13 +31,16 @@
3131
*/
3232
package com.jme3.gde.core.appstates;
3333

34+
import java.io.IOException;
35+
import java.util.ArrayList;
36+
import java.util.Collections;
3437
import java.util.EnumSet;
35-
import java.util.Iterator;
36-
import java.util.LinkedList;
3738
import java.util.List;
3839
import java.util.Set;
3940
import javax.lang.model.element.TypeElement;
41+
import javax.lang.model.type.TypeKind;
4042
import javax.lang.model.type.TypeMirror;
43+
import javax.lang.model.util.Types;
4144
import javax.swing.JPanel;
4245
import org.netbeans.api.java.classpath.ClassPath;
4346
import org.netbeans.api.java.project.JavaProjectConstants;
@@ -48,11 +51,11 @@
4851
import org.netbeans.api.java.source.CompilationController;
4952
import org.netbeans.api.java.source.ElementHandle;
5053
import org.netbeans.api.java.source.JavaSource;
51-
import org.netbeans.api.java.source.JavaSource.Phase;
52-
import org.netbeans.api.java.source.Task;
5354
import org.netbeans.api.project.Project;
55+
import org.netbeans.api.project.ProjectUtils;
5456
import org.netbeans.api.project.SourceGroup;
5557
import org.netbeans.api.project.Sources;
58+
import org.openide.filesystems.FileObject;
5659
import org.openide.util.Exceptions;
5760

5861
@SuppressWarnings({"unchecked", "rawtypes"})
@@ -82,57 +85,103 @@ private void scanControls() {
8285
}
8386

8487
private List<String> getSources() {
85-
Sources sources = proj.getLookup().lookup(Sources.class);
86-
final List<String> list = new LinkedList<String>();
87-
if (sources != null) {
88+
Project root = ProjectUtils.rootOf(proj);
89+
Set<Project> containedProjects = ProjectUtils.getContainedProjects(root, true);
90+
List<Project> projects = new ArrayList<>();
91+
projects.add(root);
92+
if (containedProjects != null) {
93+
projects.addAll(containedProjects);
94+
}
95+
if (projects.isEmpty()) {
96+
return Collections.emptyList();
97+
}
98+
99+
List<String> list = new ArrayList<>();
100+
for (Project project : projects) {
101+
Sources sources = ProjectUtils.getSources(project);
102+
if (sources == null) {
103+
continue;
104+
}
105+
88106
SourceGroup[] groups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
89-
if (groups != null) {
90-
for (SourceGroup sourceGroup : groups) {
91-
ClasspathInfo cpInfo = ClasspathInfo.create(ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.BOOT),
92-
ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.COMPILE),
93-
ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.SOURCE));
94-
95-
Set<SearchScope> set = EnumSet.of(ClassIndex.SearchScope.SOURCE);
96-
Set<ElementHandle<TypeElement>> types = cpInfo.getClassIndex().getDeclaredTypes("", NameKind.PREFIX, set);
97-
for (Iterator<ElementHandle<TypeElement>> it = types.iterator(); it.hasNext();) {
98-
final ElementHandle<TypeElement> elementHandle = it.next();
99-
JavaSource js = JavaSource.create(cpInfo);
100-
try {
101-
js.runUserActionTask(new Task<CompilationController>() {
102-
public void run(CompilationController control)
103-
throws Exception {
104-
control.toPhase(Phase.RESOLVED);
105-
//TODO: check with proper casting check.. gotta get TypeMirror of Control interface..
106-
// TypeUtilities util = control.getTypeUtilities();//.isCastable(Types., null)
107-
// util.isCastable(null, null);
108-
TypeElement elem = elementHandle.resolve(control);
109-
if (elem != null) {
110-
List<? extends TypeMirror> interfaces = elem.getInterfaces();
111-
for (TypeMirror typeMirror : interfaces) {
112-
String interfaceName = typeMirror.toString();
113-
if ("com.jme3.app.state.AppState".equals(interfaceName)) {
114-
list.add(elem.getQualifiedName().toString());
115-
}
116-
}
117-
TypeMirror superClass = elem.getSuperclass();
118-
String superClassName = superClass.toString();
119-
if ("com.jme3.app.state.AbstractAppState".equals(superClassName)) {
120-
list.add(elem.getQualifiedName().toString());
121-
}
122-
}
123-
}
124-
}, false);
125-
} catch (Exception ioe) {
126-
Exceptions.printStackTrace(ioe);
127-
}
128-
}
107+
if (groups == null) {
108+
continue;
109+
}
129110

111+
for (SourceGroup sourceGroup : groups) {
112+
FileObject rootFolder = sourceGroup.getRootFolder();
113+
ClasspathInfo cpInfo = ClasspathInfo.create(
114+
ClassPath.getClassPath(rootFolder, ClassPath.BOOT),
115+
ClassPath.getClassPath(rootFolder, ClassPath.COMPILE),
116+
ClassPath.getClassPath(rootFolder, ClassPath.SOURCE)
117+
);
118+
119+
Set<SearchScope> set = EnumSet.of(ClassIndex.SearchScope.SOURCE);
120+
Set<ElementHandle<TypeElement>> types = cpInfo.getClassIndex().getDeclaredTypes("", NameKind.PREFIX, set);
121+
for (ElementHandle<TypeElement> elementHandle : types) {
122+
JavaSource js = JavaSource.create(cpInfo);
123+
try {
124+
js.runUserActionTask((CompilationController control) -> {
125+
control.toPhase(JavaSource.Phase.RESOLVED);
126+
TypeElement elem = elementHandle.resolve(control);
127+
if (elem != null && doesInheritFromAppState(elem, control.getTypes())) {
128+
list.add(elem.getQualifiedName().toString());
129+
}
130+
}, false);
131+
} catch (IOException ioe) {
132+
Exceptions.printStackTrace(ioe);
133+
}
130134
}
131135
}
132136
}
137+
133138
return list;
134139
}
135140

141+
/**
142+
* Checks recursively if a type inherits from or implements any
143+
* AppState-related class/interface.
144+
*/
145+
private boolean doesInheritFromAppState(TypeElement type, Types typeUtils) {
146+
if (type == null) {
147+
return false;
148+
}
149+
150+
// Check interfaces
151+
for (TypeMirror iface : type.getInterfaces()) {
152+
if (isAppStateType(iface)) {
153+
return true;
154+
}
155+
if (doesInheritFromAppState((TypeElement) typeUtils.asElement(iface), typeUtils)) {
156+
return true;
157+
}
158+
}
159+
160+
// Check superclass
161+
TypeMirror superClass = type.getSuperclass();
162+
if (superClass != null && superClass.getKind() != TypeKind.NONE) {
163+
if (isAppStateType(superClass)) {
164+
return true;
165+
}
166+
return doesInheritFromAppState((TypeElement) typeUtils.asElement(superClass), typeUtils);
167+
}
168+
169+
return false;
170+
}
171+
172+
/**
173+
* Determines if a TypeMirror corresponds to an AppState-related type.
174+
*/
175+
private boolean isAppStateType(TypeMirror typeMirror) {
176+
if (typeMirror == null) {
177+
return false;
178+
}
179+
String className = typeMirror.toString();
180+
return "com.jme3.app.state.AppState".equals(className)
181+
|| "com.jme3.app.state.AbstractAppState".equals(className)
182+
|| "com.jme3.app.state.BaseAppState".equals(className);
183+
}
184+
136185
public void load(Project proj) {
137186
this.proj = proj;
138187
scanControls();

jme3-core/src/com/jme3/gde/core/assets/ExternalChangeScanner.java

+13-43
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003-2012 jMonkeyEngine
2+
* Copyright (c) 2003-2024 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,6 @@
3636
import com.jme3.gde.core.scene.SceneApplication;
3737
import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent;
3838
import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
39-
import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
4039
import com.jme3.gde.core.util.SpatialUtil;
4140
import com.jme3.gde.core.util.TaggedSpatialFinder;
4241
import com.jme3.gde.core.util.datatransfer.CopyAnimationDataFromOriginal;
@@ -186,9 +185,7 @@ private void notifyUser() {
186185

187186
private void applyExternalData(final boolean onlyMeshData,
188187
final boolean onlyAnimData) {
189-
final ProgressHandle handle = ProgressHandle.createHandle("Updating "
190-
+ "file "
191-
+ "data");
188+
final ProgressHandle handle = ProgressHandle.createHandle("Updating file data");
192189
handle.start();
193190
try {
194191
final Spatial original = loadOriginalSpatial();
@@ -207,13 +204,11 @@ private void applyExternalData(final boolean onlyMeshData,
207204
new CopyTransformDataFromOriginal(finder).update(spat, original);
208205
new CopyMaterialDataFromOriginal(finder).update(spat, original);
209206
}
210-
// Do a complicated recurse refresh since AbstractSceneExplorerNode:refresh() isn't working
207+
211208
SwingUtilities.invokeLater(() -> {
212209
Node rootNode = SceneExplorerTopComponent.findInstance().getExplorerManager().getRootContext();
213-
if (rootNode instanceof JmeNode) {
214-
SceneApplication.getApplication().enqueue((Runnable) () -> {
215-
refreshNamedSpatial((JmeNode) rootNode, spat.getName());
216-
});
210+
if (rootNode instanceof JmeNode jmeNode) {
211+
SceneApplication.getApplication().enqueue(new RefreshJmeSpatial(jmeNode, spat.getName()));
217212
}
218213
});
219214

@@ -228,46 +223,15 @@ private void applyExternalData(final boolean onlyMeshData,
228223
}
229224
}
230225

231-
/**
232-
* Look for the spatial to update using the name of the asset
233-
* @param spatial
234-
* @param name
235-
*/
236-
private void refreshNamedSpatial(JmeSpatial spatial, String name){
237-
if(spatial.getName().equals(name)){
238-
recurseRefresh(spatial);
239-
} else {
240-
for(Node s: spatial.getChildren().getNodes()){
241-
if(s instanceof JmeSpatial){
242-
refreshNamedSpatial((JmeSpatial) s, name);
243-
}
244-
245-
}
246-
}
247-
}
248-
249-
/**
250-
* Refreshes the spatial and all children
251-
* @param spatial
252-
*/
253-
private void recurseRefresh(JmeSpatial spatial){
254-
spatial.refresh(false);
255-
for(Node s: spatial.getChildren().getNodes()){
256-
if(s instanceof JmeSpatial){
257-
recurseRefresh((JmeSpatial) s);
258-
}
259-
}
260-
}
261-
262226
private Spatial loadOriginalSpatial() {
263227
try {
264228
final DataObject dobj = DataObject.find(originalObject);
265229
final AssetData originalAssetData =
266230
dobj.getLookup().lookup(AssetData.class);
267231
if (originalAssetData != null) {
268232
final Savable sav = originalAssetData.loadAsset();
269-
if (sav instanceof Spatial) {
270-
return (Spatial) sav;
233+
if (sav instanceof Spatial spatial) {
234+
return spatial;
271235
} else {
272236
LOGGER.log(Level.SEVERE, "Trying to load original for {0}"
273237
+ " but it is not a Spatial: {1}",
@@ -352,18 +316,22 @@ public void assetDataPropertyChanged(final String property,
352316
}
353317
}
354318

319+
@Override
355320
public void fileFolderCreated(FileEvent fe) {
356321
}
357322

323+
@Override
358324
public void fileDataCreated(FileEvent fe) {
359325
}
360326

327+
@Override
361328
public void fileChanged(FileEvent fe) {
362329
LOGGER.log(Level.INFO, "External file {0} for {1} changed!",
363330
new Object[]{fe.getFile(), assetDataObject.getName()});
364331
notifyUser();
365332
}
366333

334+
@Override
367335
public void fileDeleted(FileEvent fe) {
368336
LOGGER.log(Level.INFO, "External file {0} for {1} deleted!",
369337
new Object[]{fe.getFile(), assetDataObject.getName()});
@@ -377,6 +345,7 @@ public void fileDeleted(FileEvent fe) {
377345
//TODO: add folder listener for when recreated
378346
}
379347

348+
@Override
380349
public void fileRenamed(FileRenameEvent fe) {
381350
LOGGER.log(Level.INFO, "External file {0} for {1} renamed!",
382351
new Object[]{fe.getFile(), assetDataObject.getName()});
@@ -388,6 +357,7 @@ public void fileRenamed(FileRenameEvent fe) {
388357
}
389358
}
390359

360+
@Override
391361
public void fileAttributeChanged(FileAttributeEvent fe) {
392362
}
393363
}

0 commit comments

Comments
 (0)