Skip to content

Commit d195337

Browse files
Refactor jump code
1 parent aa936d6 commit d195337

File tree

3 files changed

+82
-25
lines changed

3 files changed

+82
-25
lines changed

packages/library/src/base/controller.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,21 +168,28 @@ export class Controller<C extends Component = Component> extends Emitter {
168168
}
169169
}
170170

171-
// Rerun that stack
172-
if (commonStack.length == 0) {
171+
this.context = await this.iterator?.tempSplice(commonStack.length + 1, [
172+
{}, // flipData
173+
this.context,
174+
])
175+
176+
// Having torn down the larger part of the current component stack,
177+
// issue a reset to the remaining part.
178+
//@ts-ignore
179+
await last(this.currentStack)?._reset?.()
180+
181+
// Don't re-mount the root component
182+
if (this.currentStack.length > 1) {
173183
//@ts-ignore
174-
await this.root?._reset?.()
175-
} else {
176-
await commonStack.at(-1)?._reset?.()
184+
this.iterator?.restartLeaf()
177185
}
178-
await this.iterator?.reset(commonStack.length)
186+
187+
// The fastforward call will also trigger continue
179188
await this.jump('fastforward', {
180189
target: data.targetStack,
181190
spliceLevel: commonStack.length,
182191
})
183192

184-
// Continue removed as it moves on too quickly
185-
//await this.continue(this.currentLeaf, {})
186193
break
187194
default:
188195
console.error(`Unknown jump instruction ${instruction}`)

packages/library/src/base/util/iterators/flipIterable.ts

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { range } from 'lodash'
1+
import { last, range } from 'lodash'
22

33
import { Component, Status } from '../../component'
44
import { requestAnimationFrameMaybe } from '../rAF'
@@ -47,6 +47,7 @@ export interface FlipIterator<T>
4747
// with the remainder of the interface.
4848
fastForward: (targetStack: String[], spliceLevel?: number) => Promise<void>
4949
peek: () => stackSummary
50+
tempSplice: (level: number, input: IteratorInput) => Promise<any>
5051
}
5152

5253
export class FlipIterable {
@@ -76,6 +77,7 @@ export class FlipIterable {
7677
const sliceIterator = this.timelineIterable[Symbol.asyncIterator]()
7778
let currentStack: Component[] = []
7879
let lockPromises: Promise<any>[] = []
80+
let restartLeaf = false
7981

8082
return {
8183
initialize: async () => {
@@ -112,23 +114,21 @@ export class FlipIterable {
112114
// the current and future stacks
113115
;({ incoming, outgoing } = resolveFlip(currentStack, nextStack))
114116

115-
// End all outgoing components, starting from the leaf
116-
for (const c of [...outgoing].reverse()) {
117-
try {
118-
c.internals.emitter.off(
119-
EventName.endUncontrolled,
120-
triggerContinue,
121-
)
122-
currentStack.pop()
123-
cancelled.push(c)
124-
await c.end(flipData.reason, { ...flipData, controlled: true })
125-
context = c.leaveContext(context)
126-
} catch (error) {
127-
console.error(`Error ending`, c)
128-
throw error
129-
}
117+
if (restartLeaf && currentStack.length > 0) {
118+
//@ts-ignore
119+
incoming.unshift(currentStack.pop())
120+
restartLeaf = false
130121
}
131122

123+
// End all outgoing components, starting from the leaf
124+
context = await stopOutgoing(
125+
outgoing,
126+
currentStack,
127+
cancelled,
128+
flipData,
129+
context,
130+
)
131+
132132
// Start all incoming components, starting from the top of the stack
133133
for (const c of incoming) {
134134
try {
@@ -193,6 +193,34 @@ export class FlipIterable {
193193
},
194194
}
195195
},
196+
tempSplice: async (
197+
level: number,
198+
[flipData, context]: [any, object] = [{}, {}],
199+
) => {
200+
const oldStack = currentStack
201+
const newStack = currentStack.slice(0, level)
202+
203+
// There are no incoming components in this flip
204+
const { outgoing } = resolveFlip(oldStack, newStack)
205+
206+
// Stop outgoing components
207+
const newContext = await stopOutgoing(
208+
outgoing,
209+
currentStack,
210+
[],
211+
flipData,
212+
context,
213+
)
214+
215+
// Reset nested slice iterator
216+
sliceIterator.splice(level)
217+
218+
return newContext
219+
},
220+
//@ts-ignore
221+
restartLeaf: () => {
222+
restartLeaf = true
223+
},
196224
splice: sliceIterator.splice,
197225
findSplice: sliceIterator.findSplice,
198226
reset: sliceIterator.reset,
@@ -228,3 +256,25 @@ export class FlipIterable {
228256
}
229257
}
230258
}
259+
260+
const stopOutgoing = async function (
261+
outgoing: Component[],
262+
currentStack: Component[],
263+
cancelled: Component[],
264+
flipData: any,
265+
context: object,
266+
) {
267+
for (const c of [...outgoing].reverse()) {
268+
try {
269+
c.internals.emitter.off(EventName.endUncontrolled, triggerContinue)
270+
currentStack.pop()
271+
cancelled.push(c)
272+
await c.end(flipData.reason, { ...flipData, controlled: true })
273+
context = c.leaveContext(context)
274+
} catch (error) {
275+
console.error(`Error ending`, c)
276+
throw error
277+
}
278+
}
279+
return context
280+
}

packages/library/src/base/util/iterators/timeline.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export class SliceIterable<T extends Object> {
8888
//@ts-ignore
8989
if (value.status >= Status.running) {
9090
//@ts-ignore
91-
value._reset()
91+
await value?._reset?.()
9292
}
9393
if (this.#checkIterator(value)) {
9494
outputStack.push(value)

0 commit comments

Comments
 (0)