editor mode asset file drag'n'drop
This commit is contained in:
parent
ed9dac0b80
commit
62ad638255
@ -1326,6 +1326,8 @@ Fix entity swap button resetting position
|
||||
Fix block meshgen not incrementing indices correctly
|
||||
Fix block meshgen algorithm iteration bug
|
||||
Add debug control to swap first/third person
|
||||
Setup scaffolding for drag-and-drop asset handling
|
||||
Editor mode asset file drag and drop
|
||||
|
||||
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import electrosphere.client.ui.menu.debug.entity.ImGuiEntityMacros;
|
||||
import electrosphere.client.ui.menu.editor.ImGuiEditorWindows;
|
||||
import electrosphere.controls.ControlHandler.ControlsState;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.renderer.ui.imgui.ImGuiLinePlot;
|
||||
@ -35,8 +36,8 @@ public class ImGuiWindowMacros {
|
||||
* Initializes imgui windows
|
||||
*/
|
||||
public static void initImGuiWindows(){
|
||||
createMainDebugMenu();
|
||||
createFramerateGraph();
|
||||
ImGuiWindowMacros.createMainDebugMenu();
|
||||
ImGuiWindowMacros.createFramerateGraph();
|
||||
ImGuiPlayerEntity.createPlayerEntityDebugWindow();
|
||||
ImGuiFluidMonitor.createFluidDebugWindows();
|
||||
ImGuiEntityMacros.createClientEntityWindows();
|
||||
@ -51,6 +52,7 @@ public class ImGuiWindowMacros {
|
||||
ImGuiNetworkMonitor.createNetworkMonitorWindows();
|
||||
ImGuiGriddedManager.createGriddedManagerWindows();
|
||||
ImGuiMemory.createMemoryWindows();
|
||||
ImGuiEditorWindows.initEditorWindows();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,13 +62,13 @@ public class ImGuiWindowMacros {
|
||||
globalFrametimeWindow = new ImGuiWindow("Frametime Graph");
|
||||
globalFrametimePlot = new ImGuiLinePlot("Frametime plot");
|
||||
globalFrametimeDatasets = new HashMap<String,ImGuiLinePlotDataset>();
|
||||
initFramerateGraphSeries("totalframerate");
|
||||
initFramerateGraphSeries("serversim");
|
||||
initFramerateGraphSeries("clientsim");
|
||||
initFramerateGraphSeries("render");
|
||||
initFramerateGraphSeries("assetLoad");
|
||||
initFramerateGraphSeries("clientNetwork");
|
||||
initFramerateGraphSeries("controls");
|
||||
ImGuiWindowMacros.initFramerateGraphSeries("totalframerate");
|
||||
ImGuiWindowMacros.initFramerateGraphSeries("serversim");
|
||||
ImGuiWindowMacros.initFramerateGraphSeries("clientsim");
|
||||
ImGuiWindowMacros.initFramerateGraphSeries("render");
|
||||
ImGuiWindowMacros.initFramerateGraphSeries("assetLoad");
|
||||
ImGuiWindowMacros.initFramerateGraphSeries("clientNetwork");
|
||||
ImGuiWindowMacros.initFramerateGraphSeries("controls");
|
||||
globalFrametimeWindow.addElement(globalFrametimePlot);
|
||||
globalFrametimeWindow.setOpen(false);
|
||||
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(globalFrametimeWindow);
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
package electrosphere.client.ui.menu.editor;
|
||||
|
||||
import electrosphere.controls.ControlHandler.ControlsState;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.renderer.ui.imgui.ImGuiWindow;
|
||||
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
|
||||
import imgui.ImGui;
|
||||
|
||||
/**
|
||||
* Details window of the editor
|
||||
*/
|
||||
public class ImGuiEditorDetailsWindow {
|
||||
|
||||
/**
|
||||
* The window object
|
||||
*/
|
||||
private static ImGuiWindow detailsWindow;
|
||||
|
||||
/**
|
||||
* Gets the details window
|
||||
* @return the details window
|
||||
*/
|
||||
public static ImGuiWindow getDetailsWindow(){
|
||||
return detailsWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits the details menu
|
||||
*/
|
||||
protected static void createDetailsMenu(){
|
||||
detailsWindow = new ImGuiWindow("Details");
|
||||
detailsWindow.setCallback(new ImGuiWindowCallback() {
|
||||
@Override
|
||||
public void exec() {
|
||||
ImGui.text("Some details or smthn");
|
||||
//close button
|
||||
if(ImGui.button("Close")){
|
||||
detailsWindow.setOpen(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
detailsWindow.setOpen(false);
|
||||
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(detailsWindow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the open state of the menu
|
||||
*/
|
||||
protected static void toggleDetailsMenus(){
|
||||
detailsWindow.setOpen(!detailsWindow.isOpen());
|
||||
if(detailsWindow.isOpen()){
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_MAIN_MENU);
|
||||
} else {
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
package electrosphere.client.ui.menu.editor;
|
||||
|
||||
import electrosphere.controls.ControlHandler.ControlsState;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.renderer.ui.imgui.ImGuiWindow;
|
||||
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
|
||||
import imgui.ImGui;
|
||||
|
||||
/**
|
||||
* Various methods for creating specific imgui windows in engine
|
||||
*/
|
||||
public class ImGuiEditorWindows {
|
||||
|
||||
|
||||
//scene hierarchy menu
|
||||
private static ImGuiWindow mainWindow;
|
||||
|
||||
//tracks if the editor menu is open
|
||||
private static boolean editorIsOpen = false;
|
||||
|
||||
/**
|
||||
* Initializes imgui windows
|
||||
*/
|
||||
public static void initEditorWindows(){
|
||||
ImGuiEditorWindows.createMainEditorMenu();
|
||||
ImGuiEditorDetailsWindow.createDetailsMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hierarchy window
|
||||
* @return the hierarchy window
|
||||
*/
|
||||
public static ImGuiWindow getHierarchyWindow(){
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inits the hierarchy menus
|
||||
*/
|
||||
private static void createMainEditorMenu(){
|
||||
mainWindow = new ImGuiWindow("Editor");
|
||||
mainWindow.setCallback(new ImGuiWindowCallback() {
|
||||
@Override
|
||||
public void exec() {
|
||||
ImGui.text("hello :)");
|
||||
//close button
|
||||
if(ImGui.button("Close")){
|
||||
mainWindow.setOpen(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
mainWindow.setOpen(false);
|
||||
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(mainWindow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the open state of the menu
|
||||
*/
|
||||
public static void toggleEditorMenus(){
|
||||
mainWindow.setOpen(!mainWindow.isOpen());
|
||||
ImGuiEditorWindows.editorIsOpen = mainWindow.isOpen();
|
||||
if(mainWindow.isOpen()){
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_MAIN_MENU);
|
||||
} else {
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||
}
|
||||
|
||||
//toggle all windows
|
||||
ImGuiEditorDetailsWindow.toggleDetailsMenus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the main editor menu properly toggles controls if it is closed with the X button
|
||||
*/
|
||||
public static void synchronizeMainEditorMenuVisibility(){
|
||||
if(ImGuiEditorWindows.editorIsOpen && !mainWindow.isOpen()){
|
||||
ImGuiEditorWindows.editorIsOpen = false;
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,6 +5,7 @@ import java.util.List;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import electrosphere.client.ui.menu.editor.ImGuiEditorWindows;
|
||||
import electrosphere.controls.Control;
|
||||
import electrosphere.controls.Control.ControlMethod;
|
||||
import electrosphere.controls.Control.ControlType;
|
||||
@ -23,6 +24,7 @@ public class ControlCategoryInGameDebug {
|
||||
public static final String DEBUG_FRAMESTEP = "framestep";
|
||||
public static final String DEBUG_SWAP_EDITOR_MODE = "swapEditorMode";
|
||||
public static final String DEBUG_SWITCH_FIRST_THIRD = "switchFirstThird";
|
||||
public static final String DEBUG_SWAP_GAME_EDITOR = "swapGameEditor";
|
||||
|
||||
/**
|
||||
* Maps the controls
|
||||
@ -30,8 +32,9 @@ public class ControlCategoryInGameDebug {
|
||||
*/
|
||||
public static void mapControls(ControlHandler handler){
|
||||
handler.addControl(DEBUG_FRAMESTEP, new Control(ControlType.KEY, GLFW.GLFW_KEY_P,false,"Framesetp","Steps the engine forward one frame"));
|
||||
handler.addControl(DEBUG_SWAP_EDITOR_MODE, new Control(ControlType.KEY, GLFW.GLFW_KEY_F4,false,"Swap Editor Mode","Swaps to/from the editor entity"));
|
||||
handler.addControl(DEBUG_SWAP_EDITOR_MODE, new Control(ControlType.KEY, GLFW.GLFW_KEY_F4,false,"Swap Editor Entity","Swaps to/from the editor entity"));
|
||||
handler.addControl(DEBUG_SWITCH_FIRST_THIRD, new Control(ControlType.KEY, GLFW.GLFW_KEY_F5,false,"Switch First/Third Person","Swaps between first and third person"));
|
||||
handler.addControl(DEBUG_SWAP_GAME_EDITOR, new Control(ControlType.KEY, GLFW.GLFW_KEY_F6,false,"Toggle Editor Mode","Toggles between the editor mode and the actual game mode"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,6 +76,16 @@ public class ControlCategoryInGameDebug {
|
||||
Globals.controlHandler.setIsThirdPerson(!Globals.controlHandler.cameraIsThirdPerson());
|
||||
}});
|
||||
controlMap.get(DEBUG_SWITCH_FIRST_THIRD).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
||||
|
||||
//
|
||||
//Swap between editor and game mode
|
||||
//
|
||||
alwaysOnDebugControlList.add(controlMap.get(DEBUG_SWAP_GAME_EDITOR));
|
||||
controlMap.get(DEBUG_SWAP_GAME_EDITOR).setOnPress(new ControlMethod(){public void execute(MouseState mouseState){
|
||||
LoggerInterface.loggerEngine.INFO("Toggle Editor Mode");
|
||||
ImGuiEditorWindows.toggleEditorMenus();
|
||||
}});
|
||||
controlMap.get(DEBUG_SWAP_GAME_EDITOR).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ import electrosphere.controls.ScrollCallback;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.engine.assetmanager.AssetManager;
|
||||
import electrosphere.engine.loadingthreads.InitialAssetLoading;
|
||||
import electrosphere.engine.os.fs.FileWatcherService;
|
||||
import electrosphere.engine.profiler.Profiler;
|
||||
import electrosphere.engine.service.ServiceManager;
|
||||
import electrosphere.engine.signal.SignalSystem;
|
||||
@ -387,6 +388,9 @@ public class Globals {
|
||||
//manager for all widgets currently being drawn to screen
|
||||
public static ElementService elementService;
|
||||
public static int openInventoriesCount = 0;
|
||||
|
||||
//file service
|
||||
public static FileWatcherService fileWatcherService;
|
||||
|
||||
//collision world data
|
||||
public static CollisionWorldData commonWorldData;
|
||||
@ -546,6 +550,7 @@ public class Globals {
|
||||
Globals.particleService = (ParticleService)serviceManager.registerService(new ParticleService());
|
||||
Globals.scriptEngine = (ScriptEngine)serviceManager.registerService(new ScriptEngine());
|
||||
Globals.mainThreadSignalService = (MainThreadSignalService)serviceManager.registerService(new MainThreadSignalService());
|
||||
Globals.fileWatcherService = (FileWatcherService)serviceManager.registerService(new FileWatcherService());
|
||||
serviceManager.instantiate();
|
||||
//
|
||||
//End service manager
|
||||
@ -557,6 +562,7 @@ public class Globals {
|
||||
Globals.signalSystem.registerService(Globals.particleService);
|
||||
Globals.signalSystem.registerService(Globals.scriptEngine);
|
||||
Globals.signalSystem.registerService(Globals.mainThreadSignalService);
|
||||
Globals.signalSystem.registerService(Globals.fileWatcherService);
|
||||
|
||||
|
||||
}
|
||||
@ -744,6 +750,7 @@ public class Globals {
|
||||
Globals.threadManager = null;
|
||||
Globals.signalSystem = null;
|
||||
Globals.serviceManager = null;
|
||||
Globals.fileWatcherService = null;
|
||||
Globals.clientConnection = null;
|
||||
Globals.clientSynchronizationManager = null;
|
||||
Globals.server = null;
|
||||
|
||||
@ -263,7 +263,7 @@ public class Main {
|
||||
LoggerInterface.loggerEngine.DEBUG_LOOP("Begin load assets");
|
||||
Globals.assetManager.loadAssetsInQueue();
|
||||
LoggerInterface.loggerEngine.DEBUG_LOOP("Begin delete assets");
|
||||
Globals.assetManager.deleteModelsInDeleteQueue();
|
||||
Globals.assetManager.handleDeleteQueue();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
@ -302,8 +302,11 @@ public class Main {
|
||||
SynchronousSignalHandling.runMainThreadSignalHandlers();
|
||||
|
||||
///
|
||||
/// S C R I P T E N G I N E
|
||||
/// E N G I N E S E R V I C E S
|
||||
///
|
||||
if(Globals.fileWatcherService != null){
|
||||
Globals.fileWatcherService.poll();
|
||||
}
|
||||
if(Globals.RUN_SCRIPTS && Globals.scriptEngine != null){
|
||||
Globals.scriptEngine.scanScriptDir();
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ public class AssetManager {
|
||||
|
||||
Map<String,PoseModel> poseModelsLoadedIntoMemory = new ConcurrentHashMap<String,PoseModel>();
|
||||
List<String> poseModelsInQueue = new CopyOnWriteArrayList<String>();
|
||||
List<String> poseModelsInDeleteQueue = new CopyOnWriteArrayList<String>();
|
||||
|
||||
//A queue of homogenous buffers to allocate this render frame
|
||||
List<HomogenousUniformBuffer> homogenousBufferAllocationQueue = new CopyOnWriteArrayList<HomogenousUniformBuffer>();
|
||||
@ -173,43 +174,59 @@ public class AssetManager {
|
||||
|
||||
//allocate homogenous buffers
|
||||
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Allocate homogenous buffers");
|
||||
allocateHomogenousBuffers();
|
||||
this.allocateHomogenousBuffers();
|
||||
|
||||
//allocate instance array buffers
|
||||
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Allocate instance array buffers");
|
||||
allocateInstanceArrayBuffers();
|
||||
this.allocateInstanceArrayBuffers();
|
||||
|
||||
//override meshes
|
||||
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Override meshes");
|
||||
performMeshOverrides();
|
||||
this.performMeshOverrides();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Deletes all models in the delete queue
|
||||
*/
|
||||
public void deleteModelsInDeleteQueue(){
|
||||
for(String modelPath : modelsInDeleteQueue){
|
||||
Model model = this.fetchModel(modelPath);
|
||||
if(model != null){
|
||||
model.delete();
|
||||
}
|
||||
this.modelsLoadedIntoMemory.remove(modelPath);
|
||||
|
||||
|
||||
//
|
||||
//Updating assets
|
||||
//
|
||||
public void updateAsset(String path){
|
||||
LoggerInterface.loggerEngine.DEBUG("AssetManager - updateAsset");
|
||||
//models
|
||||
if(modelsLoadedIntoMemory.containsKey(path)){
|
||||
this.queueModelForDeletion(path);
|
||||
this.deleteModelsInDeleteQueue();
|
||||
this.addModelPathToQueue(path);
|
||||
}
|
||||
//textures
|
||||
if(texturesLoadedIntoMemory.containsKey(path)){
|
||||
this.queueTextureForDeletion(path);
|
||||
this.deleteTexturesInDeleteQueue();
|
||||
this.addTexturePathtoQueue(path);
|
||||
}
|
||||
//pose models
|
||||
if(poseModelsLoadedIntoMemory.containsKey(path)){
|
||||
this.queuePoseModelForDeletion(path);
|
||||
this.deletePoseModelsInDeleteQueue();
|
||||
this.addPoseModelPathToQueue(path);
|
||||
}
|
||||
if(audioLoadedIntoMemory.containsKey(path)){
|
||||
throw new Error("Unhandled asset type! (Audio)");
|
||||
}
|
||||
if(shadersLoadedIntoMemory.containsKey(path)){
|
||||
throw new Error("Unhandled asset type! (Shader - Visual)");
|
||||
}
|
||||
if(computeShadersLoadedIntoMemory.containsKey(path)){
|
||||
throw new Error("Unhandled asset type! (Shader - Compute)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all textures in the delete queue
|
||||
* Handles the delete queues
|
||||
*/
|
||||
public void deleteTexturesInDeleteQueue(){
|
||||
for(String texturePath : texturesInDeleteQueue){
|
||||
Texture texture = this.fetchTexture(texturePath);
|
||||
if(texture != null){
|
||||
texture.free();
|
||||
}
|
||||
this.texturesLoadedIntoMemory.remove(texturePath);
|
||||
}
|
||||
public void handleDeleteQueue(){
|
||||
this.deleteModelsInDeleteQueue();
|
||||
this.deletePoseModelsInDeleteQueue();
|
||||
this.deleteTexturesInDeleteQueue();
|
||||
}
|
||||
|
||||
|
||||
@ -217,6 +234,8 @@ public class AssetManager {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Models
|
||||
//
|
||||
@ -305,6 +324,19 @@ public class AssetManager {
|
||||
// modelsLoadedIntoMemory.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all models in the delete queue
|
||||
*/
|
||||
public void deleteModelsInDeleteQueue(){
|
||||
for(String modelPath : modelsInDeleteQueue){
|
||||
Model model = this.fetchModel(modelPath);
|
||||
if(model != null){
|
||||
model.delete();
|
||||
}
|
||||
this.modelsLoadedIntoMemory.remove(modelPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -347,6 +379,27 @@ public class AssetManager {
|
||||
public void registerPoseModelWithPath(PoseModel m, String path){
|
||||
poseModelsLoadedIntoMemory.put(path, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues a pose model for deletion
|
||||
* @param modelPath The path to the pose model
|
||||
*/
|
||||
public void queuePoseModelForDeletion(String modelPath){
|
||||
poseModelsInDeleteQueue.add(modelPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all pose models in the delete queue
|
||||
*/
|
||||
public void deletePoseModelsInDeleteQueue(){
|
||||
for(String modelPath : poseModelsInDeleteQueue){
|
||||
PoseModel poseModel = this.fetchPoseModel(modelPath);
|
||||
if(poseModel != null){
|
||||
poseModel.delete();
|
||||
}
|
||||
this.poseModelsLoadedIntoMemory.remove(modelPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -423,6 +476,19 @@ public class AssetManager {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all textures in the delete queue
|
||||
*/
|
||||
public void deleteTexturesInDeleteQueue(){
|
||||
for(String texturePath : texturesInDeleteQueue){
|
||||
Texture texture = this.fetchTexture(texturePath);
|
||||
if(texture != null){
|
||||
texture.free();
|
||||
}
|
||||
this.texturesLoadedIntoMemory.remove(texturePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
63
src/main/java/electrosphere/engine/os/OSDragAndDrop.java
Normal file
63
src/main/java/electrosphere/engine/os/OSDragAndDrop.java
Normal file
@ -0,0 +1,63 @@
|
||||
package electrosphere.engine.os;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import electrosphere.client.ui.menu.editor.ImGuiEditorWindows;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.os.fs.FileWatcher;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
|
||||
/**
|
||||
* Handles drag-and-drop signals from the OS
|
||||
*/
|
||||
public class OSDragAndDrop {
|
||||
|
||||
/**
|
||||
* Fires when a file path is dropped on the application
|
||||
* @param paths The paths of the files
|
||||
*/
|
||||
public static void handleDragAndDrop(List<String> paths){
|
||||
if(ImGuiEditorWindows.getHierarchyWindow().isOpen()){
|
||||
OSDragAndDrop.handleDropAsset(paths);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the case where asset path(s) have been dropped on the application
|
||||
* @param paths The paths of the assets
|
||||
*/
|
||||
private static void handleDropAsset(List<String> paths){
|
||||
//try watching the file and register it to be an asset
|
||||
LoggerInterface.loggerFileIO.WARNING("File(s) added to application");
|
||||
for(String rawPath : paths){
|
||||
String normalized = rawPath.toLowerCase();
|
||||
Path absolutePath = new File(rawPath).toPath();
|
||||
Path relativePath = new File("./assets").getAbsoluteFile().toPath().relativize(absolutePath);
|
||||
|
||||
//register based on file type
|
||||
if(normalized.contains(".glsl") || normalized.contains(".dae")){
|
||||
Globals.assetManager.addModelPathToQueue(relativePath.toString());
|
||||
} else if(normalized.contains(".wav") || normalized.contains(".ogg")){
|
||||
Globals.assetManager.addAudioPathToQueue(relativePath.toString());
|
||||
} else if(normalized.contains(".jpg") || normalized.contains(".jpeg") || normalized.contains(".png")){
|
||||
Globals.assetManager.addTexturePathtoQueue(relativePath.toString());
|
||||
} else {
|
||||
throw new Error("Unhandled file type! " + rawPath);
|
||||
}
|
||||
|
||||
//watch the asset for file updates
|
||||
LoggerInterface.loggerEngine.WARNING("Tracking " + rawPath);
|
||||
Globals.fileWatcherService.trackFile(new FileWatcher(rawPath).setOnWrite(updatedPath -> {
|
||||
LoggerInterface.loggerFileIO.WARNING("File updated: " + updatedPath.toString());
|
||||
Globals.assetManager.updateAsset(updatedPath.toString());
|
||||
}).setOnDelete(updatedPath -> {
|
||||
LoggerInterface.loggerFileIO.WARNING("File deleted: " + updatedPath.toString());
|
||||
}).setOnCreate(updatedPath -> {
|
||||
LoggerInterface.loggerFileIO.WARNING("File created: " + updatedPath.toString());
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
123
src/main/java/electrosphere/engine/os/fs/FileWatcher.java
Normal file
123
src/main/java/electrosphere/engine/os/fs/FileWatcher.java
Normal file
@ -0,0 +1,123 @@
|
||||
package electrosphere.engine.os.fs;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Sets a callback to fire every time a type of event happens to a fire
|
||||
*/
|
||||
public class FileWatcher {
|
||||
|
||||
/**
|
||||
* The path of the file that is being watched
|
||||
*/
|
||||
Path path;
|
||||
|
||||
/**
|
||||
* The callback that fires when the file is created
|
||||
*/
|
||||
Consumer<Path> onCreate;
|
||||
|
||||
/**
|
||||
* The callback that fires when the file is edited
|
||||
*/
|
||||
Consumer<Path> onWrite;
|
||||
|
||||
/**
|
||||
* The callback that fires when the file is deleted
|
||||
*/
|
||||
Consumer<Path> onDelete;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param path The path the watcher should follow
|
||||
*/
|
||||
public FileWatcher(String path){
|
||||
this.path = new File(path).toPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path of the file that this watcher is tracking
|
||||
* @return The path of the file that this watcher is tracking
|
||||
*/
|
||||
public Path getPath(){
|
||||
return this.path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the on-create callback for the watcher
|
||||
* @param onCreate The callback that fires when the file is created
|
||||
* @return The file watcher instance that the callback is being attached to
|
||||
*/
|
||||
public FileWatcher setOnCreate(Consumer<Path> onCreate){
|
||||
this.onCreate = onCreate;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the on-create callback
|
||||
* @return The on-create callback
|
||||
*/
|
||||
public Consumer<Path> getOnCreate(){
|
||||
return this.onCreate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the file is created
|
||||
*/
|
||||
protected void onCreate(){
|
||||
this.onCreate.accept(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the on-write callback for the watcher
|
||||
* @param onWrite The callback that fires when the file is edited
|
||||
* @return The file watcher instance that the callback is being attached to
|
||||
*/
|
||||
public FileWatcher setOnWrite(Consumer<Path> onWrite){
|
||||
this.onWrite = onWrite;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the on-write callback
|
||||
* @return The on-write callback
|
||||
*/
|
||||
public Consumer<Path> getOnWrite(){
|
||||
return this.onWrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the file is written to
|
||||
*/
|
||||
protected void onWrite(){
|
||||
this.onWrite.accept(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the on-delete callback for the watcher
|
||||
* @param onDelete The callback that fires when the file is deleted
|
||||
* @return The file watcher instance that the callback is being attached to
|
||||
*/
|
||||
public FileWatcher setOnDelete(Consumer<Path> onDelete){
|
||||
this.onDelete = onDelete;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the on-delete callback
|
||||
* @return The on-delete callback
|
||||
*/
|
||||
public Consumer<Path> getOnDelete(){
|
||||
return this.onDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the file is deleted
|
||||
*/
|
||||
protected void onDelete(){
|
||||
this.onDelete.accept(path);
|
||||
}
|
||||
|
||||
}
|
||||
118
src/main/java/electrosphere/engine/os/fs/FileWatcherService.java
Normal file
118
src/main/java/electrosphere/engine/os/fs/FileWatcherService.java
Normal file
@ -0,0 +1,118 @@
|
||||
package electrosphere.engine.os.fs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardWatchEventKinds;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.nio.file.WatchKey;
|
||||
import java.nio.file.WatchService;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import electrosphere.engine.signal.Signal.SignalType;
|
||||
import electrosphere.engine.signal.SignalServiceImpl;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
|
||||
/**
|
||||
* Service that manages file watchers
|
||||
*/
|
||||
public class FileWatcherService extends SignalServiceImpl {
|
||||
|
||||
/**
|
||||
* The file system object
|
||||
*/
|
||||
FileSystem fs;
|
||||
|
||||
/**
|
||||
* The watch service
|
||||
*/
|
||||
WatchService watchService;
|
||||
|
||||
/**
|
||||
* Map of path to watcher
|
||||
*/
|
||||
Map<String,FileWatcher> pathWatcherMap;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public FileWatcherService() {
|
||||
super(
|
||||
"FileWatcher",
|
||||
new SignalType[]{
|
||||
}
|
||||
);
|
||||
this.fs = FileSystems.getDefault();
|
||||
try {
|
||||
this.watchService = fs.newWatchService();
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerFileIO.ERROR(e);
|
||||
}
|
||||
this.pathWatcherMap = new HashMap<String,FileWatcher>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks a file
|
||||
* @param watcher Tracks a file
|
||||
*/
|
||||
public void trackFile(FileWatcher watcher){
|
||||
try {
|
||||
watcher.getPath().getParent().register(
|
||||
watchService,
|
||||
new WatchEvent.Kind[]{StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE}
|
||||
);
|
||||
pathWatcherMap.put(watcher.path.toAbsolutePath().normalize().toString(),watcher);
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerEngine.ERROR(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans all tracked files
|
||||
*/
|
||||
public void poll(){
|
||||
WatchKey key = null;
|
||||
while((key = watchService.poll()) != null){
|
||||
List<WatchEvent<?>> events = key.pollEvents();
|
||||
Path keyParentDir = (Path)key.watchable();
|
||||
for(WatchEvent<?> event : events){
|
||||
if(event.kind() == StandardWatchEventKinds.ENTRY_MODIFY){
|
||||
if(event.context() instanceof Path){
|
||||
Path filePath = (Path)event.context();
|
||||
Path resolved = keyParentDir.resolve(filePath);
|
||||
String normalized = resolved.toAbsolutePath().normalize().toString();
|
||||
FileWatcher watcher = this.pathWatcherMap.get(normalized);
|
||||
if(watcher != null){
|
||||
watcher.onWrite();
|
||||
}
|
||||
}
|
||||
} else if(event.kind() == StandardWatchEventKinds.ENTRY_CREATE){
|
||||
if(event.context() instanceof Path){
|
||||
Path filePath = (Path)event.context();
|
||||
Path resolved = keyParentDir.resolve(filePath);
|
||||
String normalized = resolved.toAbsolutePath().normalize().toString();
|
||||
FileWatcher watcher = this.pathWatcherMap.get(normalized);
|
||||
if(watcher != null){
|
||||
watcher.onCreate();
|
||||
}
|
||||
}
|
||||
} else if(event.kind() == StandardWatchEventKinds.ENTRY_DELETE){
|
||||
if(event.context() instanceof Path){
|
||||
Path filePath = (Path)event.context();
|
||||
Path resolved = keyParentDir.resolve(filePath);
|
||||
String normalized = resolved.toAbsolutePath().normalize().toString();
|
||||
FileWatcher watcher = this.pathWatcherMap.get(normalized);
|
||||
if(watcher != null){
|
||||
watcher.onDelete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
key.reset();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,10 +9,13 @@ import static org.lwjgl.opengl.GL30.glBindRenderbuffer;
|
||||
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Vector3d;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
import org.lwjgl.opengl.GL;
|
||||
@ -21,8 +24,10 @@ import org.lwjgl.opengl.GL30;
|
||||
import org.lwjgl.opengl.GL45;
|
||||
import org.lwjgl.opengl.GLDebugMessageCallback;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.os.OSDragAndDrop;
|
||||
import electrosphere.engine.signal.Signal.SignalType;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.debug.DebugRendering;
|
||||
@ -444,6 +449,19 @@ public class RenderingEngine {
|
||||
// fogColor.flip();
|
||||
// GL11.glFogfv(GL_FOG_COLOR, fogColor);
|
||||
|
||||
//
|
||||
//Set file drag-and-drop for app
|
||||
//
|
||||
GLFW.glfwSetDropCallback(Globals.window, (long window, int count, long names) -> {
|
||||
PointerBuffer charPointers = MemoryUtil.memPointerBuffer(names, count);
|
||||
List<String> paths = new LinkedList<String>();
|
||||
for(int i = 0; i < count; i++){
|
||||
String name = MemoryUtil.memUTF8(charPointers.get(i));
|
||||
paths.add(name);
|
||||
}
|
||||
OSDragAndDrop.handleDragAndDrop(paths);
|
||||
});
|
||||
|
||||
//
|
||||
//Init pipelines
|
||||
//
|
||||
|
||||
@ -4,6 +4,7 @@ import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import electrosphere.client.ui.menu.debug.ImGuiWindowMacros;
|
||||
import electrosphere.client.ui.menu.editor.ImGuiEditorWindows;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
@ -63,6 +64,7 @@ public class ImGuiPipeline implements RenderPipeline {
|
||||
ImGui.render();
|
||||
imGuiGl13.renderDrawData(ImGui.getDrawData());
|
||||
ImGuiWindowMacros.synchronizeMainDebugMenuVisibility();
|
||||
ImGuiEditorWindows.synchronizeMainEditorMenuVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -161,8 +161,7 @@ public class ScriptEngine extends SignalServiceImpl {
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
LoggerInterface.loggerEngine.ERROR(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -267,4 +267,11 @@ public class PoseModel {
|
||||
return this.bones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete - currently does nothing
|
||||
*/
|
||||
public void delete(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user