/* * This file is part of the Illarion project. * * Copyright © 2015 - Illarion e.V. * * Illarion is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Illarion is distributed in the hope that it will be useful, * 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. */ package illarion.client.world; import illarion.client.graphics.AnimationManager; import illarion.client.graphics.MapDisplayManager; import illarion.client.gui.GameGui; import illarion.client.gui.controller.GameScreenController; import illarion.client.net.NetComm; import illarion.client.util.ChatHandler; import illarion.client.util.UpdateTaskManager; import illarion.client.world.interactive.InteractionManager; import org.illarion.engine.Engine; import org.illarion.engine.EngineException; import org.illarion.engine.graphic.LightTracer; import org.jetbrains.annotations.Contract; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; /** * This class is used to unify the access to the different components of the game and to ensure a proper * initialization and cleaning of those components if needed. * * @author Martin Karing <nitram@illarion.org> */ @ThreadSafe public final class World { /** * The singleton instance of this class. */ @Nonnull private static final World INSTANCE = new World(); public static void shutdownWorld() { if (INSTANCE.net != null) { INSTANCE.net.disconnect(); } if (INSTANCE.player != null) { INSTANCE.player.shutdown(); } if (INSTANCE.lights != null) { INSTANCE.lights.saveShutdown(); } if (INSTANCE.map != null) { INSTANCE.map.getMiniMap().saveAllMaps(); INSTANCE.map.saveShutdown(); } if (INSTANCE.weather != null) { INSTANCE.weather.shutdown(); } if (INSTANCE.musicBox != null) { INSTANCE.musicBox.saveShutdown(); } } /** * Shutdown every class that is currently maintained by the world. */ @SuppressWarnings("StaticMethodOnlyUsedInOneClass") public static void cleanEnvironment() { shutdownWorld(); INSTANCE.chatHandler = null; INSTANCE.aniManager = null; INSTANCE.interactionManager = null; INSTANCE.map = null; INSTANCE.musicBox = null; INSTANCE.lights = null; INSTANCE.player = null; INSTANCE.people = null; INSTANCE.net = null; INSTANCE.weather = null; INSTANCE.clock = null; INSTANCE.updateManager = null; INSTANCE.init = false; } @Nonnull public static AnimationManager getAnimationManager() { AnimationManager instance = INSTANCE.aniManager; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static Clock getClock() { Clock instance = INSTANCE.clock; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static ChatHandler getChatHandler() { ChatHandler instance = INSTANCE.chatHandler; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static LightTracer getLights() { LightTracer instance = INSTANCE.lights; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } /** * Get the map of the game. * * @return the map of the game */ @Nonnull public static GameMap getMap() { GameMap instance = INSTANCE.map; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static MapDisplayManager getMapDisplay() { MapDisplayManager instance = INSTANCE.mapDisplay; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static MusicBox getMusicBox() { MusicBox instance = INSTANCE.musicBox; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static NetComm getNet() { NetComm instance = INSTANCE.net; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static People getPeople() { People instance = INSTANCE.people; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static Player getPlayer() { Player instance = INSTANCE.player; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static Weather getWeather() { Weather instance = INSTANCE.weather; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static InteractionManager getInteractionManager() { InteractionManager instance = INSTANCE.interactionManager; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static UpdateTaskManager getUpdateTaskManager() { UpdateTaskManager instance = INSTANCE.updateManager; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } @Nonnull public static GameGui getGameGui() { GameGui instance = INSTANCE.gameGui; if (instance == null) { throw new IllegalStateException("World is not yet initialized"); } return instance; } /** * The animation manager that takes care for updating and synchronizing the animations in the game. */ @Nullable private AnimationManager aniManager; /** * The manager that takes care for the interaction between map and GUI. */ @Nullable private InteractionManager interactionManager; /** * The class that handles the Chat in and output. */ @Nullable private ChatHandler chatHandler; /** * The instance of the clock used to keep track of the time in Illarion. */ @Nullable private Clock clock; /** * The instance of the light tracer of the game. */ @Nullable private LightTracer lights; /** * The instance of the map of the game. */ @Nullable private GameMap map; /** * The map display manager that takes care for rendering the map. */ private MapDisplayManager mapDisplay; /** * The music box that takes care for playing the proper music. */ @Nullable private MusicBox musicBox; /** * The network communication interface that is used in this game session. */ @Nullable private NetComm net; /** * The instance of the people storage that is used in this session. */ @Nullable private People people; /** * The instance of the player who plays currently. */ @Nullable private Player player; /** * The weather class that is used to maintain the current weather and * display it. */ @Nullable private Weather weather; /** * This update manager takes care for executing tasks in sync with the main loop. */ @Nullable private UpdateTaskManager updateManager; /** * The reference to the GUI of the game. */ @Nullable private GameGui gameGui; /** * Private constructor to ensure the sole instance is the singleton * instance. */ private World() { } /** * This variable is set {@code true} once the world is initialized. */ private boolean init; /** * Prepare all components of the world. This needs to be called before the world is used. * * @param engine the engine that is used to display the game */ public static void initWorldComponents(@Nonnull Engine engine) throws EngineException { if (INSTANCE.init) { return; } INSTANCE.init = true; INSTANCE.updateManager = new UpdateTaskManager(); INSTANCE.aniManager = new AnimationManager(); INSTANCE.chatHandler = new ChatHandler(); INSTANCE.clock = new Clock(); INSTANCE.map = new GameMap(engine); INSTANCE.lights = new LightTracer(INSTANCE.map); INSTANCE.mapDisplay = new MapDisplayManager(engine); INSTANCE.musicBox = new MusicBox(engine); INSTANCE.net = new NetComm(); INSTANCE.people = new People(); INSTANCE.player = new Player(engine); INSTANCE.weather = new Weather(); INSTANCE.interactionManager = new InteractionManager(); } /** * Init the GUI of the game. * * @param engine the game engine */ public static void initGui(@Nonnull Engine engine) { INSTANCE.gameGui = new GameScreenController(engine.getInput()); } @Contract(pure = true) public static boolean isInitDone() { return INSTANCE.init; } }