de.winniehell.battlebeavers.storage.GameStorage.java Source code

Java tutorial

Introduction

Here is the source code for de.winniehell.battlebeavers.storage.GameStorage.java

Source

/*
   (c) winniehell, wintermadnezz (2012)
    
   This file is part of the game Battle Beavers.
    
   Battle Beavers is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
    
   Battle Beavers is distributed in the hope that it will be fun,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
    
   You should have received a copy of the GNU General Public License
   along with Battle Beavers. If not, see <http://www.gnu.org/licenses/>.
*/

package de.winniehell.battlebeavers.storage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.anddev.andengine.util.StreamUtils;
import de.winniehell.battlebeavers.App;
import de.winniehell.battlebeavers.R;
import de.winniehell.battlebeavers.Settings;
import de.winniehell.battlebeavers.gameplay.Game;
import de.winniehell.battlebeavers.gameplay.GameInfo;
import de.winniehell.battlebeavers.ingame.IGameEventsListener;
import de.winniehell.battlebeavers.ingame.IMenuDialogListener;
import de.winniehell.battlebeavers.ingame.ISoldierListener;
import de.winniehell.battlebeavers.ingame.Soldier;
import de.winniehell.battlebeavers.ingame.Tile;
import de.winniehell.battlebeavers.ingame.WayPoint;

import android.content.Context;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

/**
 * used to load a game state from file (and save it)
 *
 * @author <a href="https://github.com/winniehell/">winniehell</a>
 */
public class GameStorage {

    /**
     * default constructor, loads game state from file
     * @param pContext
     * @param pGame
     * @throws UnexpectedTileContentException
     */
    public GameStorage(final Context pContext, final Game pGame) throws Exception {
        context = pContext;
        game = pGame;

        // initialize game object containers
        teams = new ArrayList<SoldierList>(getSettings().getMaxPlayers());

        for (int i = 0; i < getSettings().getMaxPlayers(); ++i) {
            teams.add(new SoldierList());
        }

        loadFromFile();
        //saveToFile();
    }

    public void addSoldier(final Soldier pSoldier) throws UnexpectedTileContentException {

        for (final SoldierList team : teams) {
            for (final Soldier soldier : team) {
                if (soldier.getTile().equals(pSoldier.getTile())) {
                    throw new UnexpectedTileContentException("Tile is not empty!");
                }
            }
        }

        teams.get(pSoldier.getTeam()).add(pSoldier);
        pSoldier.setPositionListener(positionListener);
        pSoldier.setGameEventsListener(gameListener);

        for (final WayPoint waypoint : pSoldier.getWaypoints()) {
            waypoint.setMenuDialogListener(menuListener);
        }
    }

    /**
     * add waypoint to container
     * @param pWaypoint a waypoint
     * @throws UnexpectedTileContentException
     */
    public void addWaypoint(final WayPoint pWaypoint) throws UnexpectedTileContentException {

        // TODO isTileOccupied(pWaypoint.getTile()))

        pWaypoint.setMenuDialogListener(menuListener);
    }

    public Soldier getSoldierById(final int pSoldierId) {
        for (final SoldierList team : teams) {
            for (final Soldier soldier : team) {
                if (soldier.getId() == pSoldierId) {
                    return soldier;
                }
            }
        }

        return null;
    }

    public Soldier getSoldierByTile(final int pTeam, final Tile pTile) throws UnexpectedTileContentException {

        for (Soldier soldier : teams.get(pTeam)) {
            if (soldier.getTile().equals(pTile)) {
                return soldier;
            }
        }

        throw new UnexpectedTileContentException("No soldier on that tile!");
    }

    public SoldierList getSoldiersByTeam(final int pTeam) {
        if (pTeam < getSettings().getMaxPlayers()) {
            return teams.get(pTeam);
        } else {
            throw new IndexOutOfBoundsException();
        }
    }

    public WayPoint getWaypointByTile(final Soldier pSoldier, final Tile pTile)
            throws UnexpectedTileContentException {
        if (pSoldier == null) {
            throw new UnexpectedTileContentException("No waypoint on that tile!");
        }

        for (WayPoint waypoint : pSoldier.getWaypoints()) {
            if (waypoint.getTile().equals(pTile)) {
                return waypoint;
            }
        }

        throw new UnexpectedTileContentException("No waypoint on that tile!");
    }

    public boolean hasSoldierOnTile(final int pTeam, final Tile pTile) {
        if ((pTeam < 0) || (pTeam >= teams.size())) {
            return false;
        }

        for (Soldier soldier : teams.get(pTeam)) {
            if (soldier.getTile().equals(pTile)) {
                return true;
            }
        }

        return false;
    }

    public boolean hasWaypointOnTile(final Soldier pSoldier, final Tile pTile) {
        if (pSoldier == null) {
            return false;
        }

        for (WayPoint waypoint : pSoldier.getWaypoints()) {
            if (waypoint.getTile().equals(pTile)) {
                return true;
            }
        }

        return false;
    }

    public void removeSoldier(final Soldier pSoldier) throws UnexpectedTileContentException {
        teams.get(pSoldier.getTeam()).remove(pSoldier);
    }

    public void removeSoldiers() throws UnexpectedTileContentException {
        Log.d(TAG, "old state: " + CustomGSON.getInstance().toJson(teams));

        for (SoldierList team : teams) {
            SoldierList oldList = (SoldierList) team.clone();

            for (final Soldier soldier : oldList) {
                soldier.detachSelf();
                removeSoldier(soldier);
            }
        }
    }

    public void saveToFile() throws FileNotFoundException {

        final Gson gson = CustomGSON.getInstance();

        JsonWriter writer;

        writer = CustomGSON.getWriter(context, getFileName());

        try {
            writer.beginArray();
            for (final SoldierList team : teams) {
                for (final Soldier soldier : team) {
                    gson.toJson(soldier, Soldier.class, writer);
                }
            }
            writer.endArray();
        } catch (final IOException e) {
            Log.e(TAG, context.getString(R.string.error_json_writing), e);
        } finally {
            try {
                writer.close();
            } catch (final IOException e) {
                Log.e(TAG, context.getString(R.string.error_json_writing), e);
            }
        }
    }

    public void setMenuDialogListener(final IMenuDialogListener mListener) {
        menuListener = mListener;

        for (final SoldierList team : teams) {
            for (final Soldier soldier : team) {
                for (final WayPoint waypoint : soldier.getWaypoints()) {
                    waypoint.setMenuDialogListener(mListener);
                }
            }
        }
    }

    public void setGameEventsListener(final IGameEventsListener pListener) {
        gameListener = pListener;

        for (final SoldierList team : teams) {
            for (final Soldier soldier : team) {
                soldier.setGameEventsListener(gameListener);
                Log.e("GameListener", "" + gameListener.toString() + " is set");
            }
        }
    }

    public void setPositionListener(final ISoldierListener pListener) {
        positionListener = pListener;

        for (final SoldierList team : teams) {
            for (final Soldier soldier : team) {
                soldier.setPositionListener(pListener);
            }
        }
    }

    @SuppressWarnings("serial")
    public static class UnexpectedTileContentException extends Exception {
        public UnexpectedTileContentException(final String pMessage) {
            super(pMessage);
        }
    }

    /**
     * @name debug
     * @{
     */
    private static final String TAG = GameStorage.class.getName();
    /**
     * @}
     */

    private final Context context;
    private final Game game;

    private final ArrayList<SoldierList> teams;

    private ISoldierListener positionListener;
    private IMenuDialogListener menuListener;
    private IGameEventsListener gameListener;

    private String getFileName() {
        return game.getDirectory(context) + "/setup.json";
    }

    private Settings getSettings() {
        if (context.getApplicationContext() instanceof App) {
            return ((App) context.getApplicationContext()).getSettings();
        } else {
            return null;
        }
    }

    /**
     * loads the storage from file
     * @throws FileNotFoundException
     */
    private void loadFromFile() throws FileNotFoundException {

        if (!(new File(getFileName())).exists()) {
            final GameInfo info = GameInfo.fromFile(context, game);

            Log.d(TAG, "Copying maps/" + info.getMapName() + "/setup.json");

            try {
                final InputStream src = context.getAssets().open("maps/" + info.getMapName() + "/setup.json");

                final FileOutputStream dest = new FileOutputStream(getFileName());

                StreamUtils.copyAndClose(src, dest);
            } catch (final IOException e) {
                Log.e(TAG, "Copying map failed!", e);
                return;
            }
        }

        try {
            Log.d(TAG, "loading: " + StreamUtils.readFully(new FileInputStream(getFileName())));
        } catch (final Exception e) {
            Log.e(TAG, e.getMessage());
            return;
        }

        final Gson gson = CustomGSON.getInstance();
        final JsonReader reader = CustomGSON.getReader(context, getFileName());

        // file does not exist
        if (reader == null) {
            throw new FileNotFoundException(getFileName());
        }

        try {
            reader.beginArray();
            while (reader.hasNext()) {
                final Soldier soldier = gson.fromJson(reader, Soldier.class);

                try {
                    addSoldier(soldier);
                } catch (final UnexpectedTileContentException e) {
                    Log.e(TAG, "Adding soldier failed!", e);
                }
            }
            reader.endArray();
        } catch (final Exception e) {
            Log.e(TAG, "Loading game storage failed!", e);
        } finally {
            try {
                reader.close();
            } catch (final IOException e) {
                Log.e(TAG, "Closing reader failed!", e);
            }
        }
    }
}