Skip to content

Commit b80117d

Browse files
committed
Improve NativeLibraryLoader.
1 parent 5e859d5 commit b80117d

File tree

7 files changed

+290
-204
lines changed

7 files changed

+290
-204
lines changed

jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ public void initialize(AppSettings settings) {
285285
logger.log(Level.INFO, getBuildInfo());
286286
if (!lowPermissions) {
287287
if (NativeLibraryLoader.isUsingNativeBullet()) {
288-
NativeLibraryLoader.loadNativeLibrary("bulletjme", true);
288+
NativeLibraryLoader.loadNativeLibrary(NativeLibraries.BulletJme.getName(), true);
289289
}
290290
}
291291
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
* Copyright (c) 2009-2023 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.system;
33+
34+
import java.nio.file.Paths;
35+
import java.util.ArrayList;
36+
import java.util.List;
37+
import java.util.function.Consumer;
38+
39+
/**
40+
* Defines default native libraries used by jMonkeyEngine.
41+
*
42+
* @author Ali-RS
43+
*/
44+
public enum NativeLibraries {
45+
46+
// Note: LWJGL 3 handles its native library extracting & loading using
47+
// its own SharedLibraryLoader.
48+
49+
// LWJGL 2
50+
Lwjgl(new LibraryInfo("lwjgl", libPath ->
51+
// lwjgl handle loading by itself.
52+
System.setProperty("org.lwjgl.librarypath",
53+
Paths.get(libPath).getParent().toAbsolutePath().toString()))
54+
.addNativeVariant(Platform.Windows32, "lwjgl.dll")
55+
.addNativeVariant(Platform.Windows64, "lwjgl64.dll")
56+
.addNativeVariant(Platform.Linux32, "liblwjgl.so")
57+
.addNativeVariant(Platform.Linux64, "liblwjgl64.so")
58+
.addNativeVariant(Platform.MacOSX32, "liblwjgl.dylib")
59+
.addNativeVariant(Platform.MacOSX64, "liblwjgl.dylib")
60+
),
61+
62+
// OpenAL for LWJGL 2
63+
// For OSX: Need to add lib prefix when extracting
64+
Openal(new LibraryInfo("openal")
65+
.addNativeVariant(Platform.Windows32, "OpenAL32.dll")
66+
.addNativeVariant(Platform.Windows64, "OpenAL64.dll")
67+
.addNativeVariant(Platform.Linux32, "libopenal.so")
68+
.addNativeVariant(Platform.Linux64, "libopenal64.so")
69+
.addNativeVariant(Platform.MacOSX32, "openal.dylib", "libopenal.dylib")
70+
.addNativeVariant(Platform.MacOSX64, "openal.dylib", "libopenal.dylib")
71+
),
72+
73+
// BulletJme
74+
BulletJme(new LibraryInfo("bulletjme")
75+
.addNativeVariant(Platform.Windows32, "native/windows/x86/bulletjme.dll", "bulletjme-x86.dll")
76+
.addNativeVariant(Platform.Windows64, "native/windows/x86_64/bulletjme.dll", "bulletjme-x86_64.dll")
77+
.addNativeVariant(Platform.Windows_ARM64, "native/windows/arm64/bulletjme.dll", "bulletjme-arm64.dll")
78+
.addNativeVariant(Platform.Linux32, "native/linux/x86/libbulletjme.so", "libbulletjme-x86.so")
79+
.addNativeVariant(Platform.Linux64, "native/linux/x86_64/libbulletjme.so", "libbulletjme-x86_64.so")
80+
.addNativeVariant(Platform.Linux_ARM32, "native/linux/arm32/libbulletjme.so", "libbulletjme-arm32.so")
81+
.addNativeVariant(Platform.Linux_ARM64, "native/linux/arm64/libbulletjme.so", "libbulletjme-arm64.so")
82+
.addNativeVariant(Platform.MacOSX32, "native/osx/x86/libbulletjme.dylib", "libbulletjme-x86.dylib")
83+
.addNativeVariant(Platform.MacOSX64, "native/osx/x86_64/libbulletjme.dylib", "libbulletjme-x86_64.dylib")
84+
.addNativeVariant(Platform.MacOSX_ARM64, "native/osx/arm64/libbulletjme.dylib", "libbulletjme-arm64.dylib")
85+
),
86+
87+
// JInput
88+
// For OSX: Need to rename extension jnilib -> dylib when extracting
89+
JInput(new LibraryInfo("jinput", libPath ->
90+
// jinput handle loading by itself.
91+
System.setProperty("net.java.games.input.librarypath",
92+
Paths.get(libPath).getParent().toAbsolutePath().toString()))
93+
.addNativeVariant(Platform.Windows32, "jinput-raw.dll")
94+
.addNativeVariant(Platform.Windows64, "jinput-raw_64.dll")
95+
.addNativeVariant(Platform.Linux32, "libjinput-linux.so")
96+
.addNativeVariant(Platform.Linux64, "libjinput-linux64.so")
97+
.addNativeVariant(Platform.MacOSX32, "libjinput-osx.jnilib", "libjinput-osx.dylib")
98+
.addNativeVariant(Platform.MacOSX64, "libjinput-osx.jnilib", "libjinput-osx.dylib")
99+
),
100+
101+
// JInput Auxiliary (only required on Windows)
102+
JInputDX8(new LibraryInfo("jinput-dx8")
103+
.addNativeVariant(Platform.Windows32, "jinput-dx8.dll", null)
104+
.addNativeVariant(Platform.Windows64, "jinput-dx8_64.dll", null)
105+
.addNativeVariant(Platform.Linux32, null)
106+
.addNativeVariant(Platform.Linux64, null)
107+
.addNativeVariant(Platform.MacOSX32, null)
108+
.addNativeVariant(Platform.MacOSX64, null)
109+
);
110+
111+
private final LibraryInfo library;
112+
113+
114+
NativeLibraries(LibraryInfo library) {
115+
this.library = library;
116+
}
117+
118+
public static void registerDefaultLibraries() {
119+
Lwjgl.registerLibrary();
120+
Openal.registerLibrary();
121+
BulletJme.registerLibrary();
122+
JInput.registerLibrary();
123+
JInputDX8.registerLibrary();
124+
}
125+
126+
public LibraryInfo getLibrary() {
127+
return library;
128+
}
129+
130+
public String getName() {
131+
return library.getName();
132+
}
133+
134+
private void registerLibrary() {
135+
library.getNativeVariants().forEach(NativeLibraryLoader::registerNativeLibrary);
136+
}
137+
138+
public static class LibraryInfo {
139+
140+
private final String name;
141+
private final List<NativeLibrary> nativeVariants = new ArrayList<>();
142+
private final Consumer<String> loadFunction;
143+
144+
public LibraryInfo(String name) {
145+
this(name, System::load);
146+
}
147+
148+
public LibraryInfo(String name, Consumer<String> loadFunction) {
149+
this.name = name;
150+
this.loadFunction = loadFunction;
151+
}
152+
153+
public String getName() {
154+
return name;
155+
}
156+
157+
public List<NativeLibrary> getNativeVariants() {
158+
return nativeVariants;
159+
}
160+
161+
public LibraryInfo addNativeVariant(Platform platform, String pathInNativesJar) {
162+
return addNativeVariant(platform, pathInNativesJar, null);
163+
}
164+
165+
public LibraryInfo addNativeVariant(Platform platform, String pathInNativesJar, String extractedAsFileName) {
166+
nativeVariants.add(new NativeLibrary(name, platform, pathInNativesJar, extractedAsFileName, loadFunction));
167+
return this;
168+
}
169+
}
170+
}

jme3-desktop/src/main/java/com/jme3/system/NativeLibrary.java

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2012 jMonkeyEngine
2+
* Copyright (c) 2009-2023 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
3131
*/
3232
package com.jme3.system;
3333

34+
import java.util.function.Consumer;
35+
3436
/**
3537
* Holds information about a native library for a particular platform.
3638
*
@@ -42,6 +44,7 @@ final class NativeLibrary {
4244
private final Platform platform;
4345
private final String pathInNativesJar;
4446
private final String extractedAsFileName;
47+
private final Consumer<String> loadFunction;
4548

4649
/**
4750
* Key for map to find a library for a name and platform.
@@ -76,6 +79,31 @@ public boolean equals(Object obj) {
7679
return true;
7780
}
7881
}
82+
83+
/**
84+
* Create a new NativeLibrary.
85+
*/
86+
public NativeLibrary(String name, Platform platform, String pathInNativesJar) {
87+
this(name, platform, pathInNativesJar, null);
88+
}
89+
90+
/**
91+
* Create a new NativeLibrary.
92+
*/
93+
public NativeLibrary(String name, Platform platform, String pathInNativesJar, String extractedAsFileName) {
94+
this(name, platform, pathInNativesJar, extractedAsFileName, System::load);
95+
}
96+
97+
/**
98+
* Create a new NativeLibrary.
99+
*/
100+
public NativeLibrary(String name, Platform platform, String pathInNativesJar, String extractedAsFileName, Consumer<String> loadFunction) {
101+
this.name = name;
102+
this.platform = platform;
103+
this.pathInNativesJar = pathInNativesJar;
104+
this.extractedAsFileName = extractedAsFileName;
105+
this.loadFunction = loadFunction;
106+
}
79107

80108
/**
81109
* The name of the library.
@@ -90,7 +118,7 @@ public String getName() {
90118
/**
91119
* The OS + architecture combination for which this library
92120
* should be extracted.
93-
*
121+
*
94122
* @return platform associated to this native library
95123
*/
96124
public Platform getPlatform() {
@@ -99,12 +127,12 @@ public Platform getPlatform() {
99127

100128
/**
101129
* The filename that the library should be extracted as.
102-
*
130+
*
103131
* In some cases, this differs from the {@link #getPathInNativesJar() path in the natives jar},
104132
* since the names of the libraries specified in the jars are often incorrect.
105133
* If set to <code>null</code>, then the filename in the
106134
* natives jar shall be used.
107-
*
135+
*
108136
* @return the name that should be given to the extracted file.
109137
*/
110138
public String getExtractedAsName() {
@@ -113,30 +141,29 @@ public String getExtractedAsName() {
113141

114142
/**
115143
* Path inside the natives jar or classpath where the library is located.
116-
*
144+
*
117145
* This library must be compatible with the {@link #getPlatform() platform}
118146
* which this library is associated with.
119-
*
147+
*
120148
* @return path to the library in the classpath
121149
*/
122150
public String getPathInNativesJar() {
123151
return pathInNativesJar;
124152
}
125153

126154
/**
127-
* Create a new NativeLibrary.
155+
* @return the load function used for loading this native library.
156+
* It loads the native library from absolute path on disk.
157+
* By default, it loads with {@link System#load(java.lang.String) }.
128158
*/
129-
public NativeLibrary(String name, Platform platform, String pathInNativesJar, String extractedAsFileName) {
130-
this.name = name;
131-
this.platform = platform;
132-
this.pathInNativesJar = pathInNativesJar;
133-
this.extractedAsFileName = extractedAsFileName;
159+
public Consumer<String> getLoadFunction() {
160+
return loadFunction;
134161
}
135162

136163
/**
137-
* Create a new NativeLibrary.
164+
* @return key for map to find a library for a name and platform.
138165
*/
139-
public NativeLibrary(String name, Platform platform, String pathInNativesJar) {
140-
this(name, platform, pathInNativesJar, null);
166+
public Key getKey() {
167+
return new NativeLibrary.Key(getName(), getPlatform());
141168
}
142169
}

0 commit comments

Comments
 (0)