com.sidereal.dolphinoes.architecture.DolphinOES.java Source code

Java tutorial

Introduction

Here is the source code for com.sidereal.dolphinoes.architecture.DolphinOES.java

Source

/******************************************************************************* Copyright 2014 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.sidereal.dolphinoes.architecture;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectMap.Entry;
import com.sidereal.dolphinoes.architecture.core.Assets;
import com.sidereal.dolphinoes.architecture.core.Debug;
import com.sidereal.dolphinoes.architecture.core.DolphinOESConfiguration;
import com.sidereal.dolphinoes.architecture.core.GameData;
import com.sidereal.dolphinoes.architecture.core.Time;
import com.sidereal.dolphinoes.architecture.core.input.Input;
import com.sidereal.dolphinoes.util.DolphinOESException;

/** Bridge between LibGDX {@link ApplicationListener} and DolphinOES' {@link DolphinOES}.
 * <p>
 * Creates a {@link DolphinOES} instance using a {@link DolphinOESConfiguration} instance for changing framework
 * settings, as well as a {@link GameScene} instance to redirect to. The DolphinOES {@link DolphinOESConfiguration}
 * parameter is not necessary, as there are 2 constructors that can be called, {@link DolphinOES#DolphinOES(GameScene)}
 * and {@link DolphinOES#DolphinOES(GameScene, DolphinOESConfiguration)}
 * 
 * @author Claudiu Bele */
public class DolphinOES extends Game {
    // region fields

    @SuppressWarnings("unused")
    private static final String version = "Beta 0.4.9.3";

    public static final Time time = new Time();

    public static final Debug debug = new Debug();

    public static final Assets assets = new Assets();

    public static final GameData data = new GameData();

    public static final Input input = new Input();

    /** Array containing all of the functionality modules. */
    private static ObjectMap<Class<? extends Module>, Module> modules;

    private static DolphinOES instance;

    private GameScene targetScene;

    private boolean isFocused;

    // endregion

    // region constructors

    /** DolphinOES constructor that does not require a {@link DolphinOESConfiguration} parameter. This constructor calls
     * {@link #DolphinOES(GameScene, DolphinOESConfiguration)} by creating a new <code>DolphinOES</code> instance (thus
     * the application has default configuration).
     * <P>
     * Is to be used in the platform-dependent main methods.
     * 
     * @throws DolphinOESException
     *             see {@link #DolphinOES(GameScene, DolphinOESConfiguration)} for exception
     * @param initialScene
     *            The scene to switch to after initialisation */
    public DolphinOES(GameScene initialScene) {

        this(initialScene, new DolphinOESConfiguration());
    }

    /** DolphinOES constructor that requires scene and a configuration. If the configuration is null, a new instance is
     * created with default values.
     * <p>
     * The default application modules are configured, by calling the configure method in them with the
     * DolphinOESConfiguration parameters. All custom modules found in {@link DolphinOESConfiguration#modules} are added
     * to {@link DolphinOES#modules}.
     * 
     * 
     * @throws DolphinOESException
     *             when the <code>initialscene</code> parameter is null
     * @param initialScene
     * @param cfg */
    public DolphinOES(GameScene initialScene, DolphinOESConfiguration cfg) {

        if (initialScene == null)
            throw new DolphinOESException("DolphinOES(GameScene,DolphinOESConfiguration) constructor "
                    + "parameter 'initialScene' of type GameScene is null");
        if (cfg == null)
            cfg = new DolphinOESConfiguration();

        debug.configure(cfg);
        assets.configure(cfg);
        data.configure(cfg);
        input.configure(cfg);
        time.configure(cfg);

        DolphinOES.modules = new ObjectMap<Class<? extends Module>, Module>();
        DolphinOES.modules.putAll(cfg.modules);
        DolphinOES.instance = this;

        targetScene = initialScene;
    }

    /** Method called after initialising the LibGDX backend. The modules' (default and custom) {@link Module#create()}
     * method is called, in which LibGDX data can be accessed.
     * <p>
     * The method also sets the screen to render as the one passed in the constructors. */
    @Override
    public void create() {

        // create the default modules
        debug.create();
        assets.create();
        data.create();
        input.create();
        time.create();

        // create all custom modules, now they can access Gdx functionality for
        // proper setup
        for (Entry<Class<? extends Module>, Module> entry : modules.entries()) {
            entry.value.create();
        }

        setScreen(targetScene);
    }

    /** Method called when unfocusing the window. Sets {@link DolphinOES#isFocused} to true, which can be accessed using
     * {@link #isFocused()} for background actions to run ( nothing happens by default) */
    @Override
    public void pause() {

        isFocused = true;
        super.pause();
    }

    /** Method called when focusing the window. Sets {@link DolphinOES#isFocused} to false, which can be accessed using
     * {@link #isFocused()} for background actions to run ( nothing happens by default) */
    @Override
    public void resume() {

        isFocused = false;
        super.resume();
    }

    /** Method called when every frame that handles scene transitions, updating modules( default and custom) as well as
     * calling {@link GameScene#render(float)} from the parent class implementation of {@link Game#render()}. */
    @Override
    public void render() {

        if (getScene() != targetScene)
            handleSceneTrasition();

        // update time data

        // update default modules
        debug.update();
        assets.update();
        data.update();
        time.update();

        // update all custom Modules
        for (Entry<Class<? extends Module>, Module> entry : modules.entries()) {
            entry.value.update();
        }
        super.render();
        input.update();

    }

    /** Method for changing the screen. The transition between scenes and the objects they share will be handled
     * automatically in {@link #handleSceneTrasition()}. If the passed parameter is not an instance of {@link GameScene}
     * , an exception is thrown
     * 
     * @throws {@link DolphinOESException} if the passed parameter is not an instance of {@link GameScene}.
     * @param screen
     *            The screen to change to */
    @Override
    public void setScreen(Screen screen) {

        if (instance.getScreen() == null) {
            if (!(screen instanceof GameScene))
                throw new DolphinOESException(
                        "DolphinOES.setScreen parameter screen has to be a subclass of GameScene");

            super.setScreen(screen);
            ((GameScene) screen).createGameBatches();
            ((GameScene) screen).createScene();
        } else {
            instance.targetScene = (GameScene) screen;
            ((GameScene) targetScene).createGameBatches();

        }

    }

    /** Returns the current scene that is being rendered.
     * 
     * @return the current scene */
    public static GameScene getScene() {

        return (GameScene) instance.getScreen();
    }

    public static DolphinOES getInstance() {
        return instance;
    }

    /** Returns whether or not the application is focused.
     * 
     * @return boolean value for whether or not the application is focused. */
    public static boolean isFocused() {

        return instance.isFocused;
    }

    // endregion

    // region methods

    /** Adds a module to run throughout the entire application. This method is to be used at runtime, as for
     * initialisation, you can add {@link Module} to {@link DolphinOESConfiguration} using
     * {@link DolphinOESConfiguration#addModule(Module)},
     * 
     * <p>
     * The module will be accessible from game scenes, batches, objects and behaviors through {@link #getModule(Class)}.
     * 
     * @param module
     * @return */
    public static <T extends Module> Class<DolphinOES> addModule(T module) {

        if (module == null)
            throw new NullPointerException(
                    "DolphinOESConfiguration.addModule parameter 'module' of type Module is null");

        if (modules.get(module.getClass()) != null)
            throw new DolphinOESException("DolphinOESConfiguration.addModule parameter type " + module.getClass()
                    + " is already in the list of modules");

        modules.put(module.getClass(), module);
        return DolphinOES.class;

    }

    /** Returns a custom module, retrieved by passing the class we want the Module we want to retrieve has.
     * 
     * @throws DolphinOESException
     *             if the module class parameter does not implement the Module interface or is not in the list of
     *             modules
     * @param moduleClass
     *            The class of the module we want to return.
     * 
     * @return Module implementation, or an exception */
    @SuppressWarnings("unchecked")
    public static <T extends Module> T getModule(Class<T> moduleClass) {

        if (!moduleClass.getInterfaces()[0].equals(Module.class))
            throw new DolphinOESException(
                    "DolphinOES.getModule parameter 'moduleClass' does not" + " implement the Module interface");

        if (modules.get(moduleClass) == null)
            throw new DolphinOESException("DolphinOES.getModule parameter type " + moduleClass.getClass()
                    + " can't be found in the list of modules");

        return (T) modules.get(moduleClass);

    }

    /** Returns a boolean for whether or not the system contains a custom module with the passed parameter as a class.
     * 
     * @param moduleClass
     *            the Module implementation class to find in the list of custom modules
     * @return a boolean for whether or not the system contains desired module */
    public static boolean containsModule(Class<? extends Module> moduleClass) {

        return modules.get(moduleClass) != null;
    }

    /** Internal method for passing objects from one scene to another, as well as disposing objects from the old scene
     * that are not required in the next scene. */
    private void handleSceneTrasition() {

        GameScene currScene = DolphinOES.getScene();

        // iterate over gamebatches to find all objects to remove
        for (int i = 0; i < currScene.gameBatches.size(); i++) {
            GameBatch gamebatch = currScene.gameBatches.get(i);

            // iterate over the objects in the gamebatch, finding if it has to
            // be removed
            // or not.
            for (int j = 0; j < gamebatch.objects.size(); j++) {
                GameObject obj = gamebatch.objects.get(j);

                if (currScene.getToKeepForNextScene().contains(obj) || obj.isPersistent()) {

                    obj.scene = targetScene;
                    obj.setGameBatch(obj.gameBatch.name);

                    j--; // decreasing index for object in gamebatch list due to
                         // calling setGameBatch
                         // the object is removed from the previous gamebatch that it
                         // was in.
                    for (int k = 0; k < obj.behaviors.size(); k++) {
                        obj.behaviors.get(k).scene = targetScene;
                    }

                    obj.handleSceneChange();
                } else {
                    obj.disposeInternal();
                }
            }
            // end of iterating over gamebatch objects
        }

        for (int i = 0; i < currScene.gameBatches.size(); i++) {
            currScene.gameBatches.get(i).dispose();
        }
        super.setScreen(targetScene);
        ((GameScene) targetScene).createScene();
        return;
    }

    // endregion methods
}