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

com.badlogic.gdx.graphics.g3d.particles.ResourceData Maven / Gradle / Ivy

There is a newer version: 1.12.1
Show newest version
/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * 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 com.badlogic.gdx.graphics.g3d.particles;

import com.badlogic.gdx.assets.AssetDescriptor;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.JsonValue;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectMap.Entry;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.ReflectionException;

/** This class handles the assets and configurations required by a given resource when de/serialized. It's handy when a given
 * object or one of its members requires some assets to be loaded to work properly after being deserialized. To save the assets,
 * the object should implement the {@link Configurable} interface and obtain a {@link SaveData} object to store every required
 * asset or information which will be used during the loading phase. The passed in {@link AssetManager} is generally used to find
 * the asset file name for a given resource of a given type. The class can also store global configurations, this is useful when
 * dealing with objects which should be allocated once (i.e singleton). The deserialization process must happen in the same order
 * of serialization, because the per object {@link SaveData} blocks are stored as an {@link Array} within the {@link ResourceData}
 * , while the global {@link SaveData} instances can be accessed in any order because require a unique {@link String} and are
 * stored in an {@link ObjectMap}.
 * @author Inferno */
public class ResourceData implements Json.Serializable {

	/** This interface must be implemented by any class requiring additional assets to be loaded/saved */
	public static interface Configurable {
		public void save (AssetManager manager, ResourceData resources);

		public void load (AssetManager manager, ResourceData resources);
	}

	/** Contains all the saved data. {@link #data} is a map which link an asset name to its instance. {@link #assets} is an array of
	 * indices addressing a given {@link com.badlogic.gdx.graphics.g3d.particles.ResourceData.AssetData} in the
	 * {@link ResourceData} */
	public static class SaveData implements Json.Serializable {
		ObjectMap data;
		IntArray assets;
		private int loadIndex;
		protected ResourceData resources;

		public SaveData () {
			data = new ObjectMap();
			assets = new IntArray();
			loadIndex = 0;
		}

		public SaveData (ResourceData resources) {
			data = new ObjectMap();
			assets = new IntArray();
			loadIndex = 0;
			this.resources = resources;
		}

		public  void saveAsset (String filename, Class type) {
			int i = resources.getAssetData(filename, type);
			if (i == -1) {
				resources.sharedAssets.add(new AssetData(filename, type));
				i = resources.sharedAssets.size - 1;
			}
			assets.add(i);
		}

		public void save (String key, Object value) {
			data.put(key, value);
		}

		public AssetDescriptor loadAsset () {
			if (loadIndex == assets.size) return null;
			AssetData data = (AssetData)resources.sharedAssets.get(assets.get(loadIndex++));
			return new AssetDescriptor(data.filename, data.type);
		}

		public  K load (String key) {
			return (K)data.get(key);
		}

		@Override
		public void write (Json json) {
			json.writeValue("data", data, ObjectMap.class);
			json.writeValue("indices", assets.toArray(), int[].class);
		}

		@Override
		public void read (Json json, JsonValue jsonData) {
			data = json.readValue("data", ObjectMap.class, jsonData);
			assets.addAll(json.readValue("indices", int[].class, jsonData));
		}
	}

	/** This class contains all the information related to a given asset */
	public static class AssetData implements Json.Serializable {
		public String filename;
		public Class type;

		public AssetData () {
		}

		public AssetData (String filename, Class type) {
			this.filename = filename;
			this.type = type;
		}

		@Override
		public void write (Json json) {
			json.writeValue("filename", filename);
			json.writeValue("type", type.getName());
		}

		@Override
		public void read (Json json, JsonValue jsonData) {
			filename = json.readValue("filename", String.class, jsonData);
			String className = json.readValue("type", String.class, jsonData);
			try {
				type = (Class)ClassReflection.forName(className);
			} catch (ReflectionException e) {
				throw new GdxRuntimeException("Class not found: " + className, e);
			}
		}
	}

	/** Unique data, can be used to save/load generic data which is not always loaded back after saving. Must be used to store data
	 * which is uniquely addressable by a given string (i.e a system configuration). */
	private ObjectMap uniqueData;

	/** Objects save data, must be loaded in the same saving order */
	private Array data;

	/** Shared assets among all the configurable objects */
	Array sharedAssets;
	private int currentLoadIndex;
	public T resource;

	public ResourceData () {
		uniqueData = new ObjectMap();
		data = new Array(true, 3, SaveData.class);
		sharedAssets = new Array();
		currentLoadIndex = 0;
	}

	public ResourceData (T resource) {
		this();
		this.resource = resource;
	}

	 int getAssetData (String filename, Class type) {
		int i = 0;
		for (AssetData data : sharedAssets) {
			if (data.filename.equals(filename) && data.type.equals(type)) {
				return i;
			}
			++i;
		}
		return -1;
	}

	public Array getAssetDescriptors () {
		Array descriptors = new Array();
		for (AssetData data : sharedAssets) {
			descriptors.add(new AssetDescriptor(data.filename, data.type));
		}
		return descriptors;
	}

	public Array getAssets () {
		return sharedAssets;
	}

	/** Creates and adds a new SaveData object to the save data list */
	public SaveData createSaveData () {
		SaveData saveData = new SaveData(this);
		data.add(saveData);
		return saveData;
	}

	/** Creates and adds a new and unique SaveData object to the save data map */
	public SaveData createSaveData (String key) {
		SaveData saveData = new SaveData(this);
		if (uniqueData.containsKey(key)) throw new RuntimeException("Key already used, data must be unique, use a different key");
		uniqueData.put(key, saveData);
		return saveData;
	}

	/** @return the next save data in the list */
	public SaveData getSaveData () {
		return data.get(currentLoadIndex++);
	}

	/** @return the unique save data in the map */
	public SaveData getSaveData (String key) {
		return uniqueData.get(key);
	}

	@Override
	public void write (Json json) {
		json.writeValue("unique", uniqueData, ObjectMap.class);
		json.writeValue("data", data, Array.class, SaveData.class);
		json.writeValue("assets", sharedAssets.toArray(AssetData.class), AssetData[].class);
		json.writeValue("resource", resource, null);
	}

	@Override
	public void read (Json json, JsonValue jsonData) {
		uniqueData = json.readValue("unique", ObjectMap.class, jsonData);
		for (Entry entry : uniqueData.entries()) {
			entry.value.resources = this;
		}

		data = json.readValue("data", Array.class, SaveData.class, jsonData);
		for (SaveData saveData : data) {
			saveData.resources = this;
		}

		sharedAssets.addAll(json.readValue("assets", Array.class, AssetData.class, jsonData));
		resource = json.readValue("resource", null, jsonData);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy