org.terasology.assets.management.AssetManager.java Source code

Java tutorial

Introduction

Here is the source code for org.terasology.assets.management.AssetManager.java

Source

/*
 * Copyright 2015 MovingBlocks
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.terasology.assets.management;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.terasology.assets.Asset;
import org.terasology.assets.AssetData;
import org.terasology.assets.AssetType;
import org.terasology.assets.ResourceUrn;
import org.terasology.module.sandbox.API;
import org.terasology.naming.Name;

import javax.annotation.concurrent.ThreadSafe;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * AssetManager provides an simplified interface for working with assets across multiple asset types.
 * <p>
 * To do this it uses an {@link AssetTypeManager} to obtain the AssetTypes relating to an Asset
 * class of interest, and delegates down to them for actions such as obtaining and reloading assets.
 * </p>
 *
 * @author Immortius
 */
@API
@ThreadSafe
public final class AssetManager {

    private final AssetTypeManager assetTypeManager;

    /**
     * @param assetTypeManager the asset type manager that will be used
     */
    public AssetManager(AssetTypeManager assetTypeManager) {
        this.assetTypeManager = assetTypeManager;
    }

    /**
     * @param urn The urn of the asset to check. Must not be an instance urn
     * @param type The Asset class of interest
     * @return whether an asset is loaded with the given urn
     */
    public boolean isLoaded(ResourceUrn urn, Class<? extends Asset<?>> type) {
        for (AssetType<?, ?> assetType : assetTypeManager.getAssetTypes(type)) {
            if (assetType.isLoaded(urn)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Retrieves a set of the ResourceUrns for all loaded assets of the given Asset class (including subtypes)
     *
     * @param type The Asset class of interest
     * @param <T>  The Asset class
     * @return A set of the ResourceUrns of all loaded assets
     */
    public <T extends Asset<?>> Set<ResourceUrn> getLoadedAssetUrns(Class<T> type) {
        List<AssetType<? extends T, ?>> assetTypes = assetTypeManager.getAssetTypes(type);
        switch (assetTypes.size()) {
        case 0:
            return Collections.emptySet();
        case 1:
            return assetTypes.get(0).getLoadedAssetUrns();
        default:
            Set<ResourceUrn> result = Sets.newLinkedHashSet();
            for (AssetType<? extends T, ?> assetType : assetTypes) {
                result.addAll(assetType.getLoadedAssetUrns());
            }
            return result;
        }
    }

    /**
     * Retrieves a list of all loaded assets of the given Asset class (including subtypes)
     *
     * @param type The Asset class of interest
     * @param <T>  The Asset class
     * @param <U>  The AssetData class
     * @return A list of all the loaded assets
     */
    public <T extends Asset<U>, U extends AssetData> Set<T> getLoadedAssets(Class<T> type) {
        List<AssetType<? extends T, ?>> assetTypes = assetTypeManager.getAssetTypes(type);
        switch (assetTypes.size()) {
        case 0:
            return Collections.emptySet();
        default:
            ImmutableSet.Builder<T> builder = ImmutableSet.builder();
            for (AssetType<? extends T, ?> assetType : assetTypes) {
                builder.addAll(assetType.getLoadedAssets());
            }
            return builder.build();
        }
    }

    /**
     * Retrieves a set of the ResourceUrns for all available assets of the given Asset class (including subtypes). An available asset is either a loaded asset, or one
     * which can be requested. The set is not necessarily complete as assets procedurally generated from their resource urn may not be included.
     *
     * @param type The Asset class of interest
     * @param <T>  The Asset class
     * @return A set of the ResourceUrns of all available assets
     */
    public <T extends Asset<?>> Set<ResourceUrn> getAvailableAssets(Class<T> type) {
        List<AssetType<? extends T, ?>> assetTypes = assetTypeManager.getAssetTypes(type);
        switch (assetTypes.size()) {
        case 0:
            return Collections.emptySet();
        case 1:
            return assetTypes.get(0).getAvailableAssetUrns();
        default:
            Set<ResourceUrn> result = Sets.newLinkedHashSet();
            for (AssetType<? extends T, ?> assetType : assetTypes) {
                result.addAll(assetType.getAvailableAssetUrns());
            }
            return result;
        }
    }

    /**
     * Given a string that may be a partial or full urn, resolves all possible ResourceUrns to load it as. This takes into account the current module context from
     * {@link org.terasology.assets.management.ContextManager}.
     *
     * @param urn  The full or partial urn to resolve.
     * @param type The type of Asset to resolve this the urn for
     * @param <T>  The class of Asset
     * @return A set of possible ResourceUrns that match these conditions
     */
    public <T extends Asset<?>> Set<ResourceUrn> resolve(String urn, Class<T> type) {
        return resolve(urn, type, ContextManager.getCurrentContext());
    }

    /**
     * Given a string that may be a partial or full urn, resolves all possible ResourceUrns to load it as. This uses the module context given.
     *
     * @param urn           The full or partial urn to resolve.
     * @param type          The type of Asset to resolve this the urn for
     * @param moduleContext The module context to resolve the urn within
     * @param <T>           The class of Asset
     * @return A set of possible ResourceUrns that match these conditions
     */
    public <T extends Asset<?>> Set<ResourceUrn> resolve(String urn, Class<T> type, Name moduleContext) {
        List<AssetType<? extends T, ?>> assetTypes = assetTypeManager.getAssetTypes(type);
        switch (assetTypes.size()) {
        case 0:
            return Collections.emptySet();
        case 1:
            return assetTypes.get(0).resolve(urn, moduleContext);
        default:
            Set<ResourceUrn> result = Sets.newLinkedHashSet();
            for (AssetType<? extends T, ?> assetType : assetTypes) {
                result.addAll(assetType.resolve(urn, moduleContext));
            }
            return result;
        }
    }

    /**
     * Retrieves an asset from a full or partial urn, of the given Asset type. The urn is resolved as per {@link #resolve(String, Class)}
     *
     * @param urn  The full or partial urn of the asset to retrieve
     * @param type The type of Asset to retrieve
     * @param <T>  The class of Asset
     * @param <U>  The class of AssetData
     * @return An optional containing the requested asset if successfully obtained.
     */
    public <T extends Asset<U>, U extends AssetData> Optional<T> getAsset(String urn, Class<T> type) {
        return getAsset(urn, type, ContextManager.getCurrentContext());
    }

    /**
     * Retrieves an asset from a full or partial urn, of the given Asset type
     *
     * @param urn           The full or partial urn of the asset to retrieve
     * @param type          The type of Asset to retrieve
     * @param moduleContext The context in which to resolve the urn
     * @param <T>           The class of Asset
     * @param <U>           The class of AssetData
     * @return An Optional containing the requested asset if successfully obtained
     */
    public <T extends Asset<U>, U extends AssetData> Optional<T> getAsset(String urn, Class<T> type,
            Name moduleContext) {
        Set<ResourceUrn> resourceUrns = resolve(urn, type, moduleContext);
        if (resourceUrns.size() == 1) {
            return getAsset(resourceUrns.iterator().next(), type);
        }
        return Optional.empty();
    }

    /**
     * Retrieves an asset with the given urn and type
     *
     * @param urn  The urn of the asset to retrieve
     * @param type The type of asset to retrieve
     * @param <T>  The class of Asset
     * @param <U>  The class of AssetData
     * @return An Optional containing the requested asset if successfully obtained
     */
    public <T extends Asset<U>, U extends AssetData> Optional<T> getAsset(ResourceUrn urn, Class<T> type) {
        List<AssetType<? extends T, ?>> assetTypes = assetTypeManager.getAssetTypes(type);
        switch (assetTypes.size()) {
        case 0:
            return Optional.empty();
        case 1: {
            Optional<? extends T> result = assetTypes.get(0).getAsset(urn);
            if (result.isPresent()) {
                return Optional.of(result.get());
            }
            break;
        }
        default:
            for (AssetType<? extends T, ?> assetType : assetTypes) {
                Optional<? extends T> result = assetType.getAsset(urn);
                if (result.isPresent()) {
                    return Optional.of(result.get());
                }
            }
            break;
        }
        return Optional.empty();
    }

    /**
     * Creates or reloads an asset with the given urn, data and type. The type must be the actual type of the asset, not a super type.
     *
     * @param urn  The urn of the asset
     * @param data The data to load the asset with
     * @param type The type of the asset
     * @param <T>  The class of Asset
     * @param <U>  The class of AssetData
     * @return The loaded asset
     * @throws java.lang.IllegalStateException if the asset type is not managed by this AssetManager.
     */
    public <T extends Asset<U>, U extends AssetData> T loadAsset(ResourceUrn urn, U data, Class<T> type) {
        Optional<AssetType<T, U>> assetType = assetTypeManager.getAssetType(type);
        if (assetType.isPresent()) {
            return assetType.get().loadAsset(urn, data);
        } else {
            throw new IllegalStateException(type + " is not a supported type of asset");
        }
    }

}