Package org.terasology.launcher

Source Code of org.terasology.launcher.TerasologyLauncher

/*
* Copyright 2014 MovingBlocks
*
* 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 org.terasology.launcher;

import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.crashreporter.CrashReporter;
import org.terasology.launcher.gui.javafx.ApplicationController;
import org.terasology.launcher.log.TempLogFilePropertyDefiner;
import org.terasology.launcher.util.BundleUtils;
import org.terasology.launcher.util.Languages;
import org.terasology.launcher.util.LauncherStartFailedException;
import org.terasology.launcher.version.TerasologyLauncherVersionInfo;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

public final class TerasologyLauncher extends Application {

    private static final Logger logger = LoggerFactory.getLogger(TerasologyLauncher.class);

    private static final int SPLASH_WIDTH = 800;
    private static final int SPLASH_HEIGHT = 223;

    private Pane splashLayout;
    private ProgressBar loadProgress;
    private Label progressText;
    private Stage mainStage;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void init() throws Exception {
        ImageView splash = new ImageView(BundleUtils.getFxImage("splash"));
        loadProgress = new ProgressBar();
        loadProgress.setPrefWidth(SPLASH_WIDTH);
        progressText = new Label();
        splashLayout = new VBox();
        splashLayout.getChildren().addAll(splash, loadProgress, progressText);
        progressText.setAlignment(Pos.CENTER);
        splashLayout.getStylesheets().add(BundleUtils.getStylesheet("css_splash"));
        splashLayout.setEffect(new DropShadow());
    }

    @Override
    public void start(final Stage initialStage) {
        logger.info("TerasologyLauncher is starting");
        logSystemInformation();

        initLanguage();

        final Task<LauncherConfiguration> launcherInitTask = new LauncherInitTask(initialStage);

        showSplashStage(initialStage, launcherInitTask);
        Thread initThread = new Thread(launcherInitTask);

        launcherInitTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(final WorkerStateEvent workerStateEvent) {
                try {
                    LauncherConfiguration config = launcherInitTask.getValue();
                    if (config == null) {
                        throw new LauncherStartFailedException("Launcher configuration was `null`.");
                    }
                    showMainStage(config);
                } catch (IOException | LauncherStartFailedException e) {
                    openCrashReporterAndExit(e);
                }
            }
        });
        initThread.start();
    }

    /**
     * Opens the CrashReporter with the given exception and exits the launcher.
     *
     * @param e the exception causing the launcher to fail
     */
    private void openCrashReporterAndExit(Exception e) {
        logger.error("The TerasologyLauncher could not be started!");

        Path logFile = TempLogFilePropertyDefiner.getInstance().getLogFile();
        CrashReporter.report(e, logFile);
        System.exit(1);
    }

    private void showMainStage(final LauncherConfiguration launcherConfiguration) throws IOException {
        mainStage = new Stage(StageStyle.DECORATED);

        // launcher frame
        FXMLLoader fxmlLoader;
        Parent root;
        /* Fall back to default language if loading the FXML file files with the current locale */
        try {
            fxmlLoader = BundleUtils.getFXMLLoader("application");
            root = (Parent) fxmlLoader.load();
        } catch (IOException e) {
            fxmlLoader = BundleUtils.getFXMLLoader("application");
            fxmlLoader.setResources(ResourceBundle.getBundle("org.terasology.launcher.bundle.LabelsBundle", Languages.DEFAULT_LOCALE));
            root = (Parent) fxmlLoader.load();
        }
        final ApplicationController controller = fxmlLoader.getController();
        controller.initialize(launcherConfiguration.getLauncherDirectory(), launcherConfiguration.getDownloadDirectory(), launcherConfiguration.getTempDirectory(),
            launcherConfiguration.getLauncherSettings(), launcherConfiguration.getGameVersions(), mainStage);

        Scene scene = new Scene(root);
        scene.getStylesheets().add(BundleUtils.getStylesheet("css_terasology"));

        decorateStage(mainStage);

        mainStage.setScene(scene);
        mainStage.setResizable(false);
        mainStage.show();

        logger.info("The TerasologyLauncher was successfully started.");
    }

    private void showSplashStage(final Stage initialStage, final Task<LauncherConfiguration> task) {
        progressText.textProperty().bind(task.messageProperty());
        loadProgress.progressProperty().bind(task.progressProperty());
        task.stateProperty().addListener(new ChangeListener<Worker.State>() {
            @Override
            public void changed(ObservableValue<? extends Worker.State> observableValue, Worker.State oldState, Worker.State newState) {
                if (newState == Worker.State.SUCCEEDED) {
                    loadProgress.progressProperty().unbind();
                    loadProgress.setProgress(1);
                    if (mainStage != null) {
                        mainStage.setIconified(false);
                    }
                    initialStage.toFront();
                    FadeTransition fadeSplash = new FadeTransition(Duration.seconds(1.2), splashLayout);
                    fadeSplash.setFromValue(1.0);
                    fadeSplash.setToValue(0.0);
                    fadeSplash.setOnFinished(new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent actionEvent) {
                            initialStage.hide();
                        }
                    });
                    fadeSplash.play();
                } // todo add code to gracefully handle other task states.
            }
        });

        decorateStage(initialStage);

        Scene splashScene = new Scene(splashLayout);
        initialStage.initStyle(StageStyle.UNDECORATED);
        final Rectangle2D bounds = Screen.getPrimary().getBounds();
        initialStage.setScene(splashScene);
        initialStage.setX(bounds.getMinX() + bounds.getWidth() / 2 - SPLASH_WIDTH / 2);
        initialStage.setY(bounds.getMinY() + bounds.getHeight() / 2 - SPLASH_HEIGHT / 2);
        initialStage.show();
    }

    private void logSystemInformation() {
        if (logger.isDebugEnabled()) {
            // Java
            logger.debug("Java: {} {} {}", System.getProperty("java.version"), System.getProperty("java.vendor"), System.getProperty("java.home"));
            logger.debug("Java VM: {} {} {}", System.getProperty("java.vm.name"), System.getProperty("java.vm.vendor"), System.getProperty("java.vm.version"));
            logger.debug("Java classpath: {}", System.getProperty("java.class.path"));

            // OS
            logger.debug("OS: {} {} {}", System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version"));

            //Memory
            logger.debug("Max. Memory: {} bytes", Runtime.getRuntime().maxMemory());

            // TerasologyLauncherVersionInfo
            logger.debug("Launcher version: {}", TerasologyLauncherVersionInfo.getInstance());
        }
    }

    private void initLanguage() {
        logger.trace("Init Languages...");
        Languages.init();
        logger.debug("Language: {}", Languages.getCurrentLocale());
    }

    /**
     * Adds title and icons to a stage.
     *
     * @param stage the stage to decorate
     */
    private static void decorateStage(Stage stage) {
        stage.setTitle("TerasologyLauncher " + TerasologyLauncherVersionInfo.getInstance().getDisplayVersion());
        List<String> iconIds = Arrays.asList("icon16", "icon32", "icon64", "icon128");

        for (String id : iconIds) {
            try {
                Image image = BundleUtils.getFxImage(id);
                stage.getIcons().add(image);
            } catch (MissingResourceException e) {
                logger.warn("Could not load icon image", e);
            }
        }
    }
}
TOP

Related Classes of org.terasology.launcher.TerasologyLauncher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.