Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand All @@ -32,7 +33,7 @@
@ApiStatus.Internal
public class Rapier3D {

private static final String NATIVE_DIR = ".sable/natives";
private static final Path NATIVE_DIR = resolveNativeDir();
private static final String LIB_NAME = "sable_rapier";

public static final String NATIVE_NAME = getNativeName();
Expand All @@ -44,6 +45,32 @@ public class Rapier3D {
loadLibrary();
}

private static Path resolveNativeDir() {
// Trying to get game directory
final Path gameDir = SableGameDirectoryPlatform.INSTANCE.getGameDirectory();
if (gameDir != null) {
final Path gameDirRelativeDir = gameDir.resolve(".sable").resolve("natives").normalize();
Sable.LOGGER.info("Using game-dir-relative Rapier native directory {}",
gameDirRelativeDir.toAbsolutePath());
return gameDirRelativeDir;
}

// Using a bit overly generic ~/.sable directory as a fallback
final Path fallbackDir = Paths.get(System.getProperty("user.home", System.getProperty("user.dir")), ".sable",
"natives");
Sable.LOGGER.info("Using fallback Rapier native directory {}", fallbackDir.toAbsolutePath());
return fallbackDir;
}

private static Path getCodeSourcePath() {
try {
return Paths.get(Rapier3D.class.getProtectionDomain().getCodeSource().getLocation().toURI());
} catch (final URISyntaxException | SecurityException e) {
Sable.LOGGER.debug("Unable to resolve Rapier code source path, falling back to user home", e);
return null;
}
}

private static String getNativeName() {
final String arch;
if (System.getProperty("os.arch").equals("arm") || System.getProperty("os.arch").startsWith("aarch64")) {
Expand All @@ -59,23 +86,28 @@ private static String getNativeName() {
return LIB_NAME + "_" + arch + "_macos.dylib";
} else {
if (os != OS.LINUX) {
Sable.LOGGER.error("Unknown platform '{}' detected, sable will attempt to use linux natives, this may or may not work.", System.getProperty("os.name"));
Sable.LOGGER.error(
"Unknown platform '{}' detected, sable will attempt to use linux natives, this may or may not work.",
System.getProperty("os.name"));
}
return LIB_NAME + "_" + arch + "_linux.so";
}
}

private static void loadLibrary() {
try (final InputStream is = Rapier3D.class.getResourceAsStream("/natives/" + LIB_NAME + "/sable_rapier_binaries.zip.l4z")) {
try (final InputStream is = Rapier3D.class
.getResourceAsStream("/natives/" + LIB_NAME + "/sable_rapier_binaries.zip.l4z")) {
if (is == null) {
throw new FileNotFoundException("sable_rapier_binaries.zip.l4z");
}

final Path dir = Paths.get(NATIVE_DIR);
final Path dir = NATIVE_DIR;
if (!Files.exists(dir)) {
Files.createDirectories(dir);
}

Sable.LOGGER.info("Using Rapier native directory {}", dir.toAbsolutePath());

try (final LZ4FrameInputStream is2 = new LZ4FrameInputStream(is);
final ZipInputStream ti = new ZipInputStream(is2)) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.ryanhcode.sable.platform;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.nio.file.Path;

@ApiStatus.Internal
public interface SableGameDirectoryPlatform {
SableGameDirectoryPlatform INSTANCE = SablePlatformUtil.load(SableGameDirectoryPlatform.class);

/**
* @return the absolute game directory for the current loader, or {@code null}
* if it is unavailable.
*/
@Nullable
Path getGameDirectory();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.ryanhcode.sable.fabric.platform;

import dev.ryanhcode.sable.platform.SableGameDirectoryPlatform;
import net.fabricmc.loader.api.FabricLoader;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.nio.file.Path;

@ApiStatus.Internal
public class SableGameDirectoryPlatformImpl implements SableGameDirectoryPlatform {

@Override
@Nullable
public Path getGameDirectory() {
return FabricLoader.getInstance().getGameDir();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dev.ryanhcode.sable.fabric.platform.SableGameDirectoryPlatformImpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.ryanhcode.sable.neoforge.platform;

import dev.ryanhcode.sable.platform.SableGameDirectoryPlatform;
import net.minecraftforge.fml.loading.FMLPaths;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.nio.file.Path;

@ApiStatus.Internal
public class SableGameDirectoryPlatformImpl implements SableGameDirectoryPlatform {

@Override
@Nullable
public Path getGameDirectory() {
return FMLPaths.GAMEDIR.get();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dev.ryanhcode.sable.neoforge.platform.SableGameDirectoryPlatformImpl