Browse Source

indexed stack

Daniel Zlotin 7 years ago
parent
commit
63c5e60ca4

lib/android/app/src/main/java/com/reactnativenavigation/utils/IdStack.java → lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/IndexedStack.java View File

@@ -1,12 +1,12 @@
1
-package com.reactnativenavigation.utils;
1
+package com.reactnativenavigation.viewcontrollers;
2
+
3
+import com.reactnativenavigation.utils.StringUtils;
2 4
 
3 5
 import java.util.ArrayDeque;
4
-import java.util.Deque;
5 6
 import java.util.HashMap;
6 7
 import java.util.Iterator;
7
-import java.util.Map;
8 8
 
9
-public class IdStack<E> implements Iterable<String> {
9
+public class IndexedStack<E> implements Iterable<String> {
10 10
 
11 11
 	private final ArrayDeque<String> deque = new ArrayDeque<>();
12 12
 	private final HashMap<String, E> map = new HashMap<>();
@@ -63,16 +63,12 @@ public class IdStack<E> implements Iterable<String> {
63 63
 		return map.remove(id);
64 64
 	}
65 65
 
66
+	public boolean isTop(final String id) {
67
+		return StringUtils.isEqual(id, peekId());
68
+	}
69
+
66 70
 	@Override
67 71
 	public Iterator<String> iterator() {
68 72
 		return deque.iterator();
69 73
 	}
70
-
71
-	public Deque<String> getIds() {
72
-		return deque;
73
-	}
74
-
75
-	public Map<String, E> getMap() {
76
-		return map;
77
-	}
78 74
 }

+ 14
- 28
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/StackController.java View File

@@ -6,15 +6,8 @@ import android.support.annotation.Nullable;
6 6
 import android.view.ViewGroup;
7 7
 import android.widget.FrameLayout;
8 8
 
9
-import com.reactnativenavigation.utils.StringUtils;
10
-
11
-import java.util.ArrayDeque;
12
-import java.util.HashMap;
13
-import java.util.Map;
14
-
15 9
 public class StackController extends ViewController {
16
-	private final ArrayDeque<String> idStack = new ArrayDeque<>();
17
-	private final Map<String, ViewController> controllersById = new HashMap<>();
10
+	private final IndexedStack<ViewController> stack = new IndexedStack<>();
18 11
 
19 12
 	public StackController(final Activity activity, String id) {
20 13
 		super(activity, id);
@@ -24,8 +17,7 @@ public class StackController extends ViewController {
24 17
 		final ViewController previousTop = peek();
25 18
 
26 19
 		child.setStackController(this);
27
-		idStack.push(child.getId());
28
-		controllersById.put(child.getId(), child);
20
+		stack.push(child.getId(), child);
29 21
 
30 22
 		getView().addView(child.getView());
31 23
 		if (previousTop != null) {
@@ -34,15 +26,14 @@ public class StackController extends ViewController {
34 26
 	}
35 27
 
36 28
 	public boolean canPop() {
37
-		return idStack.size() > 1;
29
+		return stack.size() > 1;
38 30
 	}
39 31
 
40 32
 	public void pop() {
41 33
 		if (!canPop()) {
42 34
 			return;
43 35
 		}
44
-		String poppedId = idStack.pop();
45
-		ViewController poppedController = controllersById.remove(poppedId);
36
+		ViewController poppedController = stack.pop();
46 37
 		getView().removeView(poppedController.getView());
47 38
 
48 39
 		ViewController previousTop = peek();
@@ -50,28 +41,23 @@ public class StackController extends ViewController {
50 41
 	}
51 42
 
52 43
 	public void pop(final ViewController childController) {
53
-		if (StringUtils.isEqual(peekId(), childController.getId())) {
44
+		if (stack.isTop(childController.getId())) {
54 45
 			pop();
55 46
 		} else {
56
-			idStack.remove(childController.getId());
57
-			controllersById.remove(childController.getId());
47
+			stack.remove(childController.getId());
58 48
 		}
59 49
 	}
60 50
 
61 51
 	public ViewController peek() {
62
-		return controllersById.get(peekId());
63
-	}
64
-
65
-	public String peekId() {
66
-		return idStack.peek();
52
+		return stack.peek();
67 53
 	}
68 54
 
69 55
 	public int size() {
70
-		return idStack.size();
56
+		return stack.size();
71 57
 	}
72 58
 
73 59
 	public boolean isEmpty() {
74
-		return idStack.isEmpty();
60
+		return stack.isEmpty();
75 61
 	}
76 62
 
77 63
 	@Override
@@ -103,10 +89,10 @@ public class StackController extends ViewController {
103 89
 	}
104 90
 
105 91
 	public void popTo(final ViewController viewController) {
106
-		if (!idStack.contains(viewController.getId())) {
92
+		if (!stack.containsId(viewController.getId())) {
107 93
 			return;
108 94
 		}
109
-		while (!StringUtils.isEqual(peekId(), viewController.getId())) {
95
+		while (!stack.isTop(viewController.getId())) {
110 96
 			pop();
111 97
 		}
112 98
 	}
@@ -118,10 +104,10 @@ public class StackController extends ViewController {
118 104
 	}
119 105
 
120 106
 	public ViewController getChildById(final String id) {
121
-		return controllersById.get(id);
107
+		return stack.get(id);
122 108
 	}
123 109
 
124
-	ArrayDeque<String> getStack() {
125
-		return idStack;
110
+	boolean containsId(String id) {
111
+		return stack.containsId(id);
126 112
 	}
127 113
 }

lib/android/app/src/test/java/com/reactnativenavigation/utils/IndexedStackTest.java → lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/IndexedStackTest.java View File

@@ -1,22 +1,20 @@
1
-package com.reactnativenavigation.utils;
1
+package com.reactnativenavigation.viewcontrollers;
2 2
 
3 3
 import com.reactnativenavigation.BaseTest;
4
+import com.reactnativenavigation.viewcontrollers.IndexedStack;
4 5
 
5 6
 import org.junit.Test;
6 7
 
7
-import java.util.Deque;
8
-import java.util.Map;
9
-
10 8
 import static org.assertj.core.api.Java6Assertions.assertThat;
11 9
 
12 10
 public class IndexedStackTest extends BaseTest {
13 11
 
14
-	private IdStack<Integer> uut;
12
+	private IndexedStack<Integer> uut;
15 13
 
16 14
 	@Override
17 15
 	public void beforeEach() {
18 16
 		super.beforeEach();
19
-		uut = new IdStack<>();
17
+		uut = new IndexedStack<>();
20 18
 	}
21 19
 
22 20
 	@Test
@@ -99,12 +97,11 @@ public class IndexedStackTest extends BaseTest {
99 97
 	}
100 98
 
101 99
 	@Test
102
-	public void getIdDeque() throws Exception {
103
-		assertThat(uut.getIds()).isNotNull().isInstanceOf(Deque.class).isEmpty();
104
-	}
105
-
106
-	@Test
107
-	public void getMap() throws Exception {
108
-		assertThat(uut.getMap()).isNotNull().isInstanceOf(Map.class).isEmpty();
100
+	public void isTop() throws Exception {
101
+		assertThat(uut.isTop("123")).isFalse();
102
+		uut.push("123", 123);
103
+		assertThat(uut.isTop("123")).isTrue();
104
+		uut.push("456", 456);
105
+		assertThat(uut.isTop("123")).isFalse();
109 106
 	}
110 107
 }

+ 19
- 12
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackControllerTest.java View File

@@ -41,23 +41,23 @@ public class StackControllerTest extends BaseTest {
41 41
 		uut.push(child2);
42 42
 		uut.push(child3);
43 43
 		assertThat(uut.peek()).isEqualTo(child3);
44
-		assertThat(uut.getStack()).containsOnly(child1.getId(), child2.getId(), child3.getId());
44
+		assertContainsOnlyId(child1.getId(), child2.getId(), child3.getId());
45 45
 	}
46 46
 
47 47
 	@Test
48 48
 	public void push() throws Exception {
49 49
 		assertThat(uut.isEmpty()).isTrue();
50 50
 		uut.push(child1);
51
-		assertThat(uut.getStack()).containsOnly(child1.getId());
51
+		assertContainsOnlyId(child1.getId());
52 52
 	}
53 53
 
54 54
 	@Test
55 55
 	public void pop() throws Exception {
56 56
 		uut.push(child1);
57 57
 		uut.push(child2);
58
-		assertThat(uut.getStack()).containsOnly(child2.getId(), child1.getId());
58
+		assertContainsOnlyId(child2.getId(), child1.getId());
59 59
 		uut.pop();
60
-		assertThat(uut.getStack()).containsOnly(child1.getId());
60
+		assertContainsOnlyId(child1.getId());
61 61
 	}
62 62
 
63 63
 	@Test
@@ -100,24 +100,24 @@ public class StackControllerTest extends BaseTest {
100 100
 
101 101
 	@Test
102 102
 	public void popDoesNothingWhenZeroOrOneChild() throws Exception {
103
-		assertThat(uut.getStack()).isEmpty();
103
+		assertThat(uut.isEmpty()).isTrue();
104 104
 		uut.pop();
105
-		assertThat(uut.getStack()).isEmpty();
105
+		assertThat(uut.isEmpty()).isTrue();
106 106
 
107 107
 		uut.push(child1);
108 108
 		uut.pop();
109
-		assertThat(uut.getStack()).containsOnly(child1.getId());
109
+		assertContainsOnlyId(child1.getId());
110 110
 	}
111 111
 
112 112
 	@Test
113 113
 	public void canPopWhenSizeIsMoreThanOne() throws Exception {
114
-		assertThat(uut.getStack()).isEmpty();
114
+		assertThat(uut.isEmpty()).isTrue();
115 115
 		assertThat(uut.canPop()).isFalse();
116 116
 		uut.push(child1);
117
-		assertThat(uut.getStack()).containsOnly(child1.getId());
117
+		assertContainsOnlyId(child1.getId());
118 118
 		assertThat(uut.canPop()).isFalse();
119 119
 		uut.push(child2);
120
-		assertThat(uut.getStack()).containsOnly(child1.getId(), child2.getId());
120
+		assertContainsOnlyId(child1.getId(), child2.getId());
121 121
 		assertThat(uut.canPop()).isTrue();
122 122
 	}
123 123
 
@@ -159,7 +159,7 @@ public class StackControllerTest extends BaseTest {
159 159
 		uut.push(child1);
160 160
 		uut.push(child2);
161 161
 		uut.pop(child2);
162
-		assertThat(uut.getStack()).containsOnly(child1.getId());
162
+		assertContainsOnlyId(child1.getId());
163 163
 		assertHasSingleChildViewOfController(child1);
164 164
 	}
165 165
 
@@ -170,7 +170,7 @@ public class StackControllerTest extends BaseTest {
170 170
 		assertHasSingleChildViewOfController(child2);
171 171
 
172 172
 		uut.pop(child1);
173
-		assertThat(uut.getStack()).containsOnly(child2.getId());
173
+		assertContainsOnlyId(child2.getId());
174 174
 		assertHasSingleChildViewOfController(child2);
175 175
 	}
176 176
 
@@ -236,4 +236,11 @@ public class StackControllerTest extends BaseTest {
236 236
 		assertThat(uut.getView().getChildCount()).isEqualTo(1);
237 237
 		assertThat(uut.getView().getChildAt(0)).isEqualTo(childController.getView());
238 238
 	}
239
+
240
+	private void assertContainsOnlyId(String... ids) {
241
+		assertThat(uut.size()).isEqualTo(ids.length);
242
+		for (String id : ids) {
243
+			assertThat(uut.containsId(id));
244
+		}
245
+	}
239 246
 }