mirror of
https://github.com/OMGeeky/ATCS.git
synced 2025-12-26 15:57:22 +01:00
272 lines
8.0 KiB
Java
272 lines
8.0 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 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 "+source.type) {
|
|
public void run() {
|
|
WatchService watchService;
|
|
|
|
while(getProject().open) {
|
|
try {
|
|
watchService = FileSystems.getDefault().newWatchService();
|
|
WatchKey watchKey = folderPath.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
|
|
WatchKey wk;
|
|
validService: while(getProject().open) {
|
|
wk = watchService.take();
|
|
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;
|
|
}
|
|
|
|
}
|