-
-
Notifications
You must be signed in to change notification settings - Fork 575
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
18 changed files
with
415 additions
and
8 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import {useThread} from '../utils'; | ||
import {DependencyContext} from './DependencyContext'; | ||
|
||
export class DeferredEffectContext extends DependencyContext { | ||
private readonly unsubscribe; | ||
public constructor(private readonly callback: () => void) { | ||
super(); | ||
this.unsubscribe = useThread().onDeferred.subscribe(this.update); | ||
this.markDirty(); | ||
} | ||
|
||
private update = () => { | ||
if (this.event.isRaised()) { | ||
this.clearDependencies(); | ||
this.startCollecting(); | ||
this.callback(); | ||
this.finishCollecting(); | ||
this.event.reset(); | ||
} | ||
}; | ||
|
||
public dispose() { | ||
super.dispose(); | ||
this.unsubscribe(); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import {DependencyContext} from './DependencyContext'; | ||
|
||
export class EffectContext extends DependencyContext { | ||
public constructor(private readonly callback: () => void) { | ||
super(); | ||
this.event.subscribe(this.update); | ||
this.markDirty(); | ||
} | ||
|
||
private update = () => { | ||
this.clearDependencies(); | ||
this.startCollecting(); | ||
this.callback(); | ||
this.finishCollecting(); | ||
this.event.reset(); | ||
}; | ||
} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import {afterAll, beforeAll, describe, expect, test, vi} from 'vitest'; | ||
import {PlaybackManager, PlaybackStatus} from '../app'; | ||
import {run} from '../flow'; | ||
import {threads} from '../threading'; | ||
import {endPlayback, startPlayback} from '../utils'; | ||
import {createDeferredEffect} from './createDeferredEffect'; | ||
import {createSignal} from './createSignal'; | ||
|
||
describe('createDeferredEffect()', () => { | ||
const status = new PlaybackStatus(new PlaybackManager()); | ||
beforeAll(() => startPlayback(status)); | ||
afterAll(() => endPlayback(status)); | ||
|
||
test('Deferred till the end of the frame', () => { | ||
const task = threads(function* () { | ||
const a = createSignal(1); | ||
const b = createSignal(2); | ||
const callback = vi.fn(() => { | ||
a(); | ||
b(); | ||
}); | ||
const unsub = createDeferredEffect(callback); | ||
|
||
expect(callback).toBeCalledTimes(0); | ||
yield; | ||
expect(callback).toBeCalledTimes(1); | ||
yield; | ||
expect(callback).toBeCalledTimes(1); | ||
a(2); | ||
a(3); | ||
b(3); | ||
expect(callback).toBeCalledTimes(1); | ||
yield; | ||
expect(callback).toBeCalledTimes(2); | ||
|
||
unsub(); | ||
yield; | ||
expect(callback).toBeCalledTimes(2); | ||
}); | ||
|
||
[...task]; | ||
}); | ||
|
||
test('Executed after all threads', () => { | ||
const order: number[] = []; | ||
const task = threads(function* () { | ||
const signal = createSignal(0); | ||
order.push(0); | ||
|
||
yield run(function* () { | ||
createDeferredEffect(() => { | ||
signal(); | ||
order.push(-1); | ||
}); | ||
|
||
order.push(1); | ||
yield; | ||
order.push(4); | ||
yield; | ||
}); | ||
|
||
yield run(function* () { | ||
order.push(2); | ||
yield; | ||
order.push(5); | ||
yield; | ||
}); | ||
|
||
order.push(3); | ||
yield; | ||
signal(1); | ||
order.push(6); | ||
yield; | ||
}); | ||
|
||
[...task]; | ||
|
||
expect(order).toEqual([0, 1, 2, 3, -1, 4, 5, 6, -1]); | ||
}); | ||
}); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import {DeferredEffectContext} from './DeferredEffectContext'; | ||
|
||
/** | ||
* Invoke the callback at the end of each frame if any of its dependencies | ||
* changed. | ||
* | ||
* @param callback - The callback to invoke. | ||
*/ | ||
export function createDeferredEffect(callback: () => void): () => void { | ||
const context = new DeferredEffectContext(callback); | ||
return () => context.dispose(); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import {describe, expect, test, vi} from 'vitest'; | ||
import {createSignal} from './createSignal'; | ||
|
||
import {createEffect} from './createEffect'; | ||
|
||
describe('createEffect()', () => { | ||
test('Invoked after creation', () => { | ||
const callback = vi.fn(); | ||
createEffect(callback); | ||
|
||
expect(callback).toBeCalled(); | ||
}); | ||
|
||
test('Invoked when dependencies change', () => { | ||
const a = createSignal(1); | ||
const b = createSignal(2); | ||
const callback = vi.fn(() => { | ||
a(); | ||
b(); | ||
}); | ||
createEffect(callback); | ||
|
||
a(2); | ||
a(3); | ||
b(3); | ||
b(4); | ||
|
||
expect(callback).toBeCalledTimes(5); | ||
}); | ||
|
||
test('Not invoked after unsubscribing', () => { | ||
const a = createSignal(1); | ||
const b = createSignal(2); | ||
const callback = vi.fn(() => { | ||
a(); | ||
b(); | ||
}); | ||
const unsub = createEffect(callback); | ||
|
||
a(2); | ||
b(3); | ||
|
||
unsub(); | ||
|
||
a(3); | ||
b(4); | ||
|
||
expect(callback).toBeCalledTimes(3); | ||
}); | ||
}); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import {EffectContext} from './EffectContext'; | ||
|
||
/** | ||
* Invoke the callback immediately after any of its dependencies change. | ||
* | ||
* @param callback - The callback to invoke. | ||
*/ | ||
export function createEffect(callback: () => void): () => void { | ||
const context = new EffectContext(callback); | ||
return () => context.dispose(); | ||
} |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Oops, something went wrong.