Improve performance and cleanup code for DelegatingResourcePack (#7228)

This commit is contained in:
Take Weiland 2020-08-21 19:48:48 +02:00 committed by GitHub
parent 797791c2af
commit 50197b1fa5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 98 deletions

View file

@ -63,7 +63,6 @@ import net.minecraftforge.fml.VersionChecker;
import net.minecraftforge.fml.client.gui.screen.LoadingErrorScreen; import net.minecraftforge.fml.client.gui.screen.LoadingErrorScreen;
import net.minecraftforge.fml.client.registry.RenderingRegistry; import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.packs.DelegatableResourcePack;
import net.minecraftforge.fml.packs.DelegatingResourcePack; import net.minecraftforge.fml.packs.DelegatingResourcePack;
import net.minecraftforge.fml.packs.ModFileResourcePack; import net.minecraftforge.fml.packs.ModFileResourcePack;
import net.minecraftforge.fml.packs.ResourcePackLoader; import net.minecraftforge.fml.packs.ResourcePackLoader;
@ -188,7 +187,7 @@ public class ClientModLoader
} }
private static void clientPackFinder(Map<ModFile, ? extends ModFileResourcePack> modResourcePacks, BiConsumer<? super ModFileResourcePack, ResourcePackInfo> packSetter, Consumer<ResourcePackInfo> consumer, ResourcePackInfo.IFactory factory) { private static void clientPackFinder(Map<ModFile, ? extends ModFileResourcePack> modResourcePacks, BiConsumer<? super ModFileResourcePack, ResourcePackInfo> packSetter, Consumer<ResourcePackInfo> consumer, ResourcePackInfo.IFactory factory) {
List<DelegatableResourcePack> hiddenPacks = new ArrayList<>(); List<ModFileResourcePack> hiddenPacks = new ArrayList<>();
for (Entry<ModFile, ? extends ModFileResourcePack> e : modResourcePacks.entrySet()) for (Entry<ModFile, ? extends ModFileResourcePack> e : modResourcePacks.entrySet())
{ {
IModInfo mod = e.getKey().getModInfos().get(0); IModInfo mod = e.getKey().getModInfos().get(0);

View file

@ -1,40 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2020.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.packs;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import net.minecraft.resources.ResourcePack;
public abstract class DelegatableResourcePack extends ResourcePack
{
protected DelegatableResourcePack(File resourcePackFileIn)
{
super(resourcePackFileIn);
}
@Override
public abstract InputStream getInputStream(String resourcePath) throws IOException;
@Override
public abstract boolean resourceExists(String resourcePath);
}

View file

@ -22,14 +22,13 @@ package net.minecraftforge.fml.packs;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import net.minecraft.resources.IResourcePack;
import net.minecraft.resources.ResourcePack; import net.minecraft.resources.ResourcePack;
import net.minecraft.resources.ResourcePackFileNotFoundException; import net.minecraft.resources.ResourcePackFileNotFoundException;
import net.minecraft.resources.ResourcePackType; import net.minecraft.resources.ResourcePackType;
@ -39,29 +38,36 @@ import net.minecraft.util.ResourceLocation;
public class DelegatingResourcePack extends ResourcePack public class DelegatingResourcePack extends ResourcePack
{ {
private final List<DelegatableResourcePack> delegates = new ArrayList<>();
private final List<IResourcePack> delegates;
private final Map<String, List<IResourcePack>> namespacesAssets;
private final Map<String, List<IResourcePack>> namespacesData;
private final String name; private final String name;
private final PackMetadataSection packInfo; private final PackMetadataSection packInfo;
public DelegatingResourcePack(String id, String name, PackMetadataSection packInfo) public DelegatingResourcePack(String id, String name, PackMetadataSection packInfo, List<? extends IResourcePack> packs)
{
this(id, name, packInfo, Collections.emptyList());
}
public DelegatingResourcePack(String id, String name, PackMetadataSection packInfo, List<DelegatableResourcePack> packs)
{ {
super(new File(id)); super(new File(id));
this.name = name; this.name = name;
this.packInfo = packInfo; this.packInfo = packInfo;
packs.forEach(this::addDelegate); this.delegates = ImmutableList.copyOf(packs);
this.namespacesAssets = this.buildNamespaceMap(ResourcePackType.CLIENT_RESOURCES, delegates);
this.namespacesData = this.buildNamespaceMap(ResourcePackType.SERVER_DATA, delegates);
} }
public void addDelegate(DelegatableResourcePack pack) private Map<String, List<IResourcePack>> buildNamespaceMap(ResourcePackType type, List<IResourcePack> packList)
{ {
synchronized(delegates) Map<String, List<IResourcePack>> map = new HashMap<>();
for (IResourcePack pack : packList)
{ {
this.delegates.add(pack); for (String namespace : pack.getResourceNamespaces(type))
{
map.computeIfAbsent(namespace, k -> new ArrayList<>()).add(pack);
}
} }
map.replaceAll((k, list) -> ImmutableList.copyOf(list));
return ImmutableMap.copyOf(map);
} }
@Override @Override
@ -84,69 +90,84 @@ public class DelegatingResourcePack extends ResourcePack
@Override @Override
public Collection<ResourceLocation> getAllResourceLocations(ResourcePackType type, String pathIn, String pathIn2, int maxDepth, Predicate<String> filter) public Collection<ResourceLocation> getAllResourceLocations(ResourcePackType type, String pathIn, String pathIn2, int maxDepth, Predicate<String> filter)
{ {
synchronized(delegates) return delegates.stream()
{ .flatMap(r -> r.getAllResourceLocations(type, pathIn, pathIn2, maxDepth, filter).stream())
return delegates.stream() .collect(Collectors.toList());
.flatMap(r -> r.getAllResourceLocations(type, pathIn, pathIn2, maxDepth, filter).stream())
.collect(Collectors.toList());
}
} }
@Override @Override
public Set<String> getResourceNamespaces(ResourcePackType type) public Set<String> getResourceNamespaces(ResourcePackType type)
{ {
synchronized (delegates) return type == ResourcePackType.CLIENT_RESOURCES ? namespacesAssets.keySet() : namespacesData.keySet();
{
return delegates.stream()
.flatMap(r -> r.getResourceNamespaces(type).stream())
.collect(Collectors.toSet());
}
} }
@Override @Override
public void close() public void close()
{ {
synchronized(delegates) for (IResourcePack pack : delegates)
{ {
for (ResourcePack pack : delegates) pack.close();
{
pack.close();
}
} }
} }
@Override
public InputStream getRootResourceStream(String fileName) throws IOException
{
// root resources do not make sense here
throw new ResourcePackFileNotFoundException(this.file, fileName);
}
@Override @Override
protected InputStream getInputStream(String resourcePath) throws IOException protected InputStream getInputStream(String resourcePath) throws IOException
{ {
if (!resourcePath.equals("pack.png")) // Mods shouldn't be able to mess with the pack icon // never called, we override all methods that call this
{
synchronized (delegates)
{
for (DelegatableResourcePack pack : delegates)
{
if (pack.resourceExists(resourcePath))
{
return pack.getInputStream(resourcePath);
}
}
}
}
throw new ResourcePackFileNotFoundException(this.file, resourcePath); throw new ResourcePackFileNotFoundException(this.file, resourcePath);
} }
@Override @Override
protected boolean resourceExists(String resourcePath) protected boolean resourceExists(String resourcePath)
{ {
synchronized (delegates) // never called, we override all methods that call this
return false;
}
@Override
public InputStream getResourceStream(ResourcePackType type, ResourceLocation location) throws IOException
{
for (IResourcePack pack : getCandidatePacks(type, location))
{ {
for (DelegatableResourcePack pack : delegates) if (pack.resourceExists(type, location))
{ {
if (pack.resourceExists(resourcePath)) return pack.getResourceStream(type, location);
{ }
return true; }
} throw new ResourcePackFileNotFoundException(this.file, getFullPath(type, location));
}
@Override
public boolean resourceExists(ResourcePackType type, ResourceLocation location)
{
for (IResourcePack pack : getCandidatePacks(type, location))
{
if (pack.resourceExists(type, location))
{
return true;
} }
} }
return false; return false;
} }
private List<IResourcePack> getCandidatePacks(ResourcePackType type, ResourceLocation location)
{
Map<String, List<IResourcePack>> map = type == ResourcePackType.CLIENT_RESOURCES ? namespacesAssets : namespacesData;
List<IResourcePack> packsWithNamespace = map.get(location.getNamespace());
return packsWithNamespace == null ? Collections.emptyList() : packsWithNamespace;
}
private static String getFullPath(ResourcePackType type, ResourceLocation location)
{
// stolen from ResourcePack
return String.format("%s/%s/%s", type.getDirectoryName(), location.getNamespace(), location.getPath());
}
} }

View file

@ -19,6 +19,7 @@
package net.minecraftforge.fml.packs; package net.minecraftforge.fml.packs;
import net.minecraft.resources.ResourcePack;
import net.minecraft.resources.ResourcePackFileNotFoundException; import net.minecraft.resources.ResourcePackFileNotFoundException;
import net.minecraft.resources.ResourcePackInfo; import net.minecraft.resources.ResourcePackInfo;
import net.minecraft.resources.ResourcePackType; import net.minecraft.resources.ResourcePackType;
@ -39,7 +40,7 @@ import java.util.stream.Collectors;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
public class ModFileResourcePack extends DelegatableResourcePack public class ModFileResourcePack extends ResourcePack
{ {
private final ModFile modFile; private final ModFile modFile;
private ResourcePackInfo packInfo; private ResourcePackInfo packInfo;
@ -61,7 +62,7 @@ public class ModFileResourcePack extends DelegatableResourcePack
} }
@Override @Override
public InputStream getInputStream(String name) throws IOException protected InputStream getInputStream(String name) throws IOException
{ {
final Path path = modFile.getLocator().findPath(modFile, name); final Path path = modFile.getLocator().findPath(modFile, name);
if(!Files.exists(path)) if(!Files.exists(path))
@ -70,7 +71,7 @@ public class ModFileResourcePack extends DelegatableResourcePack
} }
@Override @Override
public boolean resourceExists(String name) protected boolean resourceExists(String name)
{ {
return Files.exists(modFile.getLocator().findPath(modFile, name)); return Files.exists(modFile.getLocator().findPath(modFile, name));
} }