this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

automatic renaming applied on saving map

clover d8c5f91a 5d7a576c

+193 -1
+2
build.gradle.kts
··· 72 72 73 73 implementation(files("lib/org.eclipse.cdt.core-5.11.0.jar")) 74 74 implementation(files("lib/org.eclipse.equinox.common-3.6.0.jar")) 75 + 76 + implementation("org.ahocorasick:ahocorasick:0.6.3") 75 77 } 76 78 77 79 tasks {
+1
src/main/java/app/config/Options.java
··· 44 44 "Set how sensitive scroll panels are to mouse wheel scrolling", 1.0, 1024.0, 1.0), 45 45 NormalsLength (true, Scope.MapEditor, Type.Float, "NormalsLength", "16.0", "Normals Draw Length", 46 46 "The length of normal visualizations draw in the editor.", 1.0, 1024.0, 1.0), 47 + RenameOnSave (true, Scope.MapEditor, Type.String, "RenameOnSave", "prompt"), 47 48 RecentMap0 (true, Scope.MapEditor, Type.String, "RecentMap0", ""), 48 49 RecentMap1 (true, Scope.MapEditor, Type.String, "RecentMap1", ""), 49 50 RecentMap2 (true, Scope.MapEditor, Type.String, "RecentMap2", ""),
+1 -1
src/main/java/app/input/IOUtils.java
··· 46 46 return getFilesWithExtension(dir, new String[] { ext }, recursive); 47 47 } 48 48 49 - private static Collection<File> getFilesWithExtension(File dir, String[] ext, boolean recursive) throws IOException 49 + public static Collection<File> getFilesWithExtension(File dir, String[] ext, boolean recursive) throws IOException 50 50 { 51 51 if (!dir.exists()) 52 52 throw new IOException("Directory " + dir + " does not exist!");
+131
src/main/java/game/map/MapSourceRenamer.java
··· 1 + package game.map; 2 + 3 + import java.io.File; 4 + import java.io.IOException; 5 + import java.nio.file.Files; 6 + import java.util.Collection; 7 + import java.util.HashMap; 8 + 9 + import javax.swing.JOptionPane; 10 + 11 + import org.ahocorasick.trie.Token; 12 + import org.ahocorasick.trie.Trie; 13 + import org.ahocorasick.trie.Trie.TrieBuilder; 14 + 15 + import app.SwingUtils; 16 + import app.config.Options; 17 + import app.input.IOUtils; 18 + import game.map.editor.MapEditor; 19 + import game.map.tree.MapObjectTreeModel; 20 + import util.Logger; 21 + 22 + public class MapSourceRenamer 23 + { 24 + private int renamedCount = 0; 25 + 26 + public MapSourceRenamer(Map map) 27 + { 28 + process(map); 29 + 30 + resetNames(map.modelTree); 31 + resetNames(map.colliderTree); 32 + resetNames(map.zoneTree); 33 + } 34 + 35 + private void resetNames(MapObjectTreeModel<?> tree) 36 + { 37 + tree.depthFirstTraversal((mobj) -> { 38 + mobj.captureOriginalName(); 39 + }); 40 + } 41 + 42 + private void addToRenameMap(HashMap<String, String> renames, MapObjectTreeModel<?> tree, String prefix) 43 + { 44 + tree.depthFirstTraversal((mobj) -> { 45 + if (!mobj.getNode().isRoot() && mobj.hasBeenRenamed()) 46 + renamedCount++; 47 + 48 + String oldName = mobj.getOriginalName(); 49 + String newName = mobj.getName(); 50 + if (oldName == null) 51 + oldName = newName; // should not occur 52 + 53 + renames.put(prefix + "_" + oldName, prefix + "_" + newName); 54 + }); 55 + } 56 + 57 + private void process(Map map) 58 + { 59 + String policy = MapEditor.instance().editorConfig.getString(Options.RenameOnSave); 60 + if (policy.equalsIgnoreCase("never")) 61 + return; 62 + 63 + HashMap<String, String> renames = new HashMap<>(); 64 + renamedCount = 0; 65 + 66 + addToRenameMap(renames, map.modelTree, "MODEL"); 67 + addToRenameMap(renames, map.colliderTree, "COLLIDER"); 68 + addToRenameMap(renames, map.zoneTree, "ZONE"); 69 + 70 + if (renamedCount == 0 || !map.getProjDir().exists()) 71 + return; 72 + 73 + String countMsg; 74 + if (renamedCount == 1) 75 + countMsg = "1 object has been renamed."; 76 + else 77 + countMsg = renamedCount + " objects have been renamed."; 78 + 79 + if (!policy.equalsIgnoreCase("always")) { 80 + // ask permission first 81 + int choice = SwingUtils.getConfirmDialog() 82 + .setTitle("Confirm Renames") 83 + .setMessage(countMsg, "Should Star Rod update source files?") 84 + .choose(); 85 + 86 + if (choice != JOptionPane.OK_OPTION) 87 + return; 88 + } 89 + 90 + TrieBuilder builder = Trie.builder().ignoreOverlaps(); 91 + for (String key : renames.keySet()) 92 + builder.addKeyword(key); 93 + Trie trie = builder.build(); 94 + 95 + Iterable<File> files; 96 + try { 97 + files = IOUtils.getFilesWithExtension(map.getProjDir(), new String[] { "h", "c" }, true); 98 + } 99 + catch (IOException e) { 100 + Logger.printStackTrace(e); 101 + Logger.logError("Could not find source files for " + map.getName() + ": " + e.getMessage()); 102 + return; 103 + } 104 + 105 + for (File srcFile : files) { 106 + try { 107 + Logger.log("Replacing names in " + srcFile.getName()); 108 + String fileText = Files.readString(srcFile.toPath()); 109 + 110 + Collection<Token> tokens = trie.tokenize(fileText); 111 + StringBuilder sb = new StringBuilder(); 112 + 113 + for (Token token : tokens) { 114 + String s = token.getFragment(); 115 + if (token.isMatch()) { 116 + sb.append(renames.get(s)); 117 + } 118 + else { 119 + sb.append(s); 120 + } 121 + } 122 + 123 + Files.writeString(srcFile.toPath(), sb.toString()); 124 + } 125 + catch (IOException e) { 126 + Logger.printStackTrace(e); 127 + Logger.logError("Rename failed for " + srcFile.getName() + ": " + e.getMessage()); 128 + } 129 + } 130 + } 131 + }
+5
src/main/java/game/map/editor/MapEditor.java
··· 61 61 import game.map.MapObject.HitType; 62 62 import game.map.MapObject.MapObjectType; 63 63 import game.map.MapObject.ShapeType; 64 + import game.map.MapSourceRenamer; 64 65 import game.map.compiler.BuildException; 65 66 import game.map.compiler.CollisionCompiler; 66 67 import game.map.compiler.GeometryCompiler; ··· 3827 3828 { 3828 3829 try { 3829 3830 map.saveMap(new MapEditorMetadata(this)); 3831 + if (!map.isStage) 3832 + new MapSourceRenamer(map); 3830 3833 } 3831 3834 catch (Exception e) { 3832 3835 displayStackTrace(e); ··· 3841 3844 { 3842 3845 try { 3843 3846 map.saveMapAs(f, new MapEditorMetadata(this)); 3847 + if (!map.isStage) 3848 + new MapSourceRenamer(map); 3844 3849 } 3845 3850 catch (Exception e) { 3846 3851 displayStackTrace(e);
+53
src/main/java/game/map/tree/MapObjectTreeModel.java
··· 176 176 } 177 177 } 178 178 179 + public static interface MapObjectVisitor<T> 180 + { 181 + public void visit(T obj); 182 + } 183 + 184 + public void depthFirstTraversal(MapObjectVisitor<T> visitor) 185 + { 186 + Stack<MapObjectNode<T>> stack = new Stack<>(); 187 + stack.push(getRoot()); 188 + 189 + while (!stack.isEmpty()) { 190 + MapObjectNode<T> node = stack.pop(); 191 + for (int i = 0; i < node.getChildCount(); i++) 192 + stack.push(node.getChildAt(i)); 193 + 194 + visitor.visit(node.getUserObject()); 195 + } 196 + } 197 + 198 + public void breadthFirstTraversal(MapObjectVisitor<T> visitor) 199 + { 200 + Queue<MapObjectNode<T>> queue = new LinkedList<>(); 201 + queue.add(getRoot()); 202 + 203 + while (!queue.isEmpty()) { 204 + MapObjectNode<T> node = queue.poll(); 205 + for (int i = 0; i < node.getChildCount(); i++) 206 + queue.add(node.getChildAt(i)); 207 + 208 + visitor.visit(node.getUserObject()); 209 + } 210 + } 211 + 212 + private void nextIndexTraversal(MapObjectVisitor<T> visitor, MapObjectNode<T> cur) 213 + { 214 + for (int i = 0; i < cur.getChildCount(); i++) { 215 + MapObjectNode<T> child = cur.getChildAt(i); 216 + nextIndexTraversal(visitor, child); 217 + } 218 + 219 + visitor.visit(cur.getUserObject()); 220 + } 221 + 222 + /** 223 + * Visit the nodes of this tree in the order of the original game's node indices:<BR> 224 + * post-order depth-first (i.e., children first, parent afterward; root last) 225 + * @param visitor 226 + */ 227 + public void indexTraversal(MapObjectVisitor<T> visitor) 228 + { 229 + nextIndexTraversal(visitor, getRoot()); 230 + } 231 + 179 232 public T getObject(String name) 180 233 { 181 234 Stack<MapObjectNode<T>> nodes = new Stack<>();