mirror of
https://github.com/AndorsTrailRelease/ATCS.git
synced 2025-10-27 18:44:03 +01:00
238 lines
6.1 KiB
Java
238 lines
6.1 KiB
Java
package com.gpl.rpg.atcontentstudio.model;
|
|
|
|
import com.gpl.rpg.atcontentstudio.model.bookmarks.BookmarkEntry;
|
|
|
|
import javax.swing.tree.TreeNode;
|
|
import java.awt.*;
|
|
import java.io.Serializable;
|
|
import java.util.List;
|
|
import java.util.*;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
public abstract class GameDataElement implements ProjectTreeNode, Serializable {
|
|
|
|
private static final long serialVersionUID = 2028934451226743389L;
|
|
|
|
public static enum State {
|
|
init, // We know the object exists, and have its key/ID.
|
|
parsed, // We know the object's properties, but related objects are referenced by ID only.
|
|
linked, // We know the object fully, and all links to related objects point to objects in the parsed state at least.
|
|
created, // This is an object we are creating
|
|
modified, // Whether altered or created, this item has been modified since creation from scratch or from JSON.
|
|
saved // Whether altered or created, this item has been saved since last modification.
|
|
}
|
|
|
|
public State state = State.init;
|
|
|
|
//Available from state init.
|
|
public ProjectTreeNode parent;
|
|
|
|
public boolean writable = false;
|
|
|
|
public BookmarkEntry bookmark = null;
|
|
|
|
//List of objects whose transition to "linked" state made them point to this instance.
|
|
private Map<GameDataElement, Integer> backlinks = new ConcurrentHashMap<GameDataElement, Integer>();
|
|
|
|
public String id = null;
|
|
|
|
@Override
|
|
public Enumeration<ProjectTreeNode> children() {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public boolean getAllowsChildren() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public TreeNode getChildAt(int arg0) {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public int getChildCount() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public int getIndex(TreeNode arg0) {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public TreeNode getParent() {
|
|
return parent;
|
|
}
|
|
|
|
@Override
|
|
public boolean isLeaf() {
|
|
return true;
|
|
}
|
|
|
|
@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) {
|
|
path.add(0, this);
|
|
parent.childrenRemoved(path);
|
|
}
|
|
|
|
@Override
|
|
public void notifyCreated() {
|
|
childrenAdded(new ArrayList<ProjectTreeNode>());
|
|
}
|
|
|
|
@Override
|
|
public abstract String getDesc();
|
|
|
|
public static String getStaticDesc() {
|
|
return "GameDataElements";
|
|
}
|
|
|
|
public abstract void parse();
|
|
|
|
public abstract void link();
|
|
|
|
|
|
@Override
|
|
public Project getProject() {
|
|
return parent == null ? null : parent.getProject();
|
|
}
|
|
|
|
|
|
public Image getIcon() {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public Image getClosedIcon() {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public Image getOpenIcon() {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public Image getLeafIcon() {
|
|
return getIcon();
|
|
}
|
|
|
|
|
|
public abstract GameDataElement clone();
|
|
|
|
public abstract void elementChanged(GameDataElement oldOne, GameDataElement newOne);
|
|
|
|
|
|
@Override
|
|
public GameSource.Type getDataType() {
|
|
if (parent == null) {
|
|
System.out.println("blerf.");
|
|
}
|
|
return parent.getDataType();
|
|
}
|
|
|
|
|
|
public List<BacklinksListener> backlinkListeners = new ArrayList<GameDataElement.BacklinksListener>();
|
|
|
|
public void addBacklinkListener(BacklinksListener l) {
|
|
backlinkListeners.add(l);
|
|
}
|
|
|
|
public void removeBacklinkListener(BacklinksListener l) {
|
|
backlinkListeners.remove(l);
|
|
}
|
|
|
|
public void addBacklink(GameDataElement gde) {
|
|
if (!backlinks.containsKey(gde)) {
|
|
backlinks.put(gde, 1);
|
|
for (BacklinksListener l : backlinkListeners) {
|
|
l.backlinkAdded(gde);
|
|
}
|
|
} else {
|
|
backlinks.put(gde, backlinks.get(gde) + 1);
|
|
}
|
|
}
|
|
|
|
public void removeBacklink(GameDataElement gde) {
|
|
if (backlinks.get(gde) == null) return;
|
|
backlinks.put(gde, backlinks.get(gde) - 1);
|
|
if (backlinks.get(gde) == 0) {
|
|
backlinks.remove(gde);
|
|
for (BacklinksListener l : backlinkListeners) {
|
|
l.backlinkRemoved(gde);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Set<GameDataElement> getBacklinks() {
|
|
return backlinks.keySet();
|
|
}
|
|
|
|
public static interface BacklinksListener {
|
|
public void backlinkAdded(GameDataElement gde);
|
|
|
|
public void backlinkRemoved(GameDataElement gde);
|
|
}
|
|
|
|
@Override
|
|
public boolean isEmpty() {
|
|
return false;
|
|
}
|
|
|
|
public boolean needsSaving() {
|
|
return this.state == State.modified || this.state == State.created;
|
|
}
|
|
|
|
public abstract String getProjectFilename();
|
|
|
|
public abstract void save();
|
|
|
|
public abstract List<SaveEvent> attemptSave();
|
|
|
|
/**
|
|
* Checks if the current state indicates that parsing/linking should be skipped.
|
|
*
|
|
* @return true if the operation should be skipped, false otherwise
|
|
*/
|
|
protected boolean shouldSkipParseOrLink() {
|
|
if (shouldSkipParse()) return true;
|
|
if (this.state == State.linked) {
|
|
//Already linked.
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected boolean shouldSkipParse() {
|
|
if (this.state == State.created || this.state == State.modified || this.state == State.saved) {
|
|
//This type of state is unrelated to parsing/linking.
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Ensures the element is parsed if needed based on its current state.
|
|
*/
|
|
protected void ensureParseIfNeeded() {
|
|
if (this.state == State.init) {
|
|
//Not parsed yet.
|
|
this.parse();
|
|
}
|
|
}
|
|
}
|