Refined implementation

FileHandleAdapter changed to abstract class
FileHandleAdapter now incorporates Reader functionality via #adapt(FileHandle,Class)
Removed specialized functions from AsyncAssetLoader (should be callable directly now)
Refactor renamed readers to adapters
AssetLoader changed from interface to abstract class
AssetLoader requires type reference and is more similar to LibGDX implementation
Adjusted test case with new API
This commit is contained in:
collinsmith 2020-09-29 12:10:23 -07:00
parent 0c81104adb
commit 1116e14fc7
9 changed files with 94 additions and 99 deletions

View File

@ -2,7 +2,24 @@ package com.riiablo.assets;
import com.badlogic.gdx.utils.Array;
public interface AssetLoader<T> {
FileHandleResolver resolver();
Array<Asset> getDependencies(Asset<T> asset);
public class AssetLoader<T, V> {
final FileHandleResolver resolver;
final Class<V> type;
protected AssetLoader(FileHandleResolver resolver, Class<V> type) {
this.resolver = resolver;
this.type = type;
}
public final Class<V> type() {
return type;
}
public final FileHandleResolver resolver() {
return resolver;
}
public Array<Asset> getDependencies(Asset<T> asset) {
return null;
}
}

View File

@ -1,6 +1,12 @@
package com.riiablo.assets;
import io.netty.util.AsciiString;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;
import com.riiablo.logger.LogManager;
import com.riiablo.logger.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -11,13 +17,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;
import com.riiablo.logger.LogManager;
import com.riiablo.logger.Logger;
import io.netty.util.AsciiString;
/**
* n io threads perform async io to retrieve ByteBuf or MPQInputStream
@ -34,7 +34,7 @@ public class AssetManager implements Disposable, LoadTask.Callback, AsyncReader.
final ArrayBlockingQueue<LoadTask> completedTasks = new ArrayBlockingQueue<>(256);
final ArrayList<LoadTask> drain = new ArrayList<>(256);
final Map<Class, FileHandleAdapter> readers = new ConcurrentHashMap<>();
final Map<Class, FileHandleAdapter> adapters = new ConcurrentHashMap<>();
final ExecutorService io;
final ExecutorService async;
@ -87,7 +87,7 @@ public class AssetManager implements Disposable, LoadTask.Callback, AsyncReader.
return loader;
}
public <T> void setLoader(Class<T> type, AssetLoader<T> loader) {
public <T> void setLoader(Class<T> type, AssetLoader<T, ?> loader) {
if (type == null) throw new IllegalArgumentException("type cannot be null");
if (loader == null) throw new IllegalArgumentException("loader cannot be null");
log.debug("Loader set {} -> {}", type.getSimpleName(), loader.getClass());
@ -95,7 +95,7 @@ public class AssetManager implements Disposable, LoadTask.Callback, AsyncReader.
}
public FileHandleAdapter getAdapter(Class type) {
return readers.get(type);
return adapters.get(type);
}
FileHandleAdapter findAdapter(Class type) {
@ -108,7 +108,7 @@ public class AssetManager implements Disposable, LoadTask.Callback, AsyncReader.
if (type == null) throw new IllegalArgumentException("type cannot be null");
if (adapter == null) throw new IllegalArgumentException("adapter cannot be null");
log.debug("Adapter set {} -> {}", type.getSimpleName(), adapter.getClass());
readers.put(type, adapter);
adapters.put(type, adapter);
}
public void clear() {
@ -166,7 +166,7 @@ public class AssetManager implements Disposable, LoadTask.Callback, AsyncReader.
if (adapter instanceof AsyncAdapter) {
// io.submit(((AsyncReader) reader).readFuture(asset, this));
} else {
((AsyncAssetLoader) loader).loadAsync(this, asset, adapter, handle);
((AsyncAssetLoader) loader).loadAsync(this, asset, adapter.adapt(handle, loader.type()));
}
} else {
// io.submit(reader.create(asset));

View File

@ -1,31 +1,14 @@
package com.riiablo.assets;
import io.netty.buffer.ByteBuf;
import java.io.InputStream;
import com.badlogic.gdx.files.FileHandle;
public abstract class AsyncAssetLoader<T, F extends FileHandle, V> implements AssetLoader<T> {
final Reader<F, V> reader;
import java.io.InputStream;
public AsyncAssetLoader(Reader<F, V> reader) {
this.reader = reader;
}
import io.netty.buffer.ByteBuf;
protected Reader<F, V> reader() {
return reader;
}
void loadAsync(AssetManager assets, Asset<T> asset, FileHandleAdapter<F> adapter, F handle) {
loadAsync(assets, asset, reader.get(adapter, handle));
}
void unloadAsync(AssetManager assets, Asset<T> asset, FileHandleAdapter<F> adapter, F handle) {
unloadAsync(assets, asset, reader.get(adapter, handle));
}
T loadSync(AssetManager assets, Asset<T> asset, FileHandleAdapter<F> adapter, F handle) {
return loadSync(assets, asset, reader.get(adapter, handle));
public abstract class AsyncAssetLoader<T, V> extends AssetLoader<T, V> {
public AsyncAssetLoader(FileHandleResolver resolver, Class<V> type) {
super(resolver, type);
}
protected abstract void loadAsync(AssetManager assets, Asset<T> asset, V data);

View File

@ -1,12 +1,32 @@
package com.riiablo.assets;
import io.netty.buffer.ByteBuf;
import java.io.InputStream;
import com.badlogic.gdx.files.FileHandle;
public interface FileHandleAdapter<T extends FileHandle> {
byte[] readBytes(T handle);
InputStream read(T handle);
ByteBuf readByteBuf(T handle);
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import io.netty.buffer.ByteBuf;
public abstract class FileHandleAdapter<F extends FileHandle> {
final Class<F> type;
final Map<Class, AsyncAssetLoader.Reader> readers;
protected FileHandleAdapter(Class<F> type) {
this.type = type;
this.readers = new HashMap<>();
readers.put(type, new AsyncAssetLoader.ReflectiveReader<>());
readers.put(InputStream.class, new AsyncAssetLoader.InputStreamReader<>());
readers.put(byte[].class, new AsyncAssetLoader.ByteArrayReader<>());
readers.put(ByteBuf.class, new AsyncAssetLoader.ByteBufReader<>());
}
@SuppressWarnings("unchecked")
public <V> V adapt(F handle, Class<V> type) {
return (V) readers.get(type).get(this, handle);
}
public abstract byte[] readBytes(F handle);
public abstract InputStream read(F handle);
public abstract ByteBuf readByteBuf(F handle);
}

View File

@ -1,11 +1,16 @@
package com.riiablo.assets;
import io.netty.buffer.ByteBuf;
import java.io.InputStream;
import com.badlogic.gdx.files.FileHandle;
public class GdxFileHandleAdapter implements FileHandleAdapter<FileHandle> {
import java.io.InputStream;
import io.netty.buffer.ByteBuf;
public final class GdxFileHandleAdapter extends FileHandleAdapter<FileHandle> {
public GdxFileHandleAdapter() {
super(FileHandle.class);
}
@Override
public byte[] readBytes(FileHandle handle) {
return handle.readBytes();

View File

@ -1,11 +1,16 @@
package com.riiablo.assets;
import io.netty.buffer.ByteBuf;
import java.io.InputStream;
import com.riiablo.mpq_bytebuf.MPQFileHandle;
public class MPQFileHandleAdapter implements FileHandleAdapter<MPQFileHandle>, AsyncAdapter {
import java.io.InputStream;
import io.netty.buffer.ByteBuf;
public final class MPQFileHandleAdapter extends FileHandleAdapter<MPQFileHandle> implements AsyncAdapter {
public MPQFileHandleAdapter() {
super(MPQFileHandle.class);
}
@Override
public byte[] readBytes(MPQFileHandle handle) {
throw new UnsupportedOperationException();

View File

@ -1,25 +1,16 @@
package com.riiablo.assets.loaders;
import io.netty.buffer.ByteBuf;
import com.badlogic.gdx.utils.Array;
import com.riiablo.assets.Asset;
import com.riiablo.assets.AssetManager;
import com.riiablo.assets.AsyncAssetLoader;
import com.riiablo.assets.FileHandleResolver;
import com.riiablo.assets.MPQFileHandleResolver;
import com.riiablo.codec.DCC;
import com.riiablo.mpq.MPQFileHandle;
public class DCCLoader extends AsyncAssetLoader<DCC, MPQFileHandle, ByteBuf> {
DCCLoader() {
super(new ByteBufReader<MPQFileHandle>());
}
import io.netty.buffer.ByteBuf;
@Override
public FileHandleResolver resolver() {
return new MPQFileHandleResolver();
public class DCCLoader extends AsyncAssetLoader<DCC, ByteBuf> {
public DCCLoader(FileHandleResolver resolver) {
super(resolver, ByteBuf.class);
}
@Override
@ -36,9 +27,4 @@ public class DCCLoader extends AsyncAssetLoader<DCC, MPQFileHandle, ByteBuf> {
public DCC loadSync(AssetManager assets, Asset<DCC> asset, ByteBuf data) {
throw new UnsupportedOperationException();
}
@Override
public Array<Asset> getDependencies(Asset<DCC> asset) {
throw new UnsupportedOperationException();
}
}

View File

@ -1,30 +1,15 @@
package com.riiablo.assets.loaders;
import io.netty.util.AsciiString;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.riiablo.assets.Asset;
import com.riiablo.assets.AssetManager;
import com.riiablo.assets.AsyncAssetLoader;
import com.riiablo.assets.DelimiterPathTransformer;
import com.riiablo.assets.FileHandleResolver;
public class MusicLoader extends AsyncAssetLoader<Music, FileHandle, FileHandle> {
MusicLoader() {
super(new ReflectiveReader<>());
}
@Override
public FileHandleResolver resolver() {
return new FileHandleResolver(DelimiterPathTransformer.INSTANCE) {
@Override
protected FileHandle resolveTransformed(AsciiString path) {
throw new UnsupportedOperationException();
}
};
public class MusicLoader extends AsyncAssetLoader<Music, FileHandle> {
MusicLoader(FileHandleResolver resolver) {
super(resolver, FileHandle.class);
}
@Override
@ -41,9 +26,4 @@ public class MusicLoader extends AsyncAssetLoader<Music, FileHandle, FileHandle>
public Music loadSync(AssetManager assets, Asset<Music> asset, FileHandle data) {
throw new UnsupportedOperationException();
}
@Override
public Array<Asset> getDependencies(Asset<Music> asset) {
throw new UnsupportedOperationException();
}
}

View File

@ -1,17 +1,16 @@
package com.riiablo.assets;
import org.junit.BeforeClass;
import org.junit.Test;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.riiablo.RiiabloTest;
import com.riiablo.logger.Level;
import com.riiablo.logger.LogManager;
import com.riiablo.mpq_bytebuf.MPQFileHandle;
import com.riiablo.mpq_bytebuf.MPQFileHandleResolver;
import org.junit.BeforeClass;
import org.junit.Test;
public class AssetManagerTest extends RiiabloTest {
@BeforeClass
public static void before() {
@ -21,7 +20,7 @@ public class AssetManagerTest extends RiiabloTest {
@Test
public void init() {
AssetManager assets = new AssetManager(1);
MPQFileHandleResolver resolver = new MPQFileHandleResolver(Gdx.files.absolute("C:\\diablo"));
MPQFileHandleResolver resolver = new MPQFileHandleResolver(Gdx.files.absolute("C:\\diablo ii"));
assets.setAdapter(FileHandle.class, new GdxFileHandleAdapter());
assets.setAdapter(MPQFileHandle.class, new MPQFileHandleAdapter());
assets.dispose();