(engine: VisualNovelEngine, statement: unknown = null, shouldAdvance = true, shouldStepBack = true)
| 189 | * @returns {Promise} - Whether the game was able to go back or not |
| 190 | */ |
| 191 | export async function revert (engine: VisualNovelEngine, statement: unknown = null, shouldAdvance = true, shouldStepBack = true): Promise<{ advance: boolean; step: boolean } | void> { |
| 192 | const actions = engine.actions (); |
| 193 | const before: Promise<void>[] = actions.map (action => action.beforeRevert ({ advance: shouldAdvance, step: shouldStepBack })); |
| 194 | |
| 195 | await Promise.all (before); |
| 196 | |
| 197 | // Check if we have steps behind us to revert to. If there aren't, then |
| 198 | // we can't revert since we are already at the first statement. |
| 199 | let actionToRevert: unknown = null; |
| 200 | const currentStep = engine.state ('step') as number; |
| 201 | const currentLabel = engine.state ('label') as string; |
| 202 | const label = engine.label () as unknown[]; |
| 203 | |
| 204 | if (statement !== null) { |
| 205 | actionToRevert = statement; |
| 206 | } else if (currentStep >= 1) { |
| 207 | actionToRevert = label[currentStep - 1]; |
| 208 | } else { |
| 209 | const jumpHistory = engine.history ('jump') as Array<{ destination: { label: string; step: number }; source: { label: string; step: number } }>; |
| 210 | const jump = [...jumpHistory].reverse ().find (o => { |
| 211 | return o.destination.label === currentLabel && o.destination.step === 0; |
| 212 | }); |
| 213 | |
| 214 | if (typeof jump !== 'undefined') { |
| 215 | engine.state ({ |
| 216 | label: jump.source.label, |
| 217 | step: jump.source.step |
| 218 | }); |
| 219 | const newLabel = engine.label () as unknown[]; |
| 220 | const newStep = engine.state ('step') as number; |
| 221 | actionToRevert = newLabel[newStep]; |
| 222 | engine.debug.debug ('Will revert to previous label.'); |
| 223 | } else { |
| 224 | engine.debug.debug ('Will not revert since this is the beginning of the game.'); |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | // Don't allow null as a valid statement |
| 229 | if (actionToRevert === null || typeof actionToRevert === 'undefined') { |
| 230 | // Clear the Stack using a Time Out instead of calling |
| 231 | // the function directly, preventing an Overflow |
| 232 | const labelArray = engine.label () as unknown[]; |
| 233 | const step = engine.state ('step') as number; |
| 234 | |
| 235 | setTimeout (() => { |
| 236 | engine.run (labelArray[step]); |
| 237 | }, 0); |
| 238 | |
| 239 | engine.debug.groupEnd (); |
| 240 | |
| 241 | return Promise.resolve (); |
| 242 | } |
| 243 | |
| 244 | // If the statement is a pure js function, it won't be reverted since we don't |
| 245 | // know what to do to revert it. |
| 246 | if (typeof actionToRevert === 'function') { |
| 247 | return Promise.reject (); |
| 248 | } |
nothing calls this directly
no test coverage detected