Fix editor idle memory leak
This commit is contained in:
Binary file not shown.
+1
-1
@@ -140,7 +140,7 @@ dependencies {
|
||||
implementation "com.github.lyze237:gdx-TinyVG:$gdxTinyVGVersion"
|
||||
implementation "com.mortennobel:java-image-scaling:0.8.6"
|
||||
implementation "org.apache.commons:commons-lang3:3.12.0"
|
||||
implementation "commons-io:commons-io:2.7"
|
||||
implementation "commons-io:commons-io:2.16.1"
|
||||
implementation 'net.mountainblade:modular:1.0'
|
||||
|
||||
testImplementation group: 'junit', name: 'junit', version: '4.12'
|
||||
|
||||
+1
-1
Submodule hyperlap2d-common-api updated: 1c02946af9...00ec574979
Submodule hyperlap2d-runtime-libgdx updated: e0312067e9...85bcd25fc4
@@ -5,8 +5,10 @@ plugins {
|
||||
group 'games.rednblack'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -21,7 +23,7 @@ dependencies {
|
||||
implementation project(":hyperlap2d-common-api")
|
||||
implementation project(":hyperlap2d-runtime-libgdx")
|
||||
|
||||
implementation "org.apache.commons:commons-io:1.3.2"
|
||||
implementation "commons-io:commons-io:2.16.1"
|
||||
|
||||
testImplementation group: 'junit', name: 'junit', version: '4.12'
|
||||
}
|
||||
|
||||
@@ -44,14 +44,9 @@ import games.rednblack.h2d.common.ProgressHandler;
|
||||
import games.rednblack.h2d.common.vo.ProjectVO;
|
||||
import games.rednblack.h2d.common.vo.SceneConfigVO;
|
||||
import games.rednblack.h2d.common.vo.TexturePackerVO;
|
||||
import games.rednblack.puremvc.Facade;
|
||||
import games.rednblack.puremvc.Proxy;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.monitor.FileAlterationListener;
|
||||
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
|
||||
import org.apache.commons.io.monitor.FileAlterationMonitor;
|
||||
import org.apache.commons.io.monitor.FileAlterationObserver;
|
||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -59,10 +54,14 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ProjectManager extends Proxy {
|
||||
private static final String TAG = ProjectManager.class.getCanonicalName();
|
||||
@@ -93,7 +92,7 @@ public class ProjectManager extends Proxy {
|
||||
private ProjectExportSettings projectExportSettings;
|
||||
private LivePreviewSettings livePreviewSettings;
|
||||
|
||||
private FileAlterationMonitor fileWatcherMonitor;
|
||||
private Thread fileWatcherThread;
|
||||
|
||||
@Override
|
||||
public void onRegister() {
|
||||
@@ -241,43 +240,84 @@ public class ProjectManager extends Proxy {
|
||||
}
|
||||
}
|
||||
|
||||
private void addFileWatcher(String projectPath) throws Exception {
|
||||
private void addFileWatcher(String projectPath) {
|
||||
stopFileWatcher();
|
||||
|
||||
fileWatcherMonitor = new FileAlterationMonitor(2000);
|
||||
if (fileWatcherThread != null) return;
|
||||
|
||||
FileAlterationObserver observer = new FileAlterationObserver(projectPath);
|
||||
FileAlterationListener listener = new FileAlterationListenerAdaptor() {
|
||||
Path directory = Paths.get(projectPath);
|
||||
|
||||
fileWatcherThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void onFileCreate(File file) {
|
||||
Gdx.app.postRunnable(() -> facade.sendNotification(MsgAPI.PROJECT_FILE_CREATED, file));
|
||||
}
|
||||
public void run() {
|
||||
try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
|
||||
registerAll(directory, watchService);
|
||||
|
||||
@Override
|
||||
public void onFileDelete(File file) {
|
||||
Gdx.app.postRunnable(() -> facade.sendNotification(MsgAPI.PROJECT_FILE_DELETED, file));
|
||||
}
|
||||
while (true) {
|
||||
WatchKey key;
|
||||
try {
|
||||
// Poll for file system events
|
||||
key = watchService.poll(2, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileChange(File file) {
|
||||
Gdx.app.postRunnable(() -> facade.sendNotification(MsgAPI.PROJECT_FILE_MODIFIED, file));
|
||||
}
|
||||
};
|
||||
observer.addListener(listener);
|
||||
if (key == null) {
|
||||
// No events within the timeout period
|
||||
continue;
|
||||
}
|
||||
|
||||
fileWatcherMonitor.addObserver(observer);
|
||||
fileWatcherMonitor.start();
|
||||
List<WatchEvent<?>> events = key.pollEvents();
|
||||
|
||||
for (int i = 0; i < events.size(); i++) {
|
||||
WatchEvent<?> event = events.get(i);
|
||||
WatchEvent.Kind<?> kind = event.kind();
|
||||
Path fileName = (Path) event.context();
|
||||
Path filePath = ((Path) key.watchable()).resolve(fileName);
|
||||
File file = filePath.toFile();
|
||||
|
||||
if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
|
||||
Gdx.app.postRunnable(() -> facade.sendNotification(MsgAPI.PROJECT_FILE_CREATED, file));
|
||||
} else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
|
||||
Gdx.app.postRunnable(() -> facade.sendNotification(MsgAPI.PROJECT_FILE_DELETED, file));
|
||||
} else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
|
||||
Gdx.app.postRunnable(() -> facade.sendNotification(MsgAPI.PROJECT_FILE_MODIFIED, file));
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the key
|
||||
boolean valid = key.reset();
|
||||
if (!valid) {
|
||||
break; // Exit the loop if the key is no longer valid
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, "FileWatcherThread");
|
||||
|
||||
fileWatcherThread.setDaemon(true);
|
||||
fileWatcherThread.start();
|
||||
}
|
||||
|
||||
public void stopFileWatcher() {
|
||||
if (fileWatcherMonitor != null) {
|
||||
try {
|
||||
fileWatcherMonitor.stop();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (fileWatcherThread == null) return;
|
||||
fileWatcherThread.interrupt();
|
||||
fileWatcherThread = null;
|
||||
}
|
||||
|
||||
private void registerAll(final Path start, final WatchService watchService) throws Exception {
|
||||
// Register the directory and its subdirectories recursively
|
||||
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||
dir.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
|
||||
StandardWatchEventKinds.ENTRY_DELETE,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
fileWatcherMonitor = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void goThroughVersionMigrationProtocol(String projectPath, ProjectVO projectVo) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import com.kotcrab.vis.ui.widget.VisLabel;
|
||||
import games.rednblack.editor.utils.Guide;
|
||||
@@ -73,7 +74,7 @@ public class RulersUI extends Actor {
|
||||
private final Circle tmpCircle = new Circle();
|
||||
private final Color tmpColor = new Color();
|
||||
|
||||
private final HashMap<Integer, String> labelTextCache = new HashMap<>();
|
||||
private final IntMap<String> labelTextCache = new IntMap<>();
|
||||
|
||||
public RulersUI() {
|
||||
horizontalRect = new Rectangle();
|
||||
@@ -324,7 +325,8 @@ public class RulersUI extends Actor {
|
||||
VisLabel label = Pools.obtain(VisLabel.class);
|
||||
label.setColor(TEXT_COLOR);
|
||||
int textNumber = (int) Math.abs(worldStartPointCpy.y + iterator * gridMeasuringSize);
|
||||
labelTextCache.putIfAbsent(textNumber, "");
|
||||
if (labelTextCache.get(textNumber) == null)
|
||||
labelTextCache.put(textNumber, "");
|
||||
String lblText = labelTextCache.get(textNumber);
|
||||
if (lblText.equals("")) {
|
||||
lblText = verticalize(textNumber + "");
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CodeEditorDialogMediator extends Mediator<CodeEditorDialog> {
|
||||
@Override
|
||||
public void listNotificationInterests(Interests interests) {
|
||||
interests.add(MsgAPI.OPEN_CODE_EDITOR,
|
||||
MsgAPI.PROJECT_FILE_MODIFIED);
|
||||
MsgAPI.PROJECT_FILE_MODIFIED, MsgAPI.PROJECT_FILE_CREATED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,6 +47,7 @@ public class CodeEditorDialogMediator extends Mediator<CodeEditorDialog> {
|
||||
readObservedFile();
|
||||
}
|
||||
break;
|
||||
case MsgAPI.PROJECT_FILE_CREATED:
|
||||
case MsgAPI.PROJECT_FILE_MODIFIED:
|
||||
if (!viewComponent.hasParent())
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user