editor mode asset file drag'n'drop

This commit is contained in:
austin 2025-03-26 22:34:24 -04:00
parent ed9dac0b80
commit 62ad638255
15 changed files with 603 additions and 39 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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);
}
}

View 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());
}));
}
}
}

View 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);
}
}

View 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();
}
}
}

View File

@ -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
//

View File

@ -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();
}
}

View File

@ -161,8 +161,7 @@ public class ScriptEngine extends SignalServiceImpl {
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
LoggerInterface.loggerEngine.ERROR(e);
}
}

View File

@ -267,4 +267,11 @@ public class PoseModel {
return this.bones;
}
/**
* Delete - currently does nothing
*/
public void delete(){
}
}