package speiger.src.coreengine.assets.impl; import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.coreengine.assets.AssetLocation; import speiger.src.coreengine.assets.IAsset; import speiger.src.coreengine.assets.IAssetPackage; import speiger.src.coreengine.assets.IAssetParser; public class ZipAssetPackage implements IAssetPackage { Path baseFolder; Function, IAssetParser> parsers; FileSystem cache; AtomicInteger usedReferences = new AtomicInteger(); Runnable referenceCleaner = this::cleanReference; public ZipAssetPackage(File file) { this(file.toPath()); } public ZipAssetPackage(Path baseFolder) { this.baseFolder = baseFolder; } @Override public void setParsers(Function, IAssetParser> parsers) { this.parsers = parsers; } private void cleanReference() { int left = usedReferences.decrementAndGet(); if(left == 0 && cache != null) { try { cache.close(); } catch(Exception e) {e.printStackTrace();} cache = null; } else if(left < 0) usedReferences.set(0); } protected FileSystem getReference() throws IOException { usedReferences.getAndIncrement(); if(cache == null) cache = FileSystems.newFileSystem(baseFolder, null); return cache; } @Override public List getDomains() { List domains = new ObjectArrayList<>(); try(FileSystem system = FileSystems.newFileSystem(baseFolder, null)) { try(DirectoryStream dirs = Files.newDirectoryStream(system.getPath("assets"))) { for(Path path : dirs) { String s = path.getFileName().toString(); domains.add(s.substring(0, s.length()-1)); } } catch(Exception e) { e.printStackTrace(); } } catch(Exception e) { e.printStackTrace(); } return domains; } @Override public IAsset getAsset(AssetLocation location) { try { Path path = getReference().getPath(location.getActualLocation()); return Files.exists(path) ? new ZipAsset(referenceCleaner, location, path, parsers) : null; } catch(Exception e) { return null; } } }