assets

A simple asset framework

License

License

GroupId

GroupId

com.github.ykiselev
ArtifactId

ArtifactId

assets
Last Version

Last Version

1.9
Release Date

Release Date

Type

Type

jar
Description

Description

assets
A simple asset framework
Project URL

Project URL

https://github.com/YKiselev/pool
Source Code Management

Source Code Management

https://github.com/YKiselev/assets/tree/master

Download assets

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.ykiselev/assets/ -->
<dependency>
    <groupId>com.github.ykiselev</groupId>
    <artifactId>assets</artifactId>
    <version>1.9</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.ykiselev/assets/
implementation 'com.github.ykiselev:assets:1.9'
// https://jarcasting.com/artifacts/com.github.ykiselev/assets/
implementation ("com.github.ykiselev:assets:1.9")
'com.github.ykiselev:assets:jar:1.9'
<dependency org="com.github.ykiselev" name="assets" rev="1.9">
  <artifact name="assets" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.ykiselev', module='assets', version='1.9')
)
libraryDependencies += "com.github.ykiselev" % "assets" % "1.9"
[com.github.ykiselev/assets "1.9"]

Dependencies

test (2)

Group / Artifact Type Version
junit : junit jar 4.12
org.mockito : mockito-core jar 2.8.47

Project Modules

There are no modules declared in this project.

Build Status License Maven Central

Assets

Synopsis

Simple framework for asset management (asset here is any application resource, for example image, texture or sound).

How to use

Asset framework consists of four interfaces:

Resources interface

Low-level api to resolve resource name to java.nio.channels.ReadableByteChannel

interface Resources {

    Optional<ReadableByteChannel> open(String resource) throws ResourceException;
}

ReadableAsset interface

Api to be implemented by user for each supported asset class

public interface ReadableAsset<T> {

    /**
     * Reads asset from channel
     */
    T read(ReadableByteChannel channel, Assets assets) throws ResourceException;
}

ReadableAssets interface

public interface ReadableAssets {

    /**
     * Resolves instance of {@link ReadableAsset} from supplied URI and/or class.
     */
    <T> ReadableAsset<T> resolve(String resource, Class<T> clazz) throws ResourceException;

    /**
     * Convenient method to resolve {@link ReadableAsset} by asset class.
     */
    default <T> ReadableAsset<T> resolve(Class<T> clazz) throws ResourceException {
        return resolve(null, clazz);
    }

    /**
     * Convenient method to resolve {@link ReadableAsset} by asset class.
     */
    default <T> ReadableAsset<T> resolve(String resource) throws ResourceException {
        return resolve(resource, null);
    }
}

Assets interface

Top-level interface which extends com.github.ykiselev.assets.Resources and adds methods to access registered com.github.ykiselev.assets.ReadableResource's or assets itself

interface Assets extends ReadableAssets {

    /**
     * Loads asset using one of registered {@link ReadableAsset}'s
    */
    <T> Optional<T> tryLoad(String resource, Class<T> clazz, Assets assets) throws ResourceException;
    
    /**
     * Loads asset using one of registered {@link ReadableResource}'s
     */
    default <T> T load(String resource, Class<T> clazz) throws ResourceException {
        return tryLoad(resource, clazz)
                .orElseThrow(() -> new ResourceException("Unable to load " + resource));
    }

    /**
     * Tries to load asset using one of registered {@link ReadableResource}'s
     */
    default <T> Optional<T> tryLoad(String resource, Class<T> clazz) throws ResourceException {
        return tryLoad(resource, clazz, this);
    }
    
    /**
     * Convenient method taking only resource name as argument.
     */
    default <T> T load(String resource) throws ResourceException {
        return load(resource, null);
    }

    /**
     * Convenient method taking only resource name as argument.
     */
    default <T> Optional<T> tryLoad(String resource) throws ResourceException {
        return tryLoad(resource, null);
    }
}

Implementations

SimpleAssets class

This is a base implementation of Assets interface. Instance of this class will require implementation of com.github.ykiselev.assets.Resources (which will be used to resolve resource name to ReadableByteChannel) and com.github.ykiselev.assets.ReadableResources which should resolve ReadableResource by specified asset name and/or class.

ManagedAssets class

This class is intended to be used as decoration for other implementations of Assets. To create instance of this class user will need to provide implementation of Assets (for example - com.github.ykiselev.assets.SimpleAssets) and an instance of class implementing java.util.Map which will be used as internal cache, not only to speed-up consecutive calls with the same asset name but also to release any system resources held by asset (asset class should implement Closeable or AutoCloseable interface). This cleanup is performed when method com.github.ykiselev.assets.ManagedAssets.close is called.

Usage

So user may use composition of provided classes plus implementations of three simple interfaces, like this:

class Example {

    public static void main(String[] args) {
        // 1
        Resources resources = resource -> Optional.of(
                Channels.newChannel(
                        Example.class.getResourceAsStream(resource)
                )
        );
        // 2
        ReadableAssets byClass = new ReadableAssets() {
            @Override
            public <T> ReadableAsset<T> resolve(String resource, Class<T> clazz) throws ResourceException {
                if (String.class.isAssignableFrom(clazz)) {
                    return (stream, assets) -> (T) readText(stream);
                } else {
                    throw new IllegalArgumentException("Unsupported resource class:" + clazz);
                }
            }
        };
        // 3
        ReadableAssets byExtension = new ReadableAssets() {
            @Override
            public <T> ReadableAsset<T> resolve(String resource, Class<T> clazz) throws ResourceException {
                if (resource.endsWith("text")) {
                    return (stream, assets) -> (T) readText(stream);
                } else {
                    throw new IllegalArgumentException("Unsupported extension:" + resource);
                }
            }
        };
        // Create instance of ManagedAssets which will delegate real work to SimpleAssets
        ManagedAssets managedAssets = new ManagedAssets(
                new SimpleAssets(
                        resources,
                        new CompositeReadableResources(
                                byClass,
                                byExtension
                        )
                ),
                new HashMap<>()
        );
        // Now we can load assets
        String AssetByClass = managedAssets.load("/sample.txt", String.class);
        String AssetByExtension = managedAssets.load("/sample.txt", null);
        assertEquals("Hello, World!", AssetByClass);
        assertSame(
                AssetByClass,
                AssetByExtension
        );
    }

    // other methods skipped...

}

Full source code of this example can be found in src/test/java/com/github/ykiselev/assets/Example.java.

License

This project is licensed under the Apache License, Version 2.0.

Versions

Version
1.9
1.8
1.7
1.6
1.5
1.4
1.3
1.2
1.1
1.0