mirror of
https://github.com/AndorsTrailRelease/ATCS.git
synced 2025-10-27 18:44:03 +01:00
On some systems changes by tiled were not detected and therefore the refresh button was greyed. The reason might have been that tiled recreates the files instead of changing them.
275 lines
8.1 KiB
Java
275 lines
8.1 KiB
Java
package com.gpl.rpg.atcontentstudio.model.maps;
|
|
|
|
import java.awt.Image;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.nio.file.FileSystems;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.nio.file.StandardWatchEventKinds;
|
|
import java.nio.file.WatchEvent;
|
|
import java.nio.file.WatchKey;
|
|
import java.nio.file.WatchService;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.Enumeration;
|
|
import java.util.List;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import javax.swing.tree.TreeNode;
|
|
|
|
import com.gpl.rpg.atcontentstudio.Notification;
|
|
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
|
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
|
|
import com.gpl.rpg.atcontentstudio.model.Project;
|
|
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
|
|
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
|
|
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
|
|
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
|
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
|
|
|
|
public class TMXMapSet implements ProjectTreeNode {
|
|
|
|
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res"+File.separator+"xml"+File.separator;
|
|
public static final String DEFAULT_REL_PATH_IN_PROJECT = "maps"+File.separator;
|
|
public static final String DEFAULT_REL_PATH_TO_DRAWABLE = ".."+File.separator+"drawable"+File.separator;
|
|
|
|
public static final String GAME_MAPS_ARRAY_NAME = "loadresource_maps";
|
|
public static final String DEBUG_SUFFIX = "_debug";
|
|
public static final String RESOURCE_PREFIX = "@xml/";
|
|
public static final String FILENAME_SUFFIX = ".tmx";
|
|
|
|
public File mapFolder = null;
|
|
public List<TMXMap> tmxMaps;
|
|
|
|
public ProjectTreeNode parent;
|
|
|
|
public TMXMapSet(GameSource source) {
|
|
this.parent = source;
|
|
if (source.type == GameSource.Type.source) {
|
|
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE);
|
|
}
|
|
else if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
|
|
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
|
|
if (!this.mapFolder.exists()) {
|
|
this.mapFolder.mkdirs();
|
|
}
|
|
FileUtils.makeSymlink(getProject().baseContent.gameSprites.drawableFolder, new File(mapFolder.getAbsolutePath()+File.separator+DEFAULT_REL_PATH_TO_DRAWABLE));
|
|
}
|
|
this.tmxMaps = new ArrayList<TMXMap>();
|
|
|
|
if (source.type == GameSource.Type.source && (source.parent.sourceSetToUse == ResourceSet.debugData || source.parent.sourceSetToUse == ResourceSet.gameData)) {
|
|
String suffix = (source.parent.sourceSetToUse == ResourceSet.debugData) ? DEBUG_SUFFIX : "";
|
|
|
|
if (source.referencedSourceFiles.get(GAME_MAPS_ARRAY_NAME+suffix) != null) {
|
|
for (String resource : source.referencedSourceFiles.get(GAME_MAPS_ARRAY_NAME+suffix)) {
|
|
File f = new File(mapFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
|
|
if (f.exists()) {
|
|
TMXMap map = new TMXMap(this, f);
|
|
tmxMaps.add(map);
|
|
} else {
|
|
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
|
|
}
|
|
}
|
|
}
|
|
|
|
} else if (this.mapFolder != null) {
|
|
for (File f : this.mapFolder.listFiles()) {
|
|
if (f.getName().endsWith(".tmx") || f.getName().endsWith(".TMX")) {
|
|
TMXMap map = new TMXMap(this, f);
|
|
if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
|
|
map.writable = true;
|
|
}
|
|
tmxMaps.add(map);
|
|
}
|
|
}
|
|
}
|
|
Collections.sort(tmxMaps, new Comparator<TMXMap>() {
|
|
@Override
|
|
public int compare(TMXMap o1, TMXMap o2) {
|
|
return o1.id.compareTo(o2.id);
|
|
}
|
|
});
|
|
if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
|
|
final Path folderPath = Paths.get(mapFolder.getAbsolutePath());
|
|
Thread watcher = new Thread("Map folder watcher for "+getProject().name+"/"+source.type) {
|
|
public void run() {
|
|
WatchService watchService;
|
|
|
|
while(getProject().open) {
|
|
try {
|
|
watchService = FileSystems.getDefault().newWatchService();
|
|
/*WatchKey watchKey = */folderPath.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);
|
|
WatchKey wk;
|
|
validService: while(getProject().open) {
|
|
wk = watchService.poll(10, TimeUnit.SECONDS);
|
|
if (wk != null) {
|
|
for (WatchEvent<?> event : wk.pollEvents()) {
|
|
Path changed = (Path) event.context();
|
|
String name = changed.getFileName().toString();
|
|
String id = name.substring(0, name.length() - 4);
|
|
TMXMap map = getMap(id);
|
|
if (map != null) {
|
|
map.mapChangedOnDisk();
|
|
}
|
|
}
|
|
if(!wk.reset()) {
|
|
watchService.close();
|
|
break validService;
|
|
}
|
|
}
|
|
}
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
};
|
|
};
|
|
watcher.start();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Enumeration<TMXMap> children() {
|
|
return Collections.enumeration(tmxMaps);
|
|
}
|
|
@Override
|
|
public boolean getAllowsChildren() {
|
|
return true;
|
|
}
|
|
@Override
|
|
public TreeNode getChildAt(int arg0) {
|
|
return tmxMaps.get(arg0);
|
|
}
|
|
@Override
|
|
public int getChildCount() {
|
|
return tmxMaps.size();
|
|
}
|
|
@Override
|
|
public int getIndex(TreeNode arg0) {
|
|
return tmxMaps.indexOf(arg0);
|
|
}
|
|
@Override
|
|
public TreeNode getParent() {
|
|
return parent;
|
|
}
|
|
@Override
|
|
public boolean isLeaf() {
|
|
return false;
|
|
}
|
|
@Override
|
|
public void childrenAdded(List<ProjectTreeNode> path) {
|
|
path.add(0, this);
|
|
parent.childrenAdded(path);
|
|
}
|
|
@Override
|
|
public void childrenChanged(List<ProjectTreeNode> path) {
|
|
path.add(0, this);
|
|
parent.childrenChanged(path);
|
|
}
|
|
@Override
|
|
public void childrenRemoved(List<ProjectTreeNode> path) {
|
|
if (path.size() == 1 && this.getChildCount() == 1) {
|
|
childrenRemoved(new ArrayList<ProjectTreeNode>());
|
|
} else {
|
|
path.add(0, this);
|
|
parent.childrenRemoved(path);
|
|
}
|
|
}
|
|
@Override
|
|
public void notifyCreated() {
|
|
childrenAdded(new ArrayList<ProjectTreeNode>());
|
|
for (TMXMap map : tmxMaps) {
|
|
map.notifyCreated();
|
|
}
|
|
}
|
|
@Override
|
|
public String getDesc() {
|
|
return (needsSaving() ? "*" : "")+"TMX Maps";
|
|
}
|
|
|
|
@Override
|
|
public Project getProject() {
|
|
return parent.getProject();
|
|
}
|
|
|
|
|
|
@Override
|
|
public Image getIcon() {
|
|
return getOpenIcon();
|
|
}
|
|
@Override
|
|
public Image getClosedIcon() {
|
|
return DefaultIcons.getTmxClosedIcon();
|
|
}
|
|
@Override
|
|
public Image getLeafIcon() {
|
|
return DefaultIcons.getTmxClosedIcon();
|
|
}
|
|
@Override
|
|
public Image getOpenIcon() {
|
|
return DefaultIcons.getTmxOpenIcon();
|
|
}
|
|
|
|
@Override
|
|
public GameDataSet getDataSet() {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public Type getDataType() {
|
|
return parent.getDataType();
|
|
}
|
|
|
|
@Override
|
|
public boolean isEmpty() {
|
|
return tmxMaps.isEmpty();
|
|
}
|
|
|
|
public TMXMap getMap(String id) {
|
|
if (tmxMaps == null) return null;
|
|
for (TMXMap map : tmxMaps) {
|
|
if (id.equals(map.id)){
|
|
return map;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void addMap(TMXMap node) {
|
|
ProjectTreeNode higherEmptyParent = this;
|
|
while (higherEmptyParent != null) {
|
|
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode)higherEmptyParent.getParent()).isEmpty()) higherEmptyParent = (ProjectTreeNode)higherEmptyParent.getParent();
|
|
else break;
|
|
}
|
|
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
|
|
tmxMaps.add(node);
|
|
if (node.tmxFile != null) {
|
|
//Altered node.
|
|
node.tmxFile = new File(this.mapFolder, node.tmxFile.getName());
|
|
} else {
|
|
//Created node.
|
|
node.tmxFile = new File(this.mapFolder, node.id+".tmx");
|
|
}
|
|
node.parent = this;
|
|
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
|
|
else node.notifyCreated();
|
|
}
|
|
|
|
public TMXMap get(int index) {
|
|
return tmxMaps.get(index);
|
|
}
|
|
|
|
@Override
|
|
public boolean needsSaving() {
|
|
for (ProjectTreeNode node : tmxMaps) {
|
|
if (node.needsSaving()) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|