81 lines
3.2 KiB
Java
Executable File
81 lines
3.2 KiB
Java
Executable File
package net.rubygrapefruit.platform;
|
|
|
|
import net.rubygrapefruit.platform.internal.NativeLibraryLoader;
|
|
import net.rubygrapefruit.platform.internal.NativeLibraryLocator;
|
|
import net.rubygrapefruit.platform.internal.Platform;
|
|
import net.rubygrapefruit.platform.internal.jni.NativeLibraryFunctions;
|
|
|
|
import java.io.File;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* Provides access to the native integrations. Use {@link #get(Class)} to load a particular integration.
|
|
*/
|
|
@ThreadSafe
|
|
public class Native {
|
|
private static NativeLibraryLoader loader;
|
|
private static final Map<Class<?>, Object> integrations = new HashMap<Class<?>, Object>();
|
|
|
|
private Native() {
|
|
}
|
|
|
|
/**
|
|
* Initialises the native integration, if not already initialized.
|
|
*
|
|
* @param extractDir The directory to extract native resources into. May be null, in which case a default is
|
|
* selected.
|
|
*
|
|
* @throws NativeIntegrationUnavailableException When native integration is not available on the current machine.
|
|
* @throws NativeException On failure to load the native integration.
|
|
*/
|
|
@ThreadSafe
|
|
static public void init(File extractDir) throws NativeIntegrationUnavailableException, NativeException {
|
|
synchronized (Native.class) {
|
|
if (loader == null) {
|
|
Platform platform = Platform.current();
|
|
try {
|
|
loader = new NativeLibraryLoader(new NativeLibraryLocator(extractDir));
|
|
loader.load(platform.getLibraryName());
|
|
int nativeVersion = NativeLibraryFunctions.getVersion();
|
|
if (nativeVersion != NativeLibraryFunctions.VERSION) {
|
|
throw new NativeException(String.format("Unexpected native library version loaded. Expected %s, was %s.", nativeVersion, NativeLibraryFunctions.VERSION));
|
|
}
|
|
} catch (NativeException e) {
|
|
throw e;
|
|
} catch (Throwable t) {
|
|
throw new NativeException("Failed to initialise native integration.", t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Locates a native integration of the given type.
|
|
*
|
|
* @return The native integration. Never returns null.
|
|
* @throws NativeIntegrationUnavailableException When the given native integration is not available on the current
|
|
* machine.
|
|
* @throws NativeException On failure to load the native integration.
|
|
*/
|
|
@ThreadSafe
|
|
public static <T extends NativeIntegration> T get(Class<T> type)
|
|
throws NativeIntegrationUnavailableException, NativeException {
|
|
init(null);
|
|
synchronized (Native.class) {
|
|
Object instance = integrations.get(type);
|
|
if (instance == null) {
|
|
try {
|
|
instance = Platform.current().get(type, loader);
|
|
} catch (NativeException e) {
|
|
throw e;
|
|
} catch (Throwable t) {
|
|
throw new NativeException(String.format("Failed to load native integration %s.", type.getSimpleName()), t);
|
|
}
|
|
integrations.put(type, instance);
|
|
}
|
|
return type.cast(instance);
|
|
}
|
|
}
|
|
}
|