Skip to content

Gestalt Asset Core Quick Start

Immortius edited this page Jun 8, 2015 · 21 revisions

Gestalt Asset Core Quick Start

Defining an Asset type

There are two important classes when defining a new asset type.

Firstly, the AssetData class provides an implementation-agnostic representation of the data needed to create the asset:

public class BookData implements AssetData {
    private String title;
    private String body;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }
}

Then there is the Asset class itself, which may be implementation specific (e.g. OpenGLTexture):

public class Book extends Asset<BookData> {

    private String title;
    private String body;

    public Book(ResourceUrn urn, AssetType<?, BookData> type, BookData data) {
        super(urn, type);
        reload(data);
    }

    @Override
    protected void doReload(BookData data) {
        title = data.getTitle();
        body = data.getBody();
    }

    @Override
    protected void doDispose() {
        title = "";
        body = "";
    }

    public String getTitle() {
        return title;
    }

    public String getBody() {
        return body;
    }
}

Additionally, you may need a AssetFactory class depending on how the asset type will be registered. A factory class looks like:

public class BookFactory implements AssetFactory<Book, BookData> {

    @Override
    public Book build(ResourceUrn urn, AssetType<? super Book, BookData> type, BookData data) {
        return new Book(urn, type, data);
    }
}

although if your constructor meets the signature, you may be able to get away with a method reference (e.g. BookAsset::new

Establishing an AssetTypeManager

AssetTypeManager is is the central manager for all asset types. ModuleAwareAssetTypeManager will set up asset types to read

ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManager();
assetTypeManager.registerCoreAssetType(Book.class, Book::new, "books");
assetTypeManager.switchEnvironment(moduleEnvironment);

You can also have asset types automatically register using the @RegisterAssetType annotation:

import org.terasology.assets.module.annotations.RegisterAssetType;

@RegisterAssetType(folderName = "books", factoryClass = BookFactory.class)
public class Book extends Asset<BookData> { 
   \\ ...
}

Obtaining Assets

Assets can most easily be obtained by using an AssetManager - a wrapper for an AssetTypeManager providing convenience methods for working with assets. Assets are referred to with a ResourceUrn typically with the structure "moduleName:assetName". If the asset is not yet loaded but available from an AssetDataProducer, the asset will be loaded and returned.

AssetManager assetManager = new AssetManager(assetTypeManager);
Optional<Book> myBook = assetManager.getAsset("engine:mybook", Book.class);

It is also possible to get a set of available asset urns:

Set<ResourceUrn> bookUrns = assetManager.getAvailableAssets(Book.class);

Programatically creating/reloading Assets

BookData data = new BookData();
Book myBook = assetManager.loadAsset(new ResourceUrn("engine:mybook"), data, Book.class);
BookData data = new BookData();
myBook.reload(data);

AssetDataProducers

Reload assets changed on disk

Contextual Asset Resolution

It is possible to attempt to obtain an asset with an incomplete urn (missing the moduleName).

// Will return an asset iff there is only one module providing an asset with the resourceName "myBook"
Optional<Book> myBook = assetManager.getAsset("mybook", Book.class);
// Will return a list of all possible ResourceUrns with an resourceName "myBook"
Set<ResourceUrn> options = resolve("mybook", Book.class);

This can be further tailored by providing a module context to resolve within. This will restrict the search for possible assets to the specified module and its dependency tree. Additionally if an asset from that module has the desired resourceName it will be used.

Optional<Book> myBook = assetManager.getAsset("mybook", Book.class, new Name("engine));
Set<ResourceUrn> options = resolve("mybook", Book.class, new Name("engine));

It is also possible to specify a context using the ContextManager - this will automatically be used if no context is specified. This can be leveraged to set the context for all resolutions to a desired module before executing code from that module.

try (Context ignored = ContextManager.beginContext(new Name("engine")) {
    Optional<Book> myBook = assetManager.getAsset("mybook", Book.class);
}