116 lines
4.0 KiB
Java
116 lines
4.0 KiB
Java
package io.gitlab.jfronny.aps.client.mixin;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.Lists;
|
|
import io.gitlab.jfronny.aps.client.impl.ResourcePackOrganizerLockState;
|
|
import io.gitlab.jfronny.libjf.LibJf;
|
|
import net.fabricmc.fabric.impl.resource.loader.FabricResourcePackProfile;
|
|
import net.minecraft.client.gui.screen.pack.ResourcePackOrganizer;
|
|
import net.minecraft.resource.ResourcePackManager;
|
|
import net.minecraft.resource.ResourcePackProfile;
|
|
import org.spongepowered.asm.mixin.*;
|
|
|
|
import java.util.List;
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.concurrent.Future;
|
|
import java.util.stream.Stream;
|
|
|
|
@Mixin(ResourcePackOrganizer.class)
|
|
public abstract class ResourcePackOrganizerMixin {
|
|
@Shadow @Final private ResourcePackManager resourcePackManager;
|
|
@Shadow @Final List<ResourcePackProfile> enabledPacks;
|
|
@Shadow @Final List<ResourcePackProfile> disabledPacks;
|
|
|
|
@Unique private Future<Void> aps$packScan = null;
|
|
@Unique private final ResourcePackOrganizerLockState aps$lock = new ResourcePackOrganizerLockState();
|
|
|
|
/**
|
|
* @author JFronny
|
|
* @reason Make reloading asynchronous
|
|
*/
|
|
@Overwrite
|
|
public void refresh() {
|
|
if (aps$lock.requestScan().shouldStart()) aps$startScan();
|
|
}
|
|
|
|
@Unique
|
|
private void aps$startScan() {
|
|
Future<Void>[] tasks = new Future[1];
|
|
aps$packScan = tasks[0] = resourcePackManager.scanPacksAsync(() -> aps$afterScan(tasks[0]));
|
|
}
|
|
|
|
@Unique
|
|
private void aps$afterScan(Future<Void> task) {
|
|
try (var lock = aps$lock.lockResources()) {
|
|
if (task.isCancelled()) return;
|
|
enabledPacks.retainAll(resourcePackManager.getProfiles());
|
|
disabledPacks.clear();
|
|
disabledPacks.addAll(resourcePackManager.getProfiles());
|
|
disabledPacks.removeAll(enabledPacks);
|
|
filterFabricPacks(enabledPacks);
|
|
filterFabricPacks(disabledPacks);
|
|
if (aps$packScan == task) aps$packScan = null;
|
|
}
|
|
if (aps$lock.emitScanFinished().shouldContinue()) aps$startScan();
|
|
}
|
|
|
|
@Unique
|
|
private void filterFabricPacks(List<ResourcePackProfile> list) {
|
|
list.removeIf(profile -> profile instanceof FabricResourcePackProfile prpp && prpp.fabric_isHidden());
|
|
}
|
|
|
|
/**
|
|
* @author JFronny
|
|
* @reason Inject lock and resynchronize from pack scan
|
|
*/
|
|
@Overwrite
|
|
public void refreshEnabledProfiles() {
|
|
try {
|
|
if (aps$packScan != null) {
|
|
aps$packScan.get();
|
|
}
|
|
try (var lock = aps$lock.lockResources()) {
|
|
// Vanilla statement, copied into here
|
|
this.resourcePackManager.setEnabledProfiles(
|
|
Lists.reverse(this.enabledPacks)
|
|
.stream()
|
|
.map(ResourcePackProfile::getId)
|
|
.collect(ImmutableList.toImmutableList())
|
|
);
|
|
}
|
|
} catch (InterruptedException | ExecutionException e) {
|
|
LibJf.LOGGER.error("Pack scan was interrupted", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @author JFronny
|
|
* @reason Inject lock
|
|
*/
|
|
@Overwrite
|
|
public Stream<ResourcePackOrganizer.Pack> getDisabledPacks() {
|
|
try (var lock = aps$lock.lockResources()) {
|
|
return this.disabledPacks
|
|
.stream()
|
|
.<ResourcePackOrganizer.Pack>map(pack -> ((ResourcePackOrganizer) (Object) this).new DisabledPack(pack))
|
|
.toList()
|
|
.stream();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @author JFronny
|
|
* @reason Inject lock
|
|
*/
|
|
@Overwrite
|
|
public Stream<ResourcePackOrganizer.Pack> getEnabledPacks() {
|
|
try (var lock = aps$lock.lockResources()) {
|
|
return this.enabledPacks
|
|
.stream()
|
|
.<ResourcePackOrganizer.Pack>map(pack -> ((ResourcePackOrganizer) (Object) this).new EnabledPack(pack))
|
|
.toList()
|
|
.stream();
|
|
}
|
|
}
|
|
}
|