this repo has no description
1
fork

Configure Feed

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

command managers

clover c3e33853 9dbd3b56

+122 -189
-53
src/main/java/common/BasicCommandManager.java
··· 1 - package common; 2 - 3 - import java.util.Stack; 4 - 5 - import util.EvictingStack; 6 - import util.Logger; 7 - 8 - public class BasicCommandManager 9 - { 10 - private EvictingStack<BasicEditorCommand> undoStack; 11 - private Stack<BasicEditorCommand> redoStack; 12 - 13 - public BasicCommandManager(int undoLimit) 14 - { 15 - undoStack = new EvictingStack<>(undoLimit); 16 - redoStack = new Stack<>(); 17 - } 18 - 19 - public void setUndoLimit(int undoLimit) 20 - { 21 - undoStack.setCapacity(undoLimit); 22 - } 23 - 24 - public void pushCommand(BasicEditorCommand cmd) 25 - { 26 - undoStack.push(cmd); 27 - redoStack.clear(); 28 - } 29 - 30 - public void undo() 31 - { 32 - if (undoStack.size() > 0) { 33 - BasicEditorCommand cmd = undoStack.pop(); 34 - cmd.undo(); 35 - redoStack.push(cmd); 36 - } 37 - else { 38 - Logger.log("Can't undo any more."); 39 - } 40 - } 41 - 42 - public void redo() 43 - { 44 - if (redoStack.size() > 0) { 45 - BasicEditorCommand cmd = redoStack.pop(); 46 - cmd.redo(); 47 - undoStack.push(cmd); 48 - } 49 - else { 50 - Logger.log("Can't redo anything."); 51 - } 52 - } 53 - }
-61
src/main/java/common/BasicEditorCommand.java
··· 1 - package common; 2 - 3 - import util.Logger; 4 - 5 - public abstract class BasicEditorCommand 6 - { 7 - public static enum STATE 8 - { 9 - READY, EXECUTED, UNDONE 10 - } 11 - 12 - private STATE state; 13 - private final String name; 14 - private boolean silent; 15 - 16 - public BasicEditorCommand(String name) 17 - { 18 - this(name, false); 19 - } 20 - 21 - public BasicEditorCommand(String name, boolean silent) 22 - { 23 - state = STATE.READY; 24 - this.name = name; 25 - this.silent = silent; 26 - } 27 - 28 - public void silence() 29 - { 30 - silent = true; 31 - } 32 - 33 - public boolean shouldExec() 34 - { 35 - return true; 36 - } 37 - 38 - public boolean triggersModify() 39 - { 40 - return true; 41 - } 42 - 43 - public void undo() 44 - { 45 - state = STATE.UNDONE; 46 - if (!silent) 47 - Logger.log("Undo: " + name); 48 - } 49 - 50 - public void redo() 51 - { 52 - state = STATE.EXECUTED; 53 - if (!silent) 54 - Logger.log("Redo: " + name); 55 - } 56 - 57 - public STATE getState() 58 - { 59 - return state; 60 - } 61 - }
+7 -5
src/main/java/common/commands/CommandManager.java
··· 5 5 import util.EvictingStack; 6 6 import util.Logger; 7 7 8 - public abstract class CommandManager 8 + public class CommandManager 9 9 { 10 10 private EvictingStack<AbstractCommand> undoStack; 11 11 private Stack<AbstractCommand> redoStack; 12 12 13 - public CommandManager(int undoLimit) 13 + private final Runnable modifyCallback; 14 + 15 + public CommandManager(int undoLimit, Runnable modifyCallback) 14 16 { 15 17 undoStack = new EvictingStack<>(undoLimit); 16 18 redoStack = new Stack<>(); 19 + 20 + this.modifyCallback = modifyCallback; 17 21 } 18 22 19 23 public void setUndoLimit(int undoLimit) ··· 31 35 redoStack.clear(); 32 36 33 37 if (cmd.modifiesData()) 34 - onModified(); 38 + modifyCallback.run(); 35 39 } 36 40 37 41 public void action_Undo() ··· 63 67 undoStack.clear(); 64 68 redoStack.clear(); 65 69 } 66 - 67 - public abstract void onModified(); 68 70 }
+62 -2
src/main/java/common/commands/ThreadSafeCommandManager.java
··· 5 5 import util.EvictingStack; 6 6 import util.Logger; 7 7 8 + /** 9 + * Manages undo and redo operations for editor commands in a thread-safe manner. 10 + * <p> 11 + * This class schedules command execution outside the critical section of an editor's main loop. 12 + * It ensures that any undoable editor state remains immutable during the main loop by using 13 + * a lock to synchronize access. 14 + */ 8 15 public class ThreadSafeCommandManager 9 16 { 10 17 private EvictingStack<AbstractCommand> undoStack; 11 18 private Stack<AbstractCommand> redoStack; 12 19 13 20 private final Object modifyLock; 21 + 14 22 private final Runnable modifyCallback; 15 23 24 + /** 25 + * Creates a new {@code ThreadSafeCommandManager} with a specified undo limit. 26 + * 27 + * @param undoLimit the maximum number of commands to keep in the undo stack 28 + * @param modifyLock the lock object to synchronize command execution 29 + * @param modifyCallback the callback to notify when a command modifies the editor state 30 + */ 16 31 public ThreadSafeCommandManager(int undoLimit, Object modifyLock, Runnable modifyCallback) 17 32 { 18 33 this.modifyLock = modifyLock; ··· 22 37 redoStack = new Stack<>(); 23 38 } 24 39 40 + /** 41 + * Sets the maximum number of commands that can be stored in the undo stack. 42 + * When the limit is exceeded, the oldest commands are discarded. 43 + * 44 + * @param undoLimit the new maximum size of the undo stack 45 + */ 25 46 public void setUndoLimit(int undoLimit) 26 47 { 27 48 undoStack.setCapacity(undoLimit); 28 49 } 29 50 51 + /** 52 + * Executes a command and adds it to the undo stack. 53 + * <p> 54 + * If the command modifies the editor state, the modify callback is triggered. 55 + * The redo stack is cleared upon execution. 56 + * 57 + * @param cmd the command to execute 58 + */ 30 59 public void executeCommand(AbstractCommand cmd) 31 60 { 32 61 if (!cmd.shouldExec()) ··· 43 72 } 44 73 } 45 74 46 - public void action_Undo() 75 + /** 76 + * Pushes a command onto the undo stack without executing it. 77 + * <p> 78 + * This is useful for commands that are undoable but do not require an initial execution. 79 + * The redo stack is cleared when a new command is pushed. 80 + * 81 + * @param cmd the command to push onto the undo stack 82 + */ 83 + public void pushCommand(AbstractCommand cmd) 84 + { 85 + synchronized (modifyLock) { 86 + undoStack.push(cmd); 87 + redoStack.clear(); 88 + } 89 + } 90 + 91 + /** 92 + * Undoes the last executed command. 93 + * <p> 94 + * The command will then be available to redo. 95 + */ 96 + public void undo() 47 97 { 48 98 if (undoStack.size() > 0) { 49 99 synchronized (modifyLock) { ··· 57 107 } 58 108 } 59 109 60 - public void action_Redo() 110 + /** 111 + * Redoes the last undone command. 112 + * <p> 113 + * The command will then be available to undo. 114 + */ 115 + public void redo() 61 116 { 62 117 if (redoStack.size() > 0) { 63 118 synchronized (modifyLock) { ··· 71 126 } 72 127 } 73 128 129 + /** 130 + * Clears both the undo and redo stacks. 131 + * <p> 132 + * After calling this method, no commands will be available to undo or redo. 133 + */ 74 134 public void flush() 75 135 { 76 136 undoStack.clear();
+9 -3
src/main/java/game/map/editor/MapEditor.java
··· 104 104 import game.map.editor.commands.JoinHitObjects.JoinColliders; 105 105 import game.map.editor.commands.JoinHitObjects.JoinZones; 106 106 import game.map.editor.commands.JoinModels; 107 - import game.map.editor.commands.MapCommandManager; 108 107 import game.map.editor.commands.PaintVertices; 109 108 import game.map.editor.commands.SeparateVertices; 110 109 import game.map.editor.commands.SplitHitObject.SplitCollider; ··· 447 446 * Major Components 448 447 */ 449 448 449 + private static final int UNDO_LIMIT = 32; 450 + 450 451 public KeyboardInput keyboard; 451 452 public MouseInput mouse; 452 453 public SpriteLoader spriteLoader; ··· 558 559 drawGeometryPreview = new PreviewGeometry(); 559 560 560 561 selectionManager = new SelectionManager(this); 561 - commandManager = new MapCommandManager(this, 32); 562 + commandManager = new CommandManager(UNDO_LIMIT, this::onModified); 562 563 drawTriManager = new DrawTrianglesManager(this, drawGeometryPreview); 563 564 564 565 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); ··· 1083 1084 selectionPaintRadius = 16.0f; 1084 1085 1085 1086 selectionManager = new SelectionManager(this); 1086 - commandManager = new MapCommandManager(this, 32); 1087 + commandManager = new CommandManager(UNDO_LIMIT, this::onModified); 1087 1088 1088 1089 if (changeMapState == ChangeMapState.NONE) { 1089 1090 showModels = true; ··· 1430 1431 profiler.record("the rest"); 1431 1432 profiler.print(); 1432 1433 } 1434 + } 1435 + 1436 + private void onModified() 1437 + { 1438 + map.modified = true; 1433 1439 } 1434 1440 1435 1441 public EditorMode getEditorMode()
-22
src/main/java/game/map/editor/commands/MapCommandManager.java
··· 1 - package game.map.editor.commands; 2 - 3 - import common.commands.CommandManager; 4 - import game.map.editor.MapEditor; 5 - 6 - public class MapCommandManager extends CommandManager 7 - { 8 - private final MapEditor editor; 9 - 10 - public MapCommandManager(MapEditor editor, int undoLimit) 11 - { 12 - super(undoLimit); 13 - 14 - this.editor = editor; 15 - } 16 - 17 - @Override 18 - public void onModified() 19 - { 20 - editor.map.modified = true; 21 - } 22 - }
+2 -2
src/main/java/game/sprite/editor/SpriteEditor.java
··· 325 325 { 326 326 assert (SwingUtilities.isEventDispatchThread()); 327 327 328 - commandManager.action_Undo(); 328 + commandManager.undo(); 329 329 } 330 330 331 331 @Override ··· 333 333 { 334 334 assert (SwingUtilities.isEventDispatchThread()); 335 335 336 - commandManager.action_Redo(); 336 + commandManager.redo(); 337 337 } 338 338 339 339 @Override
+22 -22
src/main/java/game/texture/editor/EditorImage.java
··· 10 10 import java.io.File; 11 11 import java.nio.ByteBuffer; 12 12 13 - import common.BasicEditorCommand; 13 + import common.commands.AbstractCommand; 14 14 import game.texture.ImageConverter; 15 15 import game.texture.Palette; 16 16 import game.texture.Tile; ··· 987 987 } 988 988 } 989 989 990 - public static class RestoreImage extends BasicEditorCommand 990 + public static class RestoreImage extends AbstractCommand 991 991 { 992 992 private final EditorImage image; 993 993 private final ImageBackup oldBackup; ··· 1002 1002 } 1003 1003 1004 1004 @Override 1005 - public void undo() 1005 + public void exec() 1006 1006 { 1007 - super.undo(); 1008 - oldBackup.apply(image); 1007 + super.exec(); 1008 + newBackup.apply(image); 1009 1009 } 1010 1010 1011 1011 @Override 1012 - public void redo() 1012 + public void undo() 1013 1013 { 1014 - super.redo(); 1015 - newBackup.apply(image); 1014 + super.undo(); 1015 + oldBackup.apply(image); 1016 1016 } 1017 1017 } 1018 1018 ··· 1044 1044 } 1045 1045 } 1046 1046 1047 - public static class RestoreSelection extends BasicEditorCommand 1047 + public static class RestoreSelection extends AbstractCommand 1048 1048 { 1049 1049 private final EditorImage image; 1050 1050 private final SelectionBackup oldBackup; ··· 1059 1059 } 1060 1060 1061 1061 @Override 1062 - public void undo() 1062 + public void exec() 1063 1063 { 1064 - super.undo(); 1065 - oldBackup.apply(image); 1064 + super.exec(); 1065 + newBackup.apply(image); 1066 1066 } 1067 1067 1068 1068 @Override 1069 - public void redo() 1069 + public void undo() 1070 1070 { 1071 - super.redo(); 1072 - newBackup.apply(image); 1071 + super.undo(); 1072 + oldBackup.apply(image); 1073 1073 } 1074 1074 } 1075 1075 1076 - public static class RestoreColor extends BasicEditorCommand 1076 + public static class RestoreColor extends AbstractCommand 1077 1077 { 1078 1078 private final EditorImage image; 1079 1079 private final int index; ··· 1090 1090 } 1091 1091 1092 1092 @Override 1093 - public void undo() 1093 + public void exec() 1094 1094 { 1095 - super.undo(); 1096 - oldBackup.apply(image); 1095 + super.exec(); 1096 + newBackup.apply(image); 1097 1097 image.editor.setSelectedIndex(index, false); 1098 1098 } 1099 1099 1100 1100 @Override 1101 - public void redo() 1101 + public void undo() 1102 1102 { 1103 - super.redo(); 1104 - newBackup.apply(image); 1103 + super.undo(); 1104 + oldBackup.apply(image); 1105 1105 image.editor.setSelectedIndex(index, false); 1106 1106 } 1107 1107 }
+18 -17
src/main/java/game/texture/editor/ImageEditor.java
··· 30 30 import common.BaseEditor; 31 31 import common.BaseEditorSettings; 32 32 import common.BasicCamera; 33 - import common.BasicCommandManager; 34 - import common.BasicEditorCommand; 35 33 import common.KeyboardInput.KeyInputEvent; 36 34 import common.MouseInput.MouseManagerListener; 37 35 import common.MousePixelRead; 36 + import common.commands.AbstractCommand; 37 + import common.commands.ThreadSafeCommandManager; 38 38 import game.map.editor.render.PresetColor; 39 39 import game.map.editor.render.TextureManager; 40 40 import game.map.editor.ui.SwatchPanel; ··· 90 90 91 91 private DrawableString greetingStr; 92 92 93 - private BasicCommandManager commandManager; 93 + private ThreadSafeCommandManager commandManager; 94 94 private final BasicCamera cam; 95 95 96 96 private OpenFileChooser importFileChooser; ··· 149 149 150 150 private void resetEditor() 151 151 { 152 - commandManager = new BasicCommandManager(32); 152 + commandManager = new ThreadSafeCommandManager(32, modifyLock, this::onModified); 153 153 154 154 mousePixelValid = false; 155 155 pickedPixel.clear(); 156 156 drawing = false; 157 157 adjustingColor = false; 158 - } 159 - 160 - public void push(BasicEditorCommand cmd) 161 - { 162 - commandManager.pushCommand(cmd); 163 - modified = true; 164 158 } 165 159 166 160 @Override ··· 654 648 } 655 649 } 656 650 651 + public void push(AbstractCommand cmd) 652 + { 653 + commandManager.pushCommand(cmd); 654 + modified = true; 655 + } 656 + 657 657 @Override 658 658 protected void undoEDT() 659 659 { 660 - invokeLater(() -> { 661 - commandManager.undo(); 662 - }); 660 + commandManager.undo(); 663 661 } 664 662 665 663 @Override 666 664 protected void redoEDT() 667 665 { 668 - invokeLater(() -> { 669 - commandManager.redo(); 670 - }); 666 + commandManager.redo(); 671 667 } 672 668 673 669 private void resetCam() ··· 822 818 RenderState.setDepthWrite(false); 823 819 LineRenderQueue.render(true); 824 820 RenderState.setDepthWrite(true); 821 + } 822 + 823 + public void onModified() 824 + { 825 + // nothing to do 825 826 } 826 827 827 828 @Override ··· 1207 1208 else 1208 1209 image.draw(mousePixelX, mousePixelY, pickedPixel); 1209 1210 } 1210 - 1211 + 1211 1212 if(mouseManager.holdingRMB && mousePixelValid) 1212 1213 image.deselect(mousePixelX, mousePixelY); 1213 1214 */
+2 -2
src/main/java/game/worldmap/WorldMapEditor.java
··· 470 470 { 471 471 assert (SwingUtilities.isEventDispatchThread()); 472 472 473 - commandManager.action_Undo(); 473 + commandManager.undo(); 474 474 } 475 475 476 476 @Override ··· 478 478 { 479 479 assert (SwingUtilities.isEventDispatchThread()); 480 480 481 - commandManager.action_Redo(); 481 + commandManager.redo(); 482 482 } 483 483 484 484 private void resetCam()