update mappings, fix NIO resource pack support on paulscode, minor cleanup/tweaks (#103)

This commit is contained in:
Adrian Siekierka 2019-02-22 23:21:54 +01:00 committed by GitHub
parent d9e25ac47b
commit 5c683237dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 262 additions and 31 deletions

View file

@ -26,8 +26,8 @@ targetCompatibility = 1.8
archivesBaseName = "fabric"
def baseVersion = "0.2.2"
def mcVersion = "19w08a"
def baseVersion = "0.2.3"
def mcVersion = "19w08b"
def ENV = System.getenv()
version = baseVersion + "." + (ENV.BUILD_NUMBER ?: "local")

View file

@ -16,9 +16,9 @@
package net.fabricmc.fabric.api.entity;
import net.minecraft.class_4048;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityCategory;
import net.minecraft.entity.EntitySize;
import net.minecraft.entity.EntityType;
import net.minecraft.world.World;
import org.apache.logging.log4j.LogManager;
@ -36,15 +36,15 @@ import java.util.function.Function;
public class FabricEntityTypeBuilder<T extends Entity> {
private static final Logger LOGGER = LogManager.getLogger();
private final EntityCategory category;
private final EntityType.class_4049 function;
private final EntityType.class_4049<T> function;
private boolean saveable = true;
private boolean summonable = true;
private int trackingDistance = -1;
private int updateIntervalTicks = -1;
private boolean alwaysUpdateVelocity = true;
private class_4048 size = class_4048.method_18385(-1.0f, -1.0f);
private EntitySize size = EntitySize.resizeable(-1.0f, -1.0f);
protected FabricEntityTypeBuilder(EntityCategory category, EntityType.class_4049 function) {
protected FabricEntityTypeBuilder(EntityCategory category, EntityType.class_4049<T> function) {
this.category = category;
this.function = function;
}
@ -61,7 +61,7 @@ public class FabricEntityTypeBuilder<T extends Entity> {
return create(category, (t, w) -> function.apply(w));
}
public static <T extends Entity> FabricEntityTypeBuilder<T> create(EntityCategory category, EntityType.class_4049 function) {
public static <T extends Entity> FabricEntityTypeBuilder<T> create(EntityCategory category, EntityType.class_4049<T> function) {
return new FabricEntityTypeBuilder<>(category, function);
}
@ -76,15 +76,15 @@ public class FabricEntityTypeBuilder<T extends Entity> {
}
/**
* @deprecated Use {@link FabricEntityTypeBuilder#size(class_4048)}
* @deprecated Use {@link FabricEntityTypeBuilder#size(EntitySize)}
*/
@Deprecated
public FabricEntityTypeBuilder<T> size(float width, float height) {
this.size = class_4048.method_18385(width, height);
this.size = EntitySize.resizeable(width, height);
return this;
}
public FabricEntityTypeBuilder<T> size(class_4048 size) {
public FabricEntityTypeBuilder<T> size(EntitySize size) {
this.size = size;
return this;
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.impl.resources;
import net.minecraft.util.Void;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.*;
/**
* InputStream deferring to a separate I/O thread to work around
* Thread.interrupt()-related issues in NIO.
*/
class DeferredInputStream extends InputStream {
private final InputStream stream;
public static InputStream deferIfNeeded(Callable<InputStream> streamSupplier) throws IOException {
if (DeferredNioExecutionHandler.shouldDefer()) {
return new DeferredInputStream(streamSupplier);
} else {
return DeferredNioExecutionHandler.submit(streamSupplier, false);
}
}
DeferredInputStream(Callable<InputStream> streamSupplier) throws IOException {
stream = DeferredNioExecutionHandler.submit(streamSupplier);
if (stream == null) {
throw new IOException("Something happened while trying to create an InputStream!");
}
}
DeferredInputStream(InputStream stream) throws IOException {
this.stream = stream;
if (this.stream == null) {
throw new IOException("Something happened while trying to create an InputStream!");
}
}
@Override
public int available() throws IOException {
return DeferredNioExecutionHandler.submit(stream::available);
}
@Override
public boolean markSupported() {
return stream.markSupported();
}
@Override
public void mark(int readLimit) {
stream.mark(readLimit);
}
@Override
public void reset() throws IOException {
DeferredNioExecutionHandler.submit(() -> {
stream.reset();
return Void.INSTANCE;
});
}
@Override
public long skip(long n) throws IOException {
return DeferredNioExecutionHandler.submit(() -> stream.skip(n));
}
@Override
public int read() throws IOException {
return DeferredNioExecutionHandler.submit(stream::read);
}
@Override
public int read(byte[] b) throws IOException {
return DeferredNioExecutionHandler.submit(() -> stream.read(b));
}
@Override
public int read(byte[] b, int offset, int length) throws IOException {
return DeferredNioExecutionHandler.submit(() -> stream.read(b, offset, length));
}
@Override
public void close() throws IOException {
DeferredNioExecutionHandler.submit(() -> {
stream.close();
return Void.INSTANCE;
});
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.impl.resources;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.io.IOException;
import java.util.concurrent.*;
class DeferredNioExecutionHandler {
private static final ThreadLocal<Boolean> DEFERRED_REQUIRED = new ThreadLocal<>();
private static ExecutorService EXECUTOR_SERVICE;
public static boolean shouldDefer() {
Boolean deferRequired = DEFERRED_REQUIRED.get();
if (deferRequired == null) {
deferRequired = false;
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for (int i = 0; i < elements.length; i++) {
if (elements[i].getClassName().startsWith("paulscode.sound.")) {
deferRequired = true;
break;
}
}
DEFERRED_REQUIRED.set(deferRequired);
}
return deferRequired;
}
public static <V> V submit(Callable<V> callable, boolean cond) throws IOException {
try {
return cond ? submit(callable) : callable.call();
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("Exception which should not happen!", e);
}
}
public static <V> V submit(Callable<V> callable) throws IOException {
if (EXECUTOR_SERVICE == null) {
EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder()
.setNameFormat("Fabric Deferred I/O Thread")
.build()
);
}
Future<V> future = EXECUTOR_SERVICE.submit(callable);
return getSubmittedFuture(future);
}
static <V> V getSubmittedFuture(Future<V> future) throws IOException {
while (true) {
try {
return future.get();
} catch (ExecutionException e) {
Throwable t = e.getCause();
if (t instanceof IOException) {
throw (IOException) t;
} else {
throw new RuntimeException("ExecutionException which should not happen!", t);
}
} catch (InterruptedException e) {
// keep calm, carry on...
}
}
}
}

View file

@ -16,18 +16,16 @@
package net.fabricmc.fabric.impl.resources;
import com.google.common.base.Joiner;
import net.fabricmc.fabric.api.resource.ModResourcePack;
import net.fabricmc.loader.api.metadata.ModMetadata;
import net.minecraft.resource.AbstractFilenameResourcePack;
import net.minecraft.resource.ResourceNotFoundException;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import net.minecraft.util.InvalidIdentifierException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
@ -36,7 +34,6 @@ import java.nio.file.Path;
import java.util.*;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class ModNioResourcePack extends AbstractFilenameResourcePack implements ModResourcePack {
private static final Logger LOGGER = LogManager.getLogger();
@ -68,16 +65,34 @@ public class ModNioResourcePack extends AbstractFilenameResourcePack implements
@Override
protected InputStream openFilename(String filename) throws IOException {
Path path = getPath(filename);
if (path != null && Files.isRegularFile(path)) {
return Files.newInputStream(path);
InputStream stream;
if (DeferredNioExecutionHandler.shouldDefer()) {
stream = DeferredNioExecutionHandler.submit(() -> {
Path path = getPath(filename);
if (path != null && Files.isRegularFile(path)) {
return new DeferredInputStream(Files.newInputStream(path));
} else {
return null;
}
});
if (stream != null) {
return stream;
}
} else {
Path path = getPath(filename);
if (path != null && Files.isRegularFile(path)) {
return Files.newInputStream(path);
}
}
InputStream stream = ModResourcePackUtil.openDefault(modInfo, filename);
if (stream == null) {
throw new ResourceNotFoundException(this.base, filename);
stream = ModResourcePackUtil.openDefault(modInfo, filename);
if (stream != null) {
return stream;
}
return stream;
// ReloadableResourceManagerImpl gets away with FileNotFoundException.
throw new FileNotFoundException("\"" + filename + "\" in Fabric mod \"" + modInfo.getId() + "\"");
}
@Override
@ -86,8 +101,19 @@ public class ModNioResourcePack extends AbstractFilenameResourcePack implements
return true;
}
Path path = getPath(filename);
return path != null && Files.isRegularFile(path);
if (DeferredNioExecutionHandler.shouldDefer()) {
try {
return DeferredNioExecutionHandler.submit(() -> {
Path path = getPath(filename);
return path != null && Files.isRegularFile(path);
});
} catch (IOException e) {
return false;
}
} else {
Path path = getPath(filename);
return path != null && Files.isRegularFile(path);
}
}
@Override

View file

@ -62,7 +62,7 @@ public final class ModResourcePackUtil {
case "pack.png":
return ModResourcePackUtil.class.getClassLoader().getResourceAsStream("assets/fabric/textures/misc/default_icon.png");
case "pack.mcmeta":
String description = info.getId(); // TODO getName
String description = info.getName();
if (description == null) {
description = "";
} else {
@ -71,15 +71,15 @@ public final class ModResourcePackUtil {
String pack = String.format("{\"pack\":{\"pack_format\":" + PACK_FORMAT_VERSION + ",\"description\":\"%s\"}}", description);
return IOUtils.toInputStream(pack, Charsets.UTF_8);
default:
throw new RuntimeException("Mismatch with .containsDefault(...)!");
return null;
}
}
public static String getName(ModMetadata info) {
/* if (info.getName() != null) {
if (info.getName() != null) {
return info.getName();
} else */ { // TODO getName
return "Fabric Mod \"" + info.getId() + "\"";
} else {
return "Fabric Mod \"" + info.getId() + "\"";
}
}
}

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.mixin.resources;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import net.fabricmc.fabric.impl.resources.ModResourcePackUtil;
import net.minecraft.client.MinecraftClient;
@ -33,6 +34,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@ -44,22 +46,33 @@ public class MixinMinecraftGame {
private void fabric_modifyResourcePackList(List<ResourcePack> list) {
List<ResourcePack> oldList = Lists.newArrayList(list);
list.clear();
boolean appended = false;
for (int i = 0; i < oldList.size(); i++) {
ResourcePack pack = oldList.get(i);
list.add(pack);
if (pack instanceof DefaultClientResourcePack) {
ModResourcePackUtil.appendModResourcePacks(list, ResourceType.ASSETS);
appended = true;
}
}
if (!appended) {
StringBuilder builder = new StringBuilder("Fabric could not find resource pack injection location!");
for (ResourcePack rp : oldList) {
builder.append("\n - ").append(rp.getName()).append(" (").append(rp.getClass().getName()).append(")");
}
throw new RuntimeException(builder.toString());
}
}
@Inject(method = "init", at = @At(value = "INVOKE", target = "Ljava/util/List;iterator()Ljava/util/Iterator;", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD)
@Inject(method = "init", at = @At(value = "INVOKE", target = "Ljava/util/List;iterator()Ljava/util/Iterator;", ordinal = 0, shift = At.Shift.BY, by = -2), locals = LocalCapture.CAPTURE_FAILHARD)
public void initResources(CallbackInfo info, List<ResourcePack> list) {
fabric_modifyResourcePackList(list);
}
@Inject(method = "reloadResources", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;method_18502(Lnet/minecraft/class_4071;)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD)
@Inject(method = "reloadResources", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ReloadableResourceManager;method_18232(Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;Ljava/util/concurrent/CompletableFuture;Ljava/util/List;)Lnet/minecraft/resource/ResourceReloadHandler;", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD)
public void reloadResources(CallbackInfoReturnable<CompletableFuture> info, CompletableFuture<java.lang.Void> cf, List<ResourcePack> list) {
fabric_modifyResourcePackList(list);
}

View file

@ -1,7 +1,7 @@
{
"id": "fabric",
"name": "Fabric API",
"version": "0.2.2",
"version": "0.2.3",
"side": "universal",
"description": "Core API module providing key hooks and intercompatibility features.",
"license": "Apache-2.0",