Android Open Source - DolphinOES Game Data






From Project

Back to project page DolphinOES.

License

The source code is released under:

Apache License

If you think the Android project DolphinOES listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/******************************************************************************* Copyright 2014 See AUTHORS file.
 * /*  w w w  .j a  v a  2 s  . co  m*/
 * 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.sidereal.dolphinoes.architecture.core;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectMap.Entry;
import com.sidereal.dolphinoes.architecture.DolphinOES;
import com.sidereal.dolphinoes.util.BooleanWrapper;
import com.sidereal.dolphinoes.util.FloatWrapper;
import com.sidereal.dolphinoes.util.IntWrapper;

/** Class used for object serialization and saving in a path relative to the preferences set by
 * {@link DolphinOESConfiguration#preferExternalStorage} and availability of the storage based on platform.
 * <p>
 * Instance is found in {@link DolphinOES#data}
 * 
 * @author Claudiu Bele */
public class GameData implements Configurable
{

  // region external

  /** Type of storage. {@link GameData#storageType} is assigned a value in {@link GameData#DataSerializer(boolean)}
   * 
   * @see StorageType#External
   * @see StorageType#Local
   * @see StorageType#None
   * @author Claudiu Bele */
  enum StorageType
  {

    /** External is prioritised and available / Internal is prioritised and unavailable
     * 
     * @see StorageType#Local */
    External,

    /** Internal is prioritised and available / External is prioritised and unavailable
     * 
     * @see StorageType#External */
    Local,

    /** Neither external or local storage are available */
    None
  }

  public static final class ParticleSettings
  {
    public static final int NONE = 0;
    public static final int LOW = 1;
    public static final int MEDIUM = 2;
    public static final int HIGH = 3;
    public static final int MAX = 4;

    public static String toString(int no)
    {

      switch (no)
      {
      case 0:
        return Settings.PARTICLE_SETTINGS_NONE;
      case 1:
        return Settings.PARTICLE_SETTINGS_LOW;
      case 2:
        return Settings.PARTICLE_SETTINGS_MEDIUM;
      case 3:
        return Settings.PARTICLE_SETTINGS_HIGH;
      case 4:
        return Settings.PARTICLE_SETTINGS_MAX;
      default:
        return Settings.PARTICLE_SETTINGS_NONE;
      }
    }
  }

  public static final class Settings
  {

    /** Specifies the setting number for the particle settings.
     * <p>
     * Value is of type {@link IntWrapper}. */
    public static final String PARTICLE_SETTINGS = "Particle settings";

    /** Whether or not to use linear filtering for the loaded textures
     * <p>
     * Set to false by default in {@link GameData#create()}, and retrieved or added to the settings file based on
     * whether or not it exists.
     * <p>
     * Value is of type {@link BooleanWrapper}. */
    public static final String LINEAR_FILTERING = "Linear filtering";

    /** Specifies whether or not to use shaders. Set to true by default.
     * <p>
     * Value is of type {@link BooleanWrapper}. */
    public static final String USE_SHADERS = "Use shaders";

    /** Music volume, from 0 to 1.
     * <p>
     * Value is of type {@link FloatWrapper}. */
    public static final String MUSIC_VOLUME = "Music volume";

    /** Sound volume, from 0 to 1.
     * <p>
     * Value is of type {@link FloatWrapper}. */
    public static final String SOUND_VOLUME = "Sound volume";

    /** Whether to run multithreaded or not.
     * <p>
     * Value is of type {@link BooleanWrapper}. */
    public static final String MULTI_THREADED = "Multi threaded";
    public static final String PARTICLE_SETTINGS_NONE = "NONE";
    public static final String PARTICLE_SETTINGS_LOW = "LOW";
    public static final String PARTICLE_SETTINGS_MEDIUM = "MEDIUM";
    public static final String PARTICLE_SETTINGS_HIGH = "HIGH";
    public static final String PARTICLE_SETTINGS_MAX = "MAX";

  }

  // endregion

  // region fields

  /** The graphical preferences, used for retrieval from files */
  public HashMap<String, Object> settings;

  /** List containing whether files have to be loaded on startup. When using {@link #saveData(String, Object, boolean)} */
  private HashMap<String, BooleanWrapper> loadOnStartup;

  /** Whether to prioritise external storage when saving data or not, if the device allows. */
  private boolean prioritiseExternalStorage;

  /** The root path to all data related to the app. */
  private String rootDataPath;

  /** The {@link File} object created at the {@link #rootDataPath} path. */
  private FileHandle rootDataFolder;

  /** Serialized data with the {@link String} key resembling the path and the value being the deserialized data which
   * can be casted as the class it was initially passed for serialization. */
  private ObjectMap<String, Object> data;

  /** Paths to all of the files. Created in {@link #create()} */
  private ArrayList<String> filePaths;

  /** The type of storage. Set in {@link #DataSerializer(boolean)} which sets it based on
   * {@link DolphinOESConfiguration#preferExternalStorage} and {@link Gdx#files#isExternalStorageAvailable()} */
  private StorageType storageType;

  // endregion fields

  // region constructors

  @SuppressWarnings("unchecked")
  public void create()
  {

    // region handle root path
    if (Gdx.files.isExternalStorageAvailable() == Gdx.files.isLocalStorageAvailable() == false)
    {
      storageType = StorageType.None;
      return;
    }

    // check if external storage is available.
    if (prioritiseExternalStorage)
    {
      if (Gdx.files.isExternalStorageAvailable())
        storageType = StorageType.External;
      else if (Gdx.files.isLocalStorageAvailable())
        storageType = StorageType.Local;
    } else
    {
      // prioritising local storage
      if (Gdx.files.isLocalStorageAvailable())
        storageType = StorageType.Local;
      else if (Gdx.files.isExternalStorageAvailable())
        storageType = StorageType.External;
    }
    rootDataPath = rootDataPath.replace('*', ' ').replace('?', ' ');
    if (rootDataPath.charAt(rootDataPath.length() - 1) != '/')
    {
      rootDataPath += "/";
    }
    // endregion

    filePaths = new ArrayList<String>();
    data = new ObjectMap<String, Object>();

    // creates folders
    getFileHandle(rootDataPath.substring(0, rootDataPath.lastIndexOf("/"))).mkdirs();

    /** Deserialises the data from all of the files found in the Data folder( including subfolders of Data). Gets
     * called only if the storageType is not null so no need to check */
    getDataFromFolder(getRootDataFolder(), "");

    if (contains("GameData/LoadOnStartup"))
    {
      loadOnStartup = (HashMap<String, BooleanWrapper>) get("GameData/LoadOnStartup");
    } else
    {
      loadOnStartup = new HashMap<String, BooleanWrapper>();
      loadOnStartup.put("GameData/Main", new BooleanWrapper(true));
    }

    for (java.util.Map.Entry<String, BooleanWrapper> entry : loadOnStartup.entrySet())
    {
      if (exists(entry.getKey()) && entry.getValue().get())
        load(entry.getKey());
    }

    // handle retrieving or setting the preferences
    if (contains("GameData/Main"))
    {
      settings = (HashMap<String, Object>) get("GameData/Main");
    } else
    {
      settings = new HashMap<String, Object>();
      settings.put(Settings.PARTICLE_SETTINGS, new IntWrapper(ParticleSettings.MAX));
      settings.put(Settings.LINEAR_FILTERING, new BooleanWrapper(false));
      settings.put(Settings.USE_SHADERS, new BooleanWrapper(true));
      settings.put(Settings.MUSIC_VOLUME, new FloatWrapper(1f));
      settings.put(Settings.SOUND_VOLUME, new FloatWrapper(1f));
      settings.put(Settings.MULTI_THREADED, new BooleanWrapper(false));
      save("GameData/Main", settings, true,true);
    }

  }

  @Override
  public void configure(DolphinOESConfiguration cfg)
  {

    this.rootDataPath = cfg.rootDataPath;
    this.prioritiseExternalStorage = cfg.prioritiseExternalStorage;
  }

  @Override
  public void update()
  {

  }

  // endregion constructor

  // region methods

  // region settings

  /** Retrieves a setting from {@link #settings}. Use {@link Settings} variables as a parameter for easy access.
   * 
   * @param settingName
   * @return */
  public Object getSettings(String settingName)
  {

    if (settings != null)
    {
      if (settings.containsKey(settingName))
      {
        return settings.get(settingName);
      }
    }
    return null;
  }

  public void updateSettings()
  {

    if (settings != null)
    {
      save("GameData/Main", settings, true, true);
    }
  }

  // endregion settings

  // region API

  // region checks

  /** Returns whether or not data with the given parameter has been loaded.
   * 
   * @param dataName
   *            The path excluding the root folder, it is the same one used for saving data.
   * @return whether or not the parameter can be found as a key. */
  public boolean contains(String dataName)
  {

    return data.containsKey(dataName);
  }

  public boolean exists(String dataName)
  {

    for (int i = 0; i < filePaths.size(); i++)
    {
      if (filePaths.get(i).equals(dataName))
        return true;
    }
    return false;
  }

  // endregion checks

  // region save
  /** Saves the object as a file at root/dataName by serialising it
   * 
   * @param dataName
   *            The name of the file path relative to the Data Folder, as well as the key used for {@link #data}
   * @param obj
   *            The value of the object. WIll be the data in the file, as well as the value of the entry that the
   *            object takes in {@link #data}
   *            <p>
   *            Passing a null object as a parameter will only make the folders */
  public final void save(String dataName, Object obj, boolean loadOnStartup, boolean storeInMemory)
  {

    if (storageType.equals(StorageType.None))
      return;

    String path = rootDataPath + "/" + dataName;
    getFileHandle(path.substring(0, path.lastIndexOf("/"))).mkdirs();

    if (obj == null)
      return;

    // we are done with creating nested files.
    try
    {
      FileHandle file = getFileHandle(rootDataPath + dataName + ".dd");

      file.writeBytes(serialize(obj), false);
      
      if(storeInMemory)
        data.put(dataName, obj);

      // not in the list of files in the system, add it there.
      if (!exists(dataName))
        filePaths.add(dataName);

      this.loadOnStartup.put(dataName, new BooleanWrapper(loadOnStartup));

    } catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  /** Saves all data in their filePath. */
  public final void saveAll()
  {

    for (Entry<String, Object> entry : data.entries())
    {
      save(entry.key, entry.value, loadOnStartup.get(entry.key).get(),false);
    }
  }

  // endregion save

  // region delete
  /** Removes a file from the map if it the key can be found, and removes the file from the disk.
   * <p>
   * {@link #filePaths}, {@link #loadOnStartup}  and {@link #data} will be updated to reflect the changes.
   * @param dataName
   *            The key to the data */
  public final void delete(String dataName)
  {

    if (storageType.equals(StorageType.None))
      return;

    DolphinOES.debug.log("Removing file from disk at location: " + dataName);
    if (contains(dataName))
    {
      FileHandle file = getFileHandle(rootDataPath + dataName + ".dd");
      if (file.exists())
      {
        file.delete();
      }
      data.remove(dataName);
      filePaths.remove(dataName);
      loadOnStartup.remove(dataName);
    }
  }
  
  /** Deletes all of the files ( excluding {@link #settings} and {@link #filePaths} ) from the disk. 
   * <p>
   * {@link #filePaths}, {@link #loadOnStartup}  and {@link #data} will be updated to reflect the changes.
   * 
   */
  public final void deleteAll()
  {
    for(int i=0;i< filePaths.size();i++)
    {
      // keep special files
      if(filePaths.get(i).equals("GameData/Main") || filePaths.get(i).equals("GameData/LoadOnStartup"))
        continue;
      
      // remove ordinary files
      getFileHandle(rootDataPath+"/"+filePaths.get(i)).delete();
      
      data.clear();
      loadOnStartup.clear();
      
      data.put("GameData/Main", settings);
      loadOnStartup.clear();
      data.clear();
      filePaths.clear();
      
      save("GameData/LoadOnStartup",  loadOnStartup, true, true);
      save("GameData/Main",  settings, true, true);


    }
  }
  
  // endregion delete

  // region get

  /** Returns the entry in the {@link #data} with the specificied key parameter
   * 
   * @param dataName
   *            The key to be used for retrieval of the value tied to it from {@link #data}
   * @return The value for the specified key or null, based on whether or not it exists in the Dictionary */
  public final Object get(String dataName)
  {

    return (data.containsKey(dataName)) ? data.get(dataName) : null;
  }

  public final ArrayList<Object> getAllFromFolder(String folderName)
  {

    ArrayList<Object> objects = new ArrayList<Object>();

    for (Entry<String, Object> entry : data.entries())
    {
      if (entry.key.startsWith(folderName))
      {
        objects.add(entry.value);
      }
    }
    return objects;
  }

  // endregion get

  // region loadData

  /** Loads a file in memory. This method has to be call in order to load data that had the
   * <code>loadOnstartup</code> parameter passed in {@link #saveData(String, Object, boolean)} set to false, otherwise
   * the asset will already be loaded at startup.
   * <p>
   * If the data is already in memory, the request is ignored.
   * 
   * @param filepath
   *            the path to the file to load. It is the path relative to the root file path. */
  public final void load(String filepath)
  {

    // already loaded, return
    if (contains(filepath))
      return;

    if (exists(filepath))
    {
      Object obj;
      try
      {
        obj = deserialize(getFileHandle(rootDataPath + "/" + filepath + ".dd").readBytes());
        data.put(filepath.substring(0, filepath.length() - 3), obj);

      } catch (IOException e)
      {
        e.printStackTrace();
      } catch (ClassNotFoundException e)
      {
        e.printStackTrace();
      }
    }

  }

  /** Uncloads a file from memory. For an asset to be loaded, upon saving the data using
   * {@link #saveData(String, Object, boolean)}, the <code>loadOnStartup</code> parameter has to be true, or
   * {@link #load(String)} has to be called.
   * <p>
   * If the data is not in memory anymore, the request is ignored
   * 
   * @param filepath
   *            the path to the file to unload. It is the path relative to the root file path. */
  public final void unload(String filepath)
  {

    // not loaded, return;
    if (!contains(filepath))
      return;

    data.remove(filepath);
  }

  /** Releases the references to files. File paths will not be removed, so you would still know where all the files are using {@link #exists(String)}.
   * <p>
   * . For an asset to be loaded, upon saving the data using
   * {@link #saveData(String, Object, boolean)}, the <code>loadOnStartup</code> parameter has to be true, or
   * {@link #load(String)} has to be called.
   * <p>
   * If the data is not in memory anymore, the request is ignored
   * 
   */
  public final void unloadAll()
  {
    data.clear();
  }
  
  // endregion loadData

  // endregion API

  // region internal

  private byte[] serialize(Object obj) throws IOException
  {

    ByteArrayOutputStream b = new ByteArrayOutputStream();
    ObjectOutputStream o = new ObjectOutputStream(b);
    o.writeObject(obj);
    return b.toByteArray();
  }

  private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException
  {

    ByteArrayInputStream b = new ByteArrayInputStream(bytes);
    ObjectInputStream o = new ObjectInputStream(b);
    return o.readObject();
  }

  private FileHandle getFileHandle(String path)
  {

    if (storageType.equals(StorageType.None))
      return null;

    if (storageType.equals(StorageType.External))
      return Gdx.files.external(path);
    return Gdx.files.local(path);
  }

  /** Returns the Data folder.
   * <p>
   * It will be created if it doesn't exists.
   * 
   * @return The Data folder */
  private final FileHandle getRootDataFolder()
  {

    FileHandle file = getFileHandle(rootDataPath.substring(0, rootDataPath.length() - 1));
    if (!file.exists() || !file.isDirectory())
    {
      if (!file.exists() && rootDataFolder != null)
      {
        file.mkdirs();
        saveAll();
      } else
      {
        file.mkdirs();
      }
      rootDataFolder = file;
    }
    return file;

  }

  /** Method for recursively accesing files.
   * <p>
   * Goes over all the files in a folder( keeping in mind the name of the path so far from Data until the current
   * file) if it is a folder, if not, tries to deserialise it and add it to {@link #data} with the key being the path
   * from Data to the file ( excluding Data/) and the value being the deserialised object.
   * <p>
   * No need to check for storageType to be {@link StorageType#None} as this is called from all files.
   * 
   * @param folder
   *            current file to search through
   * @param currentPathString
   *            the path so far. */
  private void getDataFromFolder(FileHandle folder, String currentPathString)
  {

    // get a list of all files
    FileHandle[] filesInFolder = folder.list();
    if (filesInFolder == null)
      return;

    for (int i = 0; i < filesInFolder.length; i++)
    {
      // // can't read, don't bother handling it.
      // if (!filesInFolder[i].)
      // continue;

      if (filesInFolder[i].isDirectory())
      {
        getDataFromFolder(filesInFolder[i], currentPathString + filesInFolder[i].name() + "/");
      } else
      // object is file
      {
        String filepath = currentPathString
          + filesInFolder[i].name().substring(0, filesInFolder[i].name().length() - 3);
        if (!exists(filepath))
          filePaths.add(filepath);
      }
    }
  }

  // endregion internal

  // endregion methods

}




Java Source Code List

com.sidereal.dolphinoes.architecture.AbstractEvent.java
com.sidereal.dolphinoes.architecture.DebugHandler.java
com.sidereal.dolphinoes.architecture.DolphinOES.java
com.sidereal.dolphinoes.architecture.GameBatch.java
com.sidereal.dolphinoes.architecture.GameBehavior.java
com.sidereal.dolphinoes.architecture.GameObject.java
com.sidereal.dolphinoes.architecture.GameScene.java
com.sidereal.dolphinoes.architecture.Module.java
com.sidereal.dolphinoes.architecture.core.Assets.java
com.sidereal.dolphinoes.architecture.core.Configurable.java
com.sidereal.dolphinoes.architecture.core.Debug.java
com.sidereal.dolphinoes.architecture.core.DolphinOESConfiguration.java
com.sidereal.dolphinoes.architecture.core.GameData.java
com.sidereal.dolphinoes.architecture.core.MouseMovedEvent.java
com.sidereal.dolphinoes.architecture.core.Time.java
com.sidereal.dolphinoes.architecture.core.assetload.AssetLoadHandler.java
com.sidereal.dolphinoes.architecture.core.assetload.AssetLoader.java
com.sidereal.dolphinoes.architecture.core.assetload.ClassFileHandleResolver.java
com.sidereal.dolphinoes.architecture.core.assetload.LoadingPercentage.java
com.sidereal.dolphinoes.architecture.core.input.ActionData.java
com.sidereal.dolphinoes.architecture.core.input.ActionEventWrapper.java
com.sidereal.dolphinoes.architecture.core.input.ActionEvent.java
com.sidereal.dolphinoes.architecture.core.input.Input.java
com.sidereal.dolphinoes.architecture.core.input.KeyTypedEvent.java
com.sidereal.dolphinoes.architecture.core.input.ScrollEvent.java
com.sidereal.dolphinoes.architecture.core.input.TouchData.java
com.sidereal.dolphinoes.architecture.core.input.TouchEventWrapper.java
com.sidereal.dolphinoes.architecture.core.input.TouchEvent.java
com.sidereal.dolphinoes.architecture.pos.Position.java
com.sidereal.dolphinoes.architecture.pos.Positions.java
com.sidereal.dolphinoes.backend.ConcreteGametester.java
com.sidereal.dolphinoes.backend.GameTester.java
com.sidereal.dolphinoes.backend.SceneGameTester.java
com.sidereal.dolphinoes.behaviors.audio.AudioListener.java
com.sidereal.dolphinoes.behaviors.audio.AudioPlayer.java
com.sidereal.dolphinoes.behaviors.events.EventTimer.java
com.sidereal.dolphinoes.behaviors.events.RecurringEvent.java
com.sidereal.dolphinoes.behaviors.input.Clickable.java
com.sidereal.dolphinoes.behaviors.particlesystem.ParticleEmitter.java
com.sidereal.dolphinoes.behaviors.particlesystem.ParticleHandler.java
com.sidereal.dolphinoes.behaviors.particlesystem.ParticleSpriteLayout.java
com.sidereal.dolphinoes.behaviors.particlesystem.ParticleSpriteObject.java
com.sidereal.dolphinoes.behaviors.pathfinding.PathfindingHandler.java
com.sidereal.dolphinoes.behaviors.pathfinding.PathfindingMap.java
com.sidereal.dolphinoes.behaviors.pathfinding.PathfindingNode.java
com.sidereal.dolphinoes.behaviors.pathfinding.PathfindingRoute.java
com.sidereal.dolphinoes.behaviors.renderer.DrawerBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.Drawer.java
com.sidereal.dolphinoes.behaviors.renderer.Renderer.java
com.sidereal.dolphinoes.behaviors.renderer.ninepatch.NinepatchBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.ninepatch.NinepatchDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.scml.SCMLBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.scml.SCMLDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.sprite.SpriteBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.sprite.SpriteDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.spritesequence.SpriteSequenceBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.spritesequence.SpriteSequenceDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.spritesequence.SpriteSequencePreference.java
com.sidereal.dolphinoes.behaviors.renderer.texture.TextureBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.texture.TextureDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.tilemap.TileMapBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.tilemap.TileMapDrawer.java
com.sidereal.dolphinoes.behaviors.triggers.Activatable.java
com.sidereal.dolphinoes.behaviors.triggers.Collider.java
com.sidereal.dolphinoes.behaviors.triggers.Hoverable.java
com.sidereal.dolphinoes.ui.MessageBubble.java
com.sidereal.dolphinoes.ui.TextBuilder.java
com.sidereal.dolphinoes.util.BooleanWrapper.java
com.sidereal.dolphinoes.util.DolphinOESException.java
com.sidereal.dolphinoes.util.FloatWrapper.java
com.sidereal.dolphinoes.util.IntWrapper.java
com.sidereal.dolphinoes.util.Utility.java