@@ -10,15 +10,16 @@ import org.rekotlin.Subscription
1010
1111// TODO: Check is this need to be a singleton ?
1212sealed class RoutingAction
13- data class push (val responsibleRoutableIndex : Int , val segmentToBePushed : RouteElementIdentifier ): RoutingAction()
14- data class pop (val responsibleRoutableIndex : Int , val segmentToBePopped : RouteElementIdentifier ): RoutingAction()
15- data class change (val responsibleRoutableIndex : Int , val segmentToBeReplaced : RouteElementIdentifier ,
16- val newSegment : RouteElementIdentifier ): RoutingAction()
1713
14+ data class push (val responsibleRoutableIndex : Int , val segmentToBePushed : RouteElementIdentifier ) : RoutingAction()
15+ data class pop (val responsibleRoutableIndex : Int , val segmentToBePopped : RouteElementIdentifier ) : RoutingAction()
16+ data class change (val responsibleRoutableIndex : Int , val segmentToBeReplaced : RouteElementIdentifier ,
17+ val newSegment : RouteElementIdentifier ) : RoutingAction()
1818
19- class Router <routerStateType: StateType > (var store : Store <routerStateType>,
19+
20+ class Router <routerStateType : StateType >(var store : Store <routerStateType>,
2021 rootRoutable : Routable ,
21- stateTransform : (Subscription <routerStateType>) -> Subscription <NavigationState >): StoreSubscriber<NavigationState> {
22+ stateTransform : (Subscription <routerStateType>) -> Subscription <NavigationState >) : StoreSubscriber<NavigationState> {
2223
2324 var lastNavigationState = NavigationState ()
2425 // TODO: Collections.synchronizedList vs CopyOnWriteArrayList
@@ -27,13 +28,13 @@ class Router<routerStateType: StateType> (var store: Store<routerStateType>,
2728
2829 init {
2930 this .routables.add(rootRoutable)
30- this .store.subscribe(this ,stateTransform)
31+ this .store.subscribe(this , stateTransform)
3132 }
3233
3334 private val mainThreadHandler = Handler (Looper .getMainLooper())
3435
3536 override fun newState (state : NavigationState ) {
36- val routingActions = routingActionsForTransitionFrom(lastNavigationState.route,state.route)
37+ val routingActions = routingActionsForTransitionFrom(lastNavigationState.route, state.route)
3738 if (routingActions.size > 0 ) {
3839 routingActions.forEach { routingAction ->
3940 routingSerailActionHandler(routingAction, state)
@@ -44,139 +45,137 @@ class Router<routerStateType: StateType> (var store: Store<routerStateType>,
4445
4546 private fun routingSerailActionHandler (routingAction : RoutingAction , state : NavigationState ) {
4647
47- synchronized(lock = routables){
48- when (routingAction) {
48+ synchronized(lock = routables) {
49+ when (routingAction) {
4950
50- is pop -> {
51- mainThreadHandler.post {
52- this .routables[routingAction.responsibleRoutableIndex]
53- .popRouteSegment(routeElementIdentifier = routingAction.segmentToBePopped,
54- animated = state.changeRouteAnimated) {}
55- this .routables.removeAt(routingAction.responsibleRoutableIndex+ 1 )
56- }
51+ is pop -> {
52+ mainThreadHandler.post {
53+ this .routables[routingAction.responsibleRoutableIndex]
54+ .popRouteSegment(routeElementIdentifier = routingAction.segmentToBePopped,
55+ animated = state.changeRouteAnimated) {}
56+ this .routables.removeAt(routingAction.responsibleRoutableIndex + 1 )
5757 }
58+ }
5859
59- is push -> {
60- mainThreadHandler.post {
61- val newRoutable = this .routables[routingAction.responsibleRoutableIndex].
62- pushRouteSegment(routeElementIdentifier = routingAction.segmentToBePushed,
63- animated = state.changeRouteAnimated){}
64- this .routables.add(newRoutable)
65- }
66-
60+ is push -> {
61+ mainThreadHandler.post {
62+ val newRoutable = this .routables[routingAction.responsibleRoutableIndex].pushRouteSegment(routeElementIdentifier = routingAction.segmentToBePushed,
63+ animated = state.changeRouteAnimated) {}
64+ this .routables.add(newRoutable)
6765 }
6866
69- is change -> {
70- mainThreadHandler.post {
71- this .routables[routingAction.responsibleRoutableIndex + 1 ] =
72- this .routables[routingAction.responsibleRoutableIndex].
73- changeRouteSegment(from = routingAction.segmentToBeReplaced,
74- to = routingAction.newSegment ,
75- animated = state.changeRouteAnimated){}
76- }
67+ }
68+
69+ is change -> {
70+ mainThreadHandler.post {
71+ this .routables[routingAction.responsibleRoutableIndex + 1 ] =
72+ this .routables[routingAction.responsibleRoutableIndex].changeRouteSegment(from = routingAction.segmentToBeReplaced ,
73+ to = routingAction.newSegment,
74+ animated = state.changeRouteAnimated) { }
7775 }
7876 }
77+ }
7978 }
8079 }
8180
8281 // Route Transformation Logic
8382 companion object {
84- private fun largestCommonSubroute (oldRoute : Route , newRoute : Route ): Int {
85- var largestCommonSubroute = - 1
83+ private fun largestCommonSubroute (oldRoute : Route , newRoute : Route ): Int {
84+ var largestCommonSubroute = - 1
8685
87- while (largestCommonSubroute + 1 < newRoute.count() &&
88- largestCommonSubroute + 1 < oldRoute.count() &&
89- newRoute[largestCommonSubroute + 1 ] == oldRoute[largestCommonSubroute + 1 ]){
90- largestCommonSubroute + = 1
91- }
86+ while (largestCommonSubroute + 1 < newRoute.count() &&
87+ largestCommonSubroute + 1 < oldRoute.count() &&
88+ newRoute[largestCommonSubroute + 1 ] == oldRoute[largestCommonSubroute + 1 ]) {
89+ largestCommonSubroute + = 1
90+ }
9291
93- return largestCommonSubroute
94- }
92+ return largestCommonSubroute
93+ }
9594
9695
97- // Maps Route index to Routable index. Routable index is offset by 1 because the root Routable
98- // is not represented in the route, e.g.
99- // route = ["tabBar"]
100- // routables = [RootRoutable, TabBarRoutable]
96+ // Maps Route index to Routable index. Routable index is offset by 1 because the root Routable
97+ // is not represented in the route, e.g.
98+ // route = ["tabBar"]
99+ // routables = [RootRoutable, TabBarRoutable]
101100
102- private fun routableIndexForRouteSegment (segment : Int ): Int {
103- return segment + 1
104- }
101+ private fun routableIndexForRouteSegment (segment : Int ): Int {
102+ return segment + 1
103+ }
105104
106- fun routingActionsForTransitionFrom (oldRoute : Route , newRoute : Route ) : ArrayList <RoutingAction > {
105+ fun routingActionsForTransitionFrom (oldRoute : Route , newRoute : Route ): ArrayList <RoutingAction > {
107106
108- val routingActions = arrayListOf<RoutingAction >()
107+ val routingActions = arrayListOf<RoutingAction >()
109108
110- // Find the last common subroute between two routes
111- val commonSubroute = largestCommonSubroute(oldRoute, newRoute)
109+ // Find the last common subroute between two routes
110+ val commonSubroute = largestCommonSubroute(oldRoute, newRoute)
112111
113- if (commonSubroute == oldRoute.count() - 1 && commonSubroute == newRoute.count() - 1 ) {
114- return arrayListOf ()
115- }
116- // Keeps track which element of the routes we are working on
117- // We start at the end of the old route
118- var routeBuildingIndex = oldRoute.count() - 1
119-
120- // Pop all route segments of the old route that are no longer in the new route
121- // Stop one element ahead of the commonSubroute. When we are one element ahead of the
122- // commmon subroute we have three options:
123- //
124- // 1. The old route had an element after the commonSubroute and the new route does not
125- // we need to pop the route segment after the commonSubroute
126- // 2. The old route had no element after the commonSubroute and the new route does, we
127- // we need to push the route segment(s) after the commonSubroute
128- // 3. The new route has a different element after the commonSubroute, we need to replace
129- // the old route element with the new one
130- while (routeBuildingIndex > commonSubroute + 1 ) {
131- val routeSegmentToPop = oldRoute[routeBuildingIndex]
132-
133- val popAction = pop(routableIndexForRouteSegment(routeBuildingIndex - 1 ),
134- routeSegmentToPop)
135- routingActions.add(popAction)
136- routeBuildingIndex - = 1
137- }
112+ if (commonSubroute == oldRoute.count() - 1 && commonSubroute == newRoute.count() - 1 ) {
113+ return arrayListOf ()
114+ }
115+ // Keeps track which element of the routes we are working on
116+ // We start at the end of the old route
117+ var routeBuildingIndex = oldRoute.count() - 1
118+
119+ // Pop all route segments of the old route that are no longer in the new route
120+ // Stop one element ahead of the commonSubroute. When we are one element ahead of the
121+ // commmon subroute we have three options:
122+ //
123+ // 1. The old route had an element after the commonSubroute and the new route does not
124+ // we need to pop the route segment after the commonSubroute
125+ // 2. The old route had no element after the commonSubroute and the new route does, we
126+ // we need to push the route segment(s) after the commonSubroute
127+ // 3. The new route has a different element after the commonSubroute, we need to replace
128+ // the old route element with the new one
129+ while (routeBuildingIndex > commonSubroute + 1 ) {
130+ val routeSegmentToPop = oldRoute[routeBuildingIndex]
131+
132+ val popAction = pop(routableIndexForRouteSegment(routeBuildingIndex - 1 ),
133+ routeSegmentToPop)
134+ routingActions.add(popAction)
135+ routeBuildingIndex - = 1
136+ }
138137
139- // This is the 3. case:
140- // "The new route has a different element after the commonSubroute, we need to replace
141- // the old route element with the new one"
142- if ((oldRoute.count() > (commonSubroute + 1 ))
143- && (newRoute.count() > (commonSubroute + 1 ))) {
144- val changeAction = change(routableIndexForRouteSegment(commonSubroute),
145- oldRoute[commonSubroute + 1 ],
146- newRoute[commonSubroute + 1 ])
138+ // This is the 3. case:
139+ // "The new route has a different element after the commonSubroute, we need to replace
140+ // the old route element with the new one"
141+ if ((oldRoute.count() > (commonSubroute + 1 ))
142+ && (newRoute.count() > (commonSubroute + 1 ))) {
143+ val changeAction = change(routableIndexForRouteSegment(commonSubroute),
144+ oldRoute[commonSubroute + 1 ],
145+ newRoute[commonSubroute + 1 ])
147146
148- routingActions.add(changeAction)
149- }
150- // This is the 1. case:
151- // "The old route had an element after the commonSubroute and the new route does not
152- // we need to pop the route segment after the commonSubroute"
153- else if (oldRoute.count() > newRoute.count()) {
154- val popAction = pop(routableIndexForRouteSegment(routeBuildingIndex - 1 ),
155- oldRoute[routeBuildingIndex])
156-
157- // routingActions = routingActions.plus(popAction)
158- routingActions.add(popAction)
159- routeBuildingIndex - = 1
160- }
147+ routingActions.add(changeAction)
148+ }
149+ // This is the 1. case:
150+ // "The old route had an element after the commonSubroute and the new route does not
151+ // we need to pop the route segment after the commonSubroute"
152+ else if (oldRoute.count() > newRoute.count()) {
153+ val popAction = pop(routableIndexForRouteSegment(routeBuildingIndex - 1 ),
154+ oldRoute[routeBuildingIndex])
155+
156+ // routingActions = routingActions.plus(popAction)
157+ routingActions.add(popAction)
158+ routeBuildingIndex - = 1
159+ }
161160
162- // Push remainder of elements in new Route that weren't in old Route, this covers
163- // the 2. case:
164- // "The old route had no element after the commonSubroute and the new route does,
165- // we need to push the route segment(s) after the commonSubroute"
166- val newRouteIndex = newRoute.count() - 1
161+ // Push remainder of elements in new Route that weren't in old Route, this covers
162+ // the 2. case:
163+ // "The old route had no element after the commonSubroute and the new route does,
164+ // we need to push the route segment(s) after the commonSubroute"
165+ val newRouteIndex = newRoute.count() - 1
167166
168- while (routeBuildingIndex < newRouteIndex) {
169- val routeSegmentToPush = newRoute[routeBuildingIndex + 1 ]
167+ while (routeBuildingIndex < newRouteIndex) {
168+ val routeSegmentToPush = newRoute[routeBuildingIndex + 1 ]
170169
171- val pushAction = push(routableIndexForRouteSegment(routeBuildingIndex),
172- routeSegmentToPush)
170+ val pushAction = push(routableIndexForRouteSegment(routeBuildingIndex),
171+ routeSegmentToPush)
173172
174- routingActions.add(pushAction)
175- routeBuildingIndex + = 1
176- }
173+ routingActions.add(pushAction)
174+ routeBuildingIndex + = 1
175+ }
177176
178- return routingActions
179- }
177+ return routingActions
178+ }
180179 }
181180}
182181
0 commit comments