Inceptum/src/main/java/io/gitlab/jfronny/inceptum/Inceptum.java

266 lines
9.9 KiB
Java
Raw Normal View History

2021-10-29 22:50:42 +02:00
package io.gitlab.jfronny.inceptum;
2021-10-27 22:00:08 +02:00
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import imgui.ImGui;
import imgui.ImGuiIO;
import imgui.flag.ImGuiConfigFlags;
import imgui.gl3.ImGuiImplGl3;
import imgui.glfw.ImGuiImplGlfw;
2021-10-29 22:50:42 +02:00
import io.gitlab.jfronny.inceptum.gson.GsonIgnoreExclusionStrategy;
import io.gitlab.jfronny.inceptum.gson.MinecraftArgumentDeserializer;
import io.gitlab.jfronny.inceptum.gson.OauthTokenResponseDeserializer;
import io.gitlab.jfronny.inceptum.gson.RulesDeserializer;
import io.gitlab.jfronny.inceptum.model.inceptum.InceptumVersion;
2021-10-29 22:50:42 +02:00
import io.gitlab.jfronny.inceptum.model.microsoft.OauthTokenResponse;
import io.gitlab.jfronny.inceptum.model.mojang.MinecraftArgument;
import io.gitlab.jfronny.inceptum.model.mojang.Rules;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
2021-10-29 22:50:42 +02:00
import io.gitlab.jfronny.inceptum.windows.MainWindow;
import io.gitlab.jfronny.inceptum.windows.Window;
2021-10-30 19:26:59 +02:00
import org.lwjgl.glfw.Callbacks;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
2021-10-27 22:00:08 +02:00
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
2021-10-30 19:26:59 +02:00
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
2021-10-27 22:00:08 +02:00
import java.io.IOException;
2021-10-28 20:19:09 +02:00
import java.io.InputStream;
2021-10-29 22:50:42 +02:00
import java.io.InputStreamReader;
2021-10-28 23:27:47 +02:00
import java.lang.reflect.Modifier;
2021-10-27 22:00:08 +02:00
import java.nio.IntBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
//TODO generate gitignore
//TODO mods browser
//TODO allow instance sync through metadata
2021-10-27 22:07:07 +02:00
//TODO update checker
2021-10-29 22:50:42 +02:00
public class Inceptum {
2021-10-27 22:00:08 +02:00
public static final Set<Window> WINDOWS = new LinkedHashSet<>();
2021-10-30 19:26:59 +02:00
public static final Logger LOGGER = LoggerFactory.getLogger("Inceptum");
2021-10-27 22:00:08 +02:00
public static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(MinecraftArgument.class, new MinecraftArgumentDeserializer())
2021-10-27 22:07:07 +02:00
.registerTypeAdapter(Rules.class, new RulesDeserializer())
2021-10-29 22:50:42 +02:00
.registerTypeAdapter(OauthTokenResponse.class, new OauthTokenResponseDeserializer())
2021-10-28 23:27:47 +02:00
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
.excludeFieldsWithModifiers(Modifier.PRIVATE)
.addSerializationExclusionStrategy(new GsonIgnoreExclusionStrategy())
.setPrettyPrinting()
2021-10-27 22:00:08 +02:00
.create();
2021-10-28 20:19:09 +02:00
//TODO allow moving to .config or elsewhere
2021-10-27 22:00:08 +02:00
public static final Path CACHE_DIR = Path.of("run/cache");
public static final Path INSTANCE_DIR = Path.of("run/instances");
public static final Path ASSETS_DIR = Path.of("run/assets");
public static final Path LIBRARIES_DIR = Path.of("run/libraries");
2021-10-30 16:12:39 +02:00
public static final Path NATIVES_DIR = Path.of("run/natives");
2021-10-28 20:19:09 +02:00
private static final Path CONFIG_PATH = Path.of("run/glaunch2.json");
2021-10-29 22:50:42 +02:00
public static final Path ACCOUNTS_PATH = Path.of("run/accounts.json");
public static InceptumVersion VERSION;
2021-10-27 22:07:07 +02:00
public static Config CONFIG;
2021-10-27 22:00:08 +02:00
public static void main(String[] args) throws IOException {
2021-10-29 22:50:42 +02:00
try (InputStream is = Inceptum.class.getClassLoader().getResourceAsStream("version.json");
InputStreamReader isr = new InputStreamReader(is)) {
VERSION = GSON.fromJson(isr, InceptumVersion.class);
}
LOGGER.info("Launching Inceptum v" + VERSION.version);
2021-10-27 22:00:08 +02:00
LOGGER.info("Setting up cache dir");
2021-10-27 22:07:07 +02:00
if (!Files.exists(CONFIG_PATH)) Utils.writeObject(CONFIG_PATH, new Config());
CONFIG = Utils.loadObject(CONFIG_PATH, Config.class);
2021-10-27 22:00:08 +02:00
if (!Files.exists(CACHE_DIR)) Files.createDirectories(CACHE_DIR);
if (!Files.exists(INSTANCE_DIR)) Files.createDirectories(INSTANCE_DIR);
if (!Files.exists(ASSETS_DIR)) Files.createDirectories(ASSETS_DIR);
if (!Files.exists(LIBRARIES_DIR)) Files.createDirectories(LIBRARIES_DIR);
2021-10-29 22:50:42 +02:00
AccountManager.loadAccounts();
2021-10-27 22:00:08 +02:00
LOGGER.info("Initializing UI");
WINDOWS.add(new MainWindow());
2021-10-28 21:31:51 +02:00
init();
run();
dispose();
}
public static void saveConfig() {
try {
Utils.writeObject(CONFIG_PATH, CONFIG);
} catch (IOException e) {
LOGGER.error("Could not save config", e);
}
2021-10-27 22:00:08 +02:00
}
public static void open(Window window) {
WINDOWS.add(window);
}
2021-10-28 21:31:51 +02:00
private static final ImGuiImplGlfw imGuiGlfw = new ImGuiImplGlfw();
private static final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3();
2021-10-27 22:00:08 +02:00
2021-10-28 21:31:51 +02:00
private static String glslVersion = null;
2021-10-27 22:00:08 +02:00
/**
* Pointer to the native GLFW window.
*/
2021-10-28 21:31:51 +02:00
protected static long handle;
2021-10-27 22:00:08 +02:00
/**
* Method to initialize application.
*/
2021-10-28 21:31:51 +02:00
protected static void init() {
2021-10-27 22:00:08 +02:00
initWindow();
initImGui();
imGuiGlfw.init(handle, true);
imGuiGl3.init(glslVersion);
}
/**
* Method to dispose all used application resources and destroy its window.
*/
2021-10-28 21:31:51 +02:00
protected static void dispose() {
2021-10-27 22:00:08 +02:00
imGuiGl3.dispose();
imGuiGlfw.dispose();
2021-10-30 16:12:39 +02:00
//TODO figure out why this is a problem
//ImGui.destroyContext();
2021-10-28 20:19:09 +02:00
Callbacks.glfwFreeCallbacks(handle);
GLFW.glfwDestroyWindow(handle);
GLFW.glfwTerminate();
Objects.requireNonNull(GLFW.glfwSetErrorCallback(null)).free();
2021-10-27 22:00:08 +02:00
}
/**
* Method to create and initialize GLFW window.
*/
2021-10-28 21:31:51 +02:00
protected static void initWindow() {
2021-10-27 22:00:08 +02:00
GLFWErrorCallback.createPrint(System.err).set();
if (!GLFW.glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
decideGlGlslVersions();
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_FALSE);
2021-10-29 22:50:42 +02:00
handle = GLFW.glfwCreateWindow(10, 10, "Inceptum", MemoryUtil.NULL, MemoryUtil.NULL);
2021-10-27 22:00:08 +02:00
if (handle == MemoryUtil.NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
try (MemoryStack stack = MemoryStack.stackPush()) {
final IntBuffer pWidth = stack.mallocInt(1); // int*
final IntBuffer pHeight = stack.mallocInt(1); // int*
GLFW.glfwGetWindowSize(handle, pWidth, pHeight);
final GLFWVidMode vidmode = Objects.requireNonNull(GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor()));
GLFW.glfwSetWindowPos(handle, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
}
GLFW.glfwMakeContextCurrent(handle);
GL.createCapabilities();
GLFW.glfwSwapInterval(GLFW.GLFW_TRUE);
clearBuffer();
renderBuffer();
}
2021-10-28 21:31:51 +02:00
private static void decideGlGlslVersions() {
2021-10-27 22:00:08 +02:00
final boolean isMac = System.getProperty("os.name").toLowerCase().contains("mac");
if (isMac) {
glslVersion = "#version 150";
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE); // Required on Mac
} else {
glslVersion = "#version 130";
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 0);
}
}
/**
* Method to initialize Dear ImGui context. Could be overridden to do custom Dear ImGui setup before application start.
*/
2021-10-28 21:31:51 +02:00
protected static void initImGui() {
2021-10-27 22:00:08 +02:00
ImGui.createContext();
ImGuiIO io = ImGui.getIO();
io.addConfigFlags(ImGuiConfigFlags.ViewportsEnable);
//io.setConfigViewportsNoDecoration(false);
io.setConfigViewportsNoAutoMerge(true);
2021-10-28 21:31:51 +02:00
//TODO use included icons (https://www.nerdfonts.com/cheat-sheet)
//Nerd Fonts-patched ubuntu font
2021-10-29 22:50:42 +02:00
try (InputStream is = Inceptum.class.getClassLoader().getResourceAsStream("font.ttf")) {
2021-10-28 20:19:09 +02:00
assert is != null;
io.setFontDefault(io.getFonts().addFontFromMemoryTTF(is.readAllBytes(), 16f));
} catch (IOException e) {
e.printStackTrace();
}
2021-10-28 21:31:51 +02:00
applyTheme();
2021-10-27 22:00:08 +02:00
}
/**
* Main application loop.
*/
2021-10-28 21:31:51 +02:00
protected static void run() {
2021-10-27 22:00:08 +02:00
while (!GLFW.glfwWindowShouldClose(handle)) {
2021-10-28 20:19:09 +02:00
//frame
clearBuffer();
imGuiGlfw.newFrame();
ImGui.newFrame();
//render
2021-10-29 22:50:42 +02:00
if (Inceptum.WINDOWS.isEmpty()) exit();
2021-10-28 20:19:09 +02:00
else {
2021-10-30 19:26:59 +02:00
Window[] array = Inceptum.WINDOWS.toArray(new Window[0]);
for (int i = 0, arrayLength = array.length; i < arrayLength; i++) {
Window window = array[i];
2021-10-28 20:19:09 +02:00
if (window.isNew()) window.preFirstDraw();
2021-10-30 19:26:59 +02:00
if (ImGui.begin(window.getName() + "##" + i, window.getOpenState(), window.getFlags()))
window.draw();
2021-10-28 20:19:09 +02:00
ImGui.end();
2021-10-28 21:31:51 +02:00
if (!window.getOpenState().get()) window.close();
2021-10-28 20:19:09 +02:00
}
2021-10-27 22:00:08 +02:00
}
2021-10-28 20:19:09 +02:00
//end frame
ImGui.render();
imGuiGl3.renderDrawData(ImGui.getDrawData());
if (ImGui.getIO().hasConfigFlags(ImGuiConfigFlags.ViewportsEnable)) {
final long backupWindowPtr = GLFW.glfwGetCurrentContext();
ImGui.updatePlatformWindows();
ImGui.renderPlatformWindowsDefault();
GLFW.glfwMakeContextCurrent(backupWindowPtr);
}
renderBuffer();
2021-10-27 22:00:08 +02:00
}
}
2021-10-28 21:31:51 +02:00
private static void clearBuffer() {
2021-10-27 22:00:08 +02:00
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
}
2021-10-28 21:31:51 +02:00
private static void renderBuffer() {
2021-10-27 22:00:08 +02:00
GLFW.glfwSwapBuffers(handle);
GLFW.glfwPollEvents();
}
2021-10-28 21:31:51 +02:00
public static void exit() {
2021-10-28 23:27:47 +02:00
GLFW.glfwSetWindowShouldClose(handle, true);
2021-10-28 21:31:51 +02:00
}
public static void applyTheme() {
if (CONFIG.darkTheme) ImGui.styleColorsDark();
else ImGui.styleColorsLight();
}
2021-10-27 22:00:08 +02:00
}