All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dermetfan.gdx.assets.AnnotationAssetManager Maven / Gradle / Ivy

There is a newer version: 0.13.4
Show newest version
/** Copyright 2014 Robin Stumm ([email protected], http://dermetfan.net)
 *
 *  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 net.dermetfan.gdx.assets;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetDescriptor;
import com.badlogic.gdx.assets.AssetLoaderParameters;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.Field;
import com.badlogic.gdx.utils.reflect.ReflectionException;

/** An {@link AssetManager} that {@link AssetManager#load(AssetDescriptor) loads} assets from a container class using reflection.
 *  @author dermetfan */
public class AnnotationAssetManager extends AssetManager {

	/** Indicates whether a field should be {@link AnnotationAssetManager#load(Field) loaded} and which {@link AssetDescriptor#type} to use if necessary.
* Should only be applied to Strings, {@link FileHandle FileHandles} or {@link AssetDescriptor AssetDescriptors}. * @author dermetfan */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Asset { /** @return whether this field should be loaded */ boolean load() default true; /** @return the {@link AssetDescriptor#type} to use */ Class value() default void.class; } /** @see AnnotationAssetManager#AnnotationAssetManager(FileHandleResolver) */ public AnnotationAssetManager() { this(new InternalFileHandleResolver()); } /** @see AssetManager#AssetManager(FileHandleResolver) * @see AssetManager#setLoader(Class, com.badlogic.gdx.assets.loaders.AssetLoader) */ public AnnotationAssetManager(FileHandleResolver resolver) { super(resolver); } /** {@link #load(Field) Loads} all fields in the given {@code container} class if they are annotated with {@link Asset} and {@link Asset#load()} is true. * @param container the instance of a container class from which to load fields annotated with {@link Asset} */ public void load(Object container) { for(Field field : ClassReflection.getFields(container.getClass())) if(field.isAnnotationPresent(Asset.class) && field.getDeclaredAnnotation(Asset.class).getAnnotation(Asset.class).load()) load(field, container); } /** @param container the class containing the fields whose {@link AssetDescriptor AssetDescriptors} to load */ public void load(Class container) { for(Field field : ClassReflection.getFields(container)) if(field.isAnnotationPresent(Asset.class) && field.getDeclaredAnnotation(Asset.class).getAnnotation(Asset.class).load()) load(field); } /** {@link AssetManager#load(String, Class) loads} the given field * @param field the field to load * @param container the instance of the class containing the given field (may be null if it's static) */ @SuppressWarnings("unchecked") public void load(Field field, Object container) { String path = getAssetPath(field, container); Class type = getAssetType(field, container); @SuppressWarnings("rawtypes") AssetLoaderParameters params = getAssetLoaderParameters(field, container); if(path == null || type == null) Gdx.app.debug(ClassReflection.getSimpleName(getClass()), '@' + ClassReflection.getSimpleName(Asset.class) + " (" + path + ", " + type + ") " + field.getName()); load(path, type, params); } /** @param field the static field to load * @see #load(Field, Object) */ public void load(Field field) { load(field, null); } /** @param field the field to get the asset path from * @param container the instance of the class containing the given field (may be null if it's static) * @return the asset path stored by the field */ public static String getAssetPath(Field field, Object container) { String path = null; try { Object content = field.get(container); if(content instanceof AssetDescriptor) path = ((AssetDescriptor) content).fileName; else if(content instanceof FileHandle) path = ((FileHandle) content).path(); else path = content.toString(); } catch(IllegalArgumentException | ReflectionException e) { Gdx.app.error(ClassReflection.getSimpleName(AnnotationAssetManager.class), "could not access field \"" + field.getName() + "\"", e); } return path; } /** @param container the instance of the class containing the given field (may be null if it's static) * @return the {@link Asset#value()} of the given Field */ public static Class getAssetType(Field field, Object container) { if(ClassReflection.isAssignableFrom(AssetDescriptor.class, field.getType())) try { return ((AssetDescriptor) field.get(container)).type; } catch(IllegalArgumentException | ReflectionException e) { Gdx.app.error(ClassReflection.getSimpleName(AnnotationAssetManager.class), "could not access field \"" + field.getName() + "\"", e); } if(field.isAnnotationPresent(Asset.class)) return field.getDeclaredAnnotation(Asset.class).getAnnotation(Asset.class).value(); return null; } /** @param container the instance of the class containing the given field (may be null if it's static) * @return the {@link AssetDescriptor#params AssetLoaderParameters} of the AssetDescriptor in the given field */ @SuppressWarnings("unchecked") public static AssetLoaderParameters getAssetLoaderParameters(Field field, Object container) { if(ClassReflection.isAssignableFrom(AssetDescriptor.class, field.getType())) try { return ((AssetDescriptor) field.get(container)).params; } catch(IllegalArgumentException | ReflectionException e) { Gdx.app.error(ClassReflection.getSimpleName(AnnotationAssetManager.class), "could not access field\"" + field.getName() + "\"", e); } return null; } /** Creates an {@link AssetDescriptor} from a field that is annotated with {@link Asset}. The field's type must be {@code String} or {@link FileHandle} and the {@link Asset#value()} must not be primitive. * @param field the field annotated with {@link Asset} to create an {@link AssetDescriptor} from * @param container the instance of the class containing the given field (may be null if it's static) * @return an {@link AssetDescriptor} created from the given, with {@link Asset} annotated field (may be null if all fields in the class annotated with {@link Asset} are static) */ @SuppressWarnings("unchecked") public AssetDescriptor createAssetDescriptor(Field field, Object container) { if(!field.isAnnotationPresent(Asset.class)) return null; Class fieldType = field.getType(); if(fieldType != String.class && fieldType != FileHandle.class && fieldType != AssetDescriptor.class) { Gdx.app.error(ClassReflection.getSimpleName(getClass()), "type of @" + ClassReflection.getSimpleName(Asset.class) + " field \"" + field.getName() + "\" must be String or " + ClassReflection.getSimpleName(FileHandle.class) + " to create an " + ClassReflection.getSimpleName(AssetDescriptor.class) + " from it"); return null; } Class type = getAssetType(field, container); if(type.isPrimitive()) { Gdx.app.error(ClassReflection.getSimpleName(getClass()), "cannot create an " + ClassReflection.getSimpleName(AssetDescriptor.class) + " of the generic type " + ClassReflection.getSimpleName(type) + " from the @" + ClassReflection.getSimpleName(Asset.class) + " field \"" + field.getName() + "\""); return null; } if(fieldType == AssetDescriptor.class) try { AssetDescriptor alreadyExistingDescriptor = (AssetDescriptor) field.get(container); if(alreadyExistingDescriptor.type == type) return (AssetDescriptor) alreadyExistingDescriptor; else return new AssetDescriptor<>(alreadyExistingDescriptor.file, (Class) type, alreadyExistingDescriptor.params); } catch(IllegalArgumentException | ReflectionException e) { Gdx.app.error(ClassReflection.getSimpleName(getClass()), "couldn't access field \"" + field.getName() + "\"", e); } else try { if(fieldType == String.class) return new AssetDescriptor<>((String) field.get(container), (Class) type); else return new AssetDescriptor<>((FileHandle) field.get(container), (Class) type); } catch(IllegalArgumentException | ReflectionException e) { Gdx.app.error(ClassReflection.getSimpleName(getClass()), "couldn't access field \"" + field.getName() + "\"", e); } return null; } /** creates an {@link AssetDescriptor} from a static field * @param field the field annotated with {@link Asset} to create an {@link AssetDescriptor} from (must be static) * @return the {@link AssetDescriptor} created from the given static {@code field} annotated with {@link Asset} * @see #createAssetDescriptor(Field, Object) */ public AssetDescriptor createAssetDescriptor(Field field) { return createAssetDescriptor(field, null); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy