From fb0ebc8ded094e81e7a0ab65d8709f22234f8743 Mon Sep 17 00:00:00 2001 From: Joshua Skelton Date: Thu, 23 Apr 2020 16:36:21 -0700 Subject: [PATCH] Initial implementation of a basic file watcher --- .../dungeoneer/editor/EditorApplication.java | 53 +++++++++++++++++++ .../src/com/interrupt/dungeoneer/Art.java | 44 +++++++++++++++ .../dungeoneer/overlays/DebugOverlay.java | 49 +---------------- 3 files changed, 98 insertions(+), 48 deletions(-) diff --git a/DelvEdit/src/com/interrupt/dungeoneer/editor/EditorApplication.java b/DelvEdit/src/com/interrupt/dungeoneer/editor/EditorApplication.java index b8a2df03..ce039bd1 100644 --- a/DelvEdit/src/com/interrupt/dungeoneer/editor/EditorApplication.java +++ b/DelvEdit/src/com/interrupt/dungeoneer/editor/EditorApplication.java @@ -1,6 +1,7 @@ package com.interrupt.dungeoneer.editor; import com.badlogic.gdx.*; +import com.badlogic.gdx.Files; import com.badlogic.gdx.Input.Buttons; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.backends.lwjgl.LwjglApplication; @@ -73,8 +74,11 @@ import javax.swing.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.nio.file.*; import java.util.HashMap; +import static java.nio.file.StandardWatchEventKinds.*; + public class EditorApplication implements ApplicationListener { public JFrame frame; @@ -348,6 +352,8 @@ protected Decal newObject () { Vector3 rayOutVector = new Vector3(); + private Thread fileWatcher; + public EditorApplication() { frame = new JFrame("DelvEdit"); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); @@ -375,6 +381,8 @@ public void windowClosing(WindowEvent e) { config.addIcon("icon-16.png", Files.FileType.Internal); // 16x16 icon (Windows) new LwjglApplication(this, config); + + startFileWatcher(); } public void init(){ @@ -410,6 +418,11 @@ public void dispose() { gameApp.dispose(); } + try { + fileWatcher.interrupt(); + } + catch (Exception ignore) {} + frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING)); } @@ -4351,4 +4364,44 @@ private void vizualizePicking() { public void setTitle(String title) { Gdx.graphics.setTitle(title + " - DelvEdit"); } + + private void startFileWatcher() { + // Super basic file watcher that refreshes the assets when any file changes. + fileWatcher = new Thread() { + public void run() { + try { + WatchService watchService = FileSystems.getDefault().newWatchService(); + java.nio.file.Path path = Paths.get(Gdx.files.getLocalStoragePath()); + path.register(watchService, ENTRY_CREATE, ENTRY_MODIFY); + + boolean running = true; + while(running) { + WatchKey key = watchService.take(); + for (WatchEvent ignored : key.pollEvents()) { + refreshAssets(); + break; + } + + running = key.reset(); + } + } + catch (Exception ignore) {} + } + }; + fileWatcher.setPriority(Thread.MIN_PRIORITY); + fileWatcher.start(); + } + + private void refreshAssets() { + try { + // Give the asset a chance to finish writing. + Thread.sleep(125); + + Art.refresh(); + for (Entity e : level.entities) { + e.drawable.refresh(); + } + } + catch (Exception ignored) {} + } } diff --git a/Dungeoneer/src/com/interrupt/dungeoneer/Art.java b/Dungeoneer/src/com/interrupt/dungeoneer/Art.java index bb1c9a4f..f66534a0 100644 --- a/Dungeoneer/src/com/interrupt/dungeoneer/Art.java +++ b/Dungeoneer/src/com/interrupt/dungeoneer/Art.java @@ -16,9 +16,12 @@ import com.badlogic.gdx.math.collision.BoundingBox; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ArrayMap; +import com.interrupt.dungeoneer.entities.Entity; import com.interrupt.dungeoneer.game.CachePools; import com.interrupt.dungeoneer.game.Game; import com.interrupt.dungeoneer.gfx.Bitmap; +import com.interrupt.dungeoneer.gfx.GlRenderer; +import com.interrupt.dungeoneer.gfx.Tesselator; import com.interrupt.dungeoneer.gfx.TextureAtlas; import com.interrupt.dungeoneer.ui.UiSkin; @@ -205,4 +208,45 @@ static public void KillCache() { // Might have some pooled meshes to clear CachePools.clearMeshPool(); } + + public static void refresh() { + try { + Art.KillCache(); + + Game.instance.loadManagers(); + GameManager.renderer.initTextures(); + GameManager.renderer.initShaders(); + + GlRenderer.staticMeshPool.resetAndDisposeAllMeshes(); + Tesselator.tesselatorMeshPool.resetAndDisposeAllMeshes(); + + // reset all drawables now that we've reset stuff + for (Entity e : Game.GetLevel().entities) { + if(e.drawable != null) { + e.drawable.refresh(); + e.drawable.update(e); + } + } + for (Entity e : Game.GetLevel().static_entities) { + if(e.drawable != null) { + e.drawable.refresh(); + e.drawable.update(e); + } + } + for (Entity e : Game.GetLevel().non_collidable_entities) { + if(e.drawable != null) { + e.drawable.refresh(); + e.drawable.update(e); + } + } + + GameManager.renderer.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + Game.GetLevel().isDirty = true; + + UiSkin.loadSkin(); + } + catch(Exception ex) { + Gdx.app.log("Delver", "Could not refresh: " + ex.getMessage()); + } + } } diff --git a/Dungeoneer/src/com/interrupt/dungeoneer/overlays/DebugOverlay.java b/Dungeoneer/src/com/interrupt/dungeoneer/overlays/DebugOverlay.java index 8358c051..79573b1a 100644 --- a/Dungeoneer/src/com/interrupt/dungeoneer/overlays/DebugOverlay.java +++ b/Dungeoneer/src/com/interrupt/dungeoneer/overlays/DebugOverlay.java @@ -2,7 +2,6 @@ import java.util.HashMap; -import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; @@ -15,16 +14,12 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Array; import com.interrupt.dungeoneer.Art; -import com.interrupt.dungeoneer.GameManager; import com.interrupt.dungeoneer.entities.Entity; import com.interrupt.dungeoneer.entities.Item; import com.interrupt.dungeoneer.entities.Monster; import com.interrupt.dungeoneer.entities.Player; import com.interrupt.dungeoneer.entities.items.*; import com.interrupt.dungeoneer.game.Game; -import com.interrupt.dungeoneer.gfx.GlRenderer; -import com.interrupt.dungeoneer.gfx.Tesselator; -import com.interrupt.dungeoneer.ui.UiSkin; import com.interrupt.managers.ItemManager; public class DebugOverlay extends WindowOverlay { @@ -357,7 +352,7 @@ protected void addRefreshItem(Table table) { @Override public void clicked(InputEvent event, float x, float y) { OverlayManager.instance.remove(thisOverlay); - refreshData(); + Art.refresh(); } @Override @@ -765,46 +760,4 @@ public void clicked(InputEvent event, float x, float y) { return contentTable; } - - // Re-load all the key assets - public void refreshData() { - try { - Art.KillCache(); - - Game.instance.loadManagers(); - GameManager.renderer.initTextures(); - GameManager.renderer.initShaders(); - - GlRenderer.staticMeshPool.resetAndDisposeAllMeshes(); - Tesselator.tesselatorMeshPool.resetAndDisposeAllMeshes(); - - // reset all drawables now that we've reset stuff - for (Entity e : Game.GetLevel().entities) { - if(e.drawable != null) { - e.drawable.refresh(); - e.drawable.update(e); - } - } - for (Entity e : Game.GetLevel().static_entities) { - if(e.drawable != null) { - e.drawable.refresh(); - e.drawable.update(e); - } - } - for (Entity e : Game.GetLevel().non_collidable_entities) { - if(e.drawable != null) { - e.drawable.refresh(); - e.drawable.update(e); - } - } - - GameManager.renderer.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - Game.GetLevel().isDirty = true; - - UiSkin.loadSkin(); - } - catch(Exception ex) { - Gdx.app.log("Delver", "Could not refresh: " + ex.getMessage()); - } - } }