Last active
          February 5, 2017 19:08 
        
      - 
      
- 
        Save ondrej-kvasnovsky/ef3106c331edfff7dd4d9066bc6f1e4f to your computer and use it in GitHub Desktop. 
    History Manager (undo / redo)
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | package com.kangoapp.view.history; | |
| import java.util.ArrayDeque; | |
| import java.util.Deque; | |
| public class History<ENTITY> { | |
| private Deque<ENTITY> backStack = new ArrayDeque<>(); | |
| private Deque<ENTITY> forwardStack; | |
| private ENTITY current; | |
| private int max; | |
| public History(int max) { | |
| this.max = max; | |
| } | |
| public void record(ENTITY entity) { | |
| if (backStack.size() >= max) { | |
| backStack.pollFirst(); | |
| } | |
| if (!entity.equals(current)) { | |
| current = entity; | |
| backStack.add(entity); | |
| forwardStack = new ArrayDeque<>(); | |
| } | |
| } | |
| public ENTITY back() { | |
| ENTITY back = backStack.pollLast(); | |
| if (back != null) { | |
| forwardStack.add(current); | |
| } | |
| if (current.equals(back)) { | |
| back = backStack.pollLast(); | |
| } | |
| if (back != null) { | |
| current = back; | |
| } | |
| return back; | |
| } | |
| public ENTITY forward() { | |
| ENTITY forward = forwardStack.pollLast(); | |
| if (forward != null) { | |
| backStack.add(current); | |
| } | |
| if (current.equals(forward)) { | |
| forward = forwardStack.pollLast(); | |
| } | |
| if (forward != null) { | |
| current = forward; | |
| } | |
| return forward; | |
| } | |
| public ENTITY getCurrent() { | |
| return current; | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | package com.kangoapp.view.history; | |
| public class HistoryManager { | |
| private final History<String> history = new History<>(1000); | |
| private boolean addHistoryRecord = true; | |
| public HistoryManager() { | |
| history.record(""); | |
| } | |
| public History<String> getHistory() { | |
| return history; | |
| } | |
| public boolean isAddHistoryRecord() { | |
| return addHistoryRecord; | |
| } | |
| public void setAddHistoryRecord(boolean addHistoryRecord) { | |
| this.addHistoryRecord = addHistoryRecord; | |
| } | |
| public void enableHistoryRecording() { | |
| this.addHistoryRecord = true; | |
| } | |
| public void disableHistoryRecording() { | |
| this.addHistoryRecord = false; | |
| } | |
| public void record(String text) { | |
| history.record(text); | |
| } | |
| public String back() { | |
| return history.back(); | |
| } | |
| public String forward() { | |
| return history.forward(); | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | package com.kangoapp.view.history; | |
| import org.junit.Assert; | |
| import org.junit.Before; | |
| import org.junit.Test; | |
| public class HistoryTest { | |
| private History<String> history; | |
| @Before | |
| public void setUp() throws Exception { | |
| history = new History<>(5); | |
| } | |
| @Test | |
| public void testRecord() throws Exception { | |
| history.record(""); | |
| history.record("a"); | |
| history.record("b"); | |
| history.record("c"); | |
| history.record("d"); | |
| Assert.assertEquals("c", history.back()); | |
| Assert.assertEquals("b", history.back()); | |
| Assert.assertEquals("a", history.back()); | |
| Assert.assertEquals("", history.back()); | |
| Assert.assertEquals(null, history.back()); | |
| Assert.assertEquals(null, history.back()); | |
| Assert.assertEquals("a", history.forward()); | |
| Assert.assertEquals("b", history.forward()); | |
| Assert.assertEquals("c", history.forward()); | |
| Assert.assertEquals("d", history.forward()); | |
| Assert.assertEquals(null, history.forward()); | |
| Assert.assertEquals(null, history.forward()); | |
| Assert.assertEquals("c", history.back()); | |
| Assert.assertEquals("b", history.back()); | |
| Assert.assertEquals("a", history.back()); | |
| } | |
| @Test | |
| public void testMax() throws Exception { | |
| history.record(""); | |
| history.record("a"); | |
| history.record("b"); | |
| history.record("c"); | |
| history.record("d"); | |
| history.record("e"); | |
| history.record("f"); | |
| Assert.assertEquals("e", history.back()); | |
| Assert.assertEquals("d", history.back()); | |
| Assert.assertEquals("c", history.back()); | |
| Assert.assertEquals("b", history.back()); | |
| Assert.assertEquals(null, history.back()); | |
| Assert.assertEquals(null, history.back()); | |
| Assert.assertEquals("c", history.forward()); | |
| Assert.assertEquals("d", history.forward()); | |
| Assert.assertEquals("e", history.forward()); | |
| Assert.assertEquals("f", history.forward()); | |
| Assert.assertEquals(null, history.forward()); | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment