Home | History | Annotate | Download | only in particles
      1 
      2 package com.badlogic.gdx.graphics.g3d.particles;
      3 
      4 import java.io.File;
      5 import java.io.FileWriter;
      6 import java.io.IOException;
      7 import java.io.Writer;
      8 
      9 import com.badlogic.gdx.Application.ApplicationType;
     10 import com.badlogic.gdx.Gdx;
     11 import com.badlogic.gdx.assets.AssetDescriptor;
     12 import com.badlogic.gdx.assets.AssetLoaderParameters;
     13 import com.badlogic.gdx.assets.AssetManager;
     14 import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader;
     15 import com.badlogic.gdx.assets.loaders.FileHandleResolver;
     16 import com.badlogic.gdx.files.FileHandle;
     17 import com.badlogic.gdx.graphics.g3d.particles.ResourceData.AssetData;
     18 import com.badlogic.gdx.graphics.g3d.particles.batches.ParticleBatch;
     19 import com.badlogic.gdx.utils.Array;
     20 import com.badlogic.gdx.utils.Json;
     21 import com.badlogic.gdx.utils.ObjectMap;
     22 import com.badlogic.gdx.utils.reflect.ClassReflection;
     23 
     24 /** This class can save and load a {@link ParticleEffect}. It should be added as {@link AsynchronousAssetLoader} to the
     25  * {@link AssetManager} so it will be able to load the effects. It's important to note that the two classes
     26  * {@link ParticleEffectLoadParameter} and {@link ParticleEffectSaveParameter} should be passed in whenever possible, because when
     27  * present the batches settings will be loaded automatically. When the load and save parameters are absent, once the effect will
     28  * be created, one will have to set the required batches manually otherwise the {@link ParticleController} instances contained
     29  * inside the effect will not be able to render themselves.
     30  * @author inferno */
     31 public class ParticleEffectLoader extends
     32 	AsynchronousAssetLoader<ParticleEffect, ParticleEffectLoader.ParticleEffectLoadParameter> {
     33 	protected Array<ObjectMap.Entry<String, ResourceData<ParticleEffect>>> items = new Array<ObjectMap.Entry<String, ResourceData<ParticleEffect>>>();
     34 
     35 	public ParticleEffectLoader (FileHandleResolver resolver) {
     36 		super(resolver);
     37 	}
     38 
     39 	@Override
     40 	public void loadAsync (AssetManager manager, String fileName, FileHandle file, ParticleEffectLoadParameter parameter) {
     41 	}
     42 
     43 	@Override
     44 	public Array<AssetDescriptor> getDependencies (String fileName, FileHandle file, ParticleEffectLoadParameter parameter) {
     45 		Json json = new Json();
     46 		ResourceData<ParticleEffect> data = json.fromJson(ResourceData.class, file);
     47 		Array<AssetData> assets = null;
     48 		synchronized (items) {
     49 			ObjectMap.Entry<String, ResourceData<ParticleEffect>> entry = new ObjectMap.Entry<String, ResourceData<ParticleEffect>>();
     50 			entry.key = fileName;
     51 			entry.value = data;
     52 			items.add(entry);
     53 			assets = data.getAssets();
     54 		}
     55 
     56 		Array<AssetDescriptor> descriptors = new Array<AssetDescriptor>();
     57 		for (AssetData<?> assetData : assets) {
     58 
     59 			// If the asset doesn't exist try to load it from loading effect directory
     60 			if (!resolve(assetData.filename).exists()) {
     61 				assetData.filename = file.parent().child(Gdx.files.internal(assetData.filename).name()).path();
     62 			}
     63 
     64 			if (assetData.type == ParticleEffect.class) {
     65 				descriptors.add(new AssetDescriptor(assetData.filename, assetData.type, parameter));
     66 			} else
     67 				descriptors.add(new AssetDescriptor(assetData.filename, assetData.type));
     68 		}
     69 
     70 		return descriptors;
     71 
     72 	}
     73 
     74 	/** Saves the effect to the given file contained in the passed in parameter. */
     75 	public void save (ParticleEffect effect, ParticleEffectSaveParameter parameter) throws IOException {
     76 		ResourceData<ParticleEffect> data = new ResourceData<ParticleEffect>(effect);
     77 
     78 		// effect assets
     79 		effect.save(parameter.manager, data);
     80 
     81 		// Batches configurations
     82 		if (parameter.batches != null) {
     83 			for (ParticleBatch<?> batch : parameter.batches) {
     84 				boolean save = false;
     85 				for (ParticleController controller : effect.getControllers()) {
     86 					if (controller.renderer.isCompatible(batch)) {
     87 						save = true;
     88 						break;
     89 					}
     90 				}
     91 
     92 				if (save) batch.save(parameter.manager, data);
     93 			}
     94 		}
     95 
     96 		// save
     97 		Json json = new Json();
     98 		json.toJson(data, parameter.file);
     99 	}
    100 
    101 	@Override
    102 	public ParticleEffect loadSync (AssetManager manager, String fileName, FileHandle file, ParticleEffectLoadParameter parameter) {
    103 		ResourceData<ParticleEffect> effectData = null;
    104 		synchronized (items) {
    105 			for (int i = 0; i < items.size; ++i) {
    106 				ObjectMap.Entry<String, ResourceData<ParticleEffect>> entry = items.get(i);
    107 				if (entry.key.equals(fileName)) {
    108 					effectData = entry.value;
    109 					items.removeIndex(i);
    110 					break;
    111 				}
    112 			}
    113 		}
    114 
    115 		effectData.resource.load(manager, effectData);
    116 		if (parameter != null) {
    117 			if (parameter.batches != null) {
    118 				for (ParticleBatch<?> batch : parameter.batches) {
    119 					batch.load(manager, effectData);
    120 				}
    121 			}
    122 			effectData.resource.setBatch(parameter.batches);
    123 		}
    124 		return effectData.resource;
    125 	}
    126 
    127 	private <T> T find (Array<?> array, Class<T> type) {
    128 		for (Object object : array) {
    129 			if (ClassReflection.isAssignableFrom(type, object.getClass())) return (T)object;
    130 		}
    131 		return null;
    132 	}
    133 
    134 	public static class ParticleEffectLoadParameter extends AssetLoaderParameters<ParticleEffect> {
    135 		Array<ParticleBatch<?>> batches;
    136 
    137 		public ParticleEffectLoadParameter (Array<ParticleBatch<?>> batches) {
    138 			this.batches = batches;
    139 		}
    140 	}
    141 
    142 	public static class ParticleEffectSaveParameter extends AssetLoaderParameters<ParticleEffect> {
    143 		/** Optional parameters, but should be present to correctly load the settings */
    144 		Array<ParticleBatch<?>> batches;
    145 
    146 		/** Required parameters */
    147 		FileHandle file;
    148 		AssetManager manager;
    149 
    150 		public ParticleEffectSaveParameter (FileHandle file, AssetManager manager, Array<ParticleBatch<?>> batches) {
    151 			this.batches = batches;
    152 			this.file = file;
    153 			this.manager = manager;
    154 		}
    155 	}
    156 
    157 }
    158