Skip to content

Commit

Permalink
Fixed #511. Preserve random values and animations with granular reeva…
Browse files Browse the repository at this point in the history
…ulation.
  • Loading branch information
amyjko committed Jul 7, 2024
1 parent 258875b commit 235b0a6
Show file tree
Hide file tree
Showing 31 changed files with 403 additions and 271 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Dates are in `YYYY-MM-DD` format and versions are in [semantic versioning](http:
- [#216](https://github.com/wordplaydev/wordplay/issues/216) Improved design of view code and copy buttons.
- [#397](https://github.com/wordplaydev/wordplay/issues/397) Redesigned home page for clarity and navigability.
- [#506](https://github.com/wordplaydev/wordplay/issues/506) Clarified behavior of localized setting.
- [#511](https://github.com/wordplaydev/wordplay/issues/511) Fixed granularity of reevaluation to preserve random values and animations.
- Added fade out sequence.
- Fixed select all button.

Expand Down
4 changes: 4 additions & 0 deletions src/basis/InternalExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export default class InternalExpression extends SimpleExpression {
return false;
}

isInternal() {
return true;
}

compile(): Step[] {
return this.steps.length === 0
? [new StartFinish(this)]
Expand Down
4 changes: 4 additions & 0 deletions src/basis/Iteration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ export class Iteration<State = any> extends Expression {
this.finish = finish;
}

isInternal() {
return true;
}

getDescriptor() {
return 'Iteration';
}
Expand Down
20 changes: 10 additions & 10 deletions src/input/AudioStream.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type Evaluator from '@runtime/Evaluator';
import TemporalStreamValue from '../values/TemporalStreamValue';
import NumberType from '../nodes/NumberType';
import NumberValue from '@values/NumberValue';
import type Evaluation from '@runtime/Evaluation';

/** We want more deail in the frequency domain and less in the amplitude domain, but we also want to minimize how much data we analyze. */
export const DEFAULT_FREQUENCY = 33;
Expand All @@ -24,23 +24,23 @@ export default abstract class AudioStream extends TemporalStreamValue<
frequency: number;

constructor(
evaluator: Evaluator,
evaluation: Evaluation,
frequency: number | undefined,
fftSize: number
fftSize: number,
) {
super(
evaluator,
evaluator.project.shares.input.Volume,
new NumberValue(evaluator.getMain(), 0),
0
evaluation,
evaluation.getEvaluator().project.shares.input.Volume,
new NumberValue(evaluation.getCreator(), 0),
0,
);
this.fftSize = fftSize;
this.frequency = Math.max(15, frequency ?? DEFAULT_FREQUENCY);
}

abstract valueFromFrequencies(
sampleRate: number,
analyzer: AnalyserNode
analyzer: AnalyserNode,
): number;

tick(time: DOMHighResTimeStamp) {
Expand All @@ -59,8 +59,8 @@ export default abstract class AudioStream extends TemporalStreamValue<
this.react(
this.valueFromFrequencies(
this.context.sampleRate,
this.analyzer
)
this.analyzer,
),
);
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/input/Button.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type Evaluator from '@runtime/Evaluator';
import StreamValue from '@values/StreamValue';
import StreamDefinition from '@nodes/StreamDefinition';
import { getDocLocales } from '@locale/getDocLocales';
Expand All @@ -12,17 +11,18 @@ import StreamType from '@nodes/StreamType';
import createStreamEvaluator from './createStreamEvaluator';
import type Locales from '../locale/Locales';
import BooleanLiteral from '../nodes/BooleanLiteral';
import type Evaluation from '@runtime/Evaluation';

export default class Button extends StreamValue<BoolValue, boolean> {
on = false;
down: boolean | undefined;

constructor(evaluator: Evaluator, down: boolean | undefined) {
constructor(evaluator: Evaluation, down: boolean | undefined) {
super(
evaluator,
evaluator.project.shares.input.Button,
new BoolValue(evaluator.getMain(), false),
false
evaluator.getEvaluator().project.shares.input.Button,
new BoolValue(evaluator.getCreator(), false),
false,
);

this.down = down;
Expand Down Expand Up @@ -55,7 +55,7 @@ export function createButtonDefinition(locales: Locales) {
getNameLocales(locales, (locale) => locale.input.Button.down.names),
UnionType.make(BooleanType.make(), NoneType.make()),
// Default to true, because down is the most likely useful default.
BooleanLiteral.make(true)
BooleanLiteral.make(true),
);
return StreamDefinition.make(
getDocLocales(locales, (locale) => locale.input.Button.doc),
Expand All @@ -66,12 +66,12 @@ export function createButtonDefinition(locales: Locales) {
Button,
(evaluation) =>
new Button(
evaluation.getEvaluator(),
evaluation.get(DownBind.names, BoolValue)?.bool
evaluation,
evaluation.get(DownBind.names, BoolValue)?.bool,
),
(stream, evaluation) =>
stream.setDown(evaluation.get(DownBind.names, BoolValue)?.bool)
stream.setDown(evaluation.get(DownBind.names, BoolValue)?.bool),
),
BooleanType.make()
BooleanType.make(),
);
}
50 changes: 25 additions & 25 deletions src/input/Camera.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type Evaluator from '@runtime/Evaluator';
import TemporalStreamValue from '../values/TemporalStreamValue';
import StreamDefinition from '../nodes/StreamDefinition';
import { getDocLocales } from '../locale/getDocLocales';
Expand All @@ -21,6 +20,7 @@ import type StructureDefinition from '../nodes/StructureDefinition';
import type Names from '../nodes/Names';
import type Value from '../values/Value';
import type Locales from '../locale/Locales';
import type Evaluation from '@runtime/Evaluation';

type CameraConfig = {
stream: MediaStream;
Expand All @@ -47,16 +47,16 @@ export default class Camera extends TemporalStreamValue<ListValue, RawFrame> {
stopped = false;

constructor(
evaluator: Evaluator,
evaluation: Evaluation,
width: number,
height: number,
frequency: number
frequency: number,
) {
super(
evaluator,
evaluator.project.shares.input.Camera,
Camera.createFrame(evaluator.getMain(), []),
[]
evaluation,
evaluation.getEvaluator().project.shares.input.Camera,
Camera.createFrame(evaluation.getCreator(), []),
[],
);

this.width = width;
Expand All @@ -77,21 +77,21 @@ export default class Camera extends TemporalStreamValue<ListValue, RawFrame> {
// Lightness
bindings.set(
ColorType.inputs[0].names,
new NumberValue(this.creator, color.l)
new NumberValue(this.creator, color.l),
);
// Chroma
bindings.set(
ColorType.inputs[1].names,
new NumberValue(this.creator, color.c)
new NumberValue(this.creator, color.c),
);
// Hue
bindings.set(
ColorType.inputs[2].names,
new NumberValue(this.creator, color.h)
new NumberValue(this.creator, color.h),
);
// Convert it to a Color value.
return createStructure(this.evaluator, ColorType, bindings);
})
}),
);

// Add the frame to the stream
Expand Down Expand Up @@ -125,15 +125,15 @@ export default class Camera extends TemporalStreamValue<ListValue, RawFrame> {
0,
0,
this.width,
this.height
this.height,
);
// Read the image
const image = context.getImageData(
0,
0,
this.width,
this.height,
{ colorSpace: 'srgb' }
{ colorSpace: 'srgb' },
);

// Translate the rows into a 2D array of colors
Expand Down Expand Up @@ -173,11 +173,11 @@ export default class Camera extends TemporalStreamValue<ListValue, RawFrame> {

static createFrame(
creator: Expression,
colors: StructureValue[][]
colors: StructureValue[][],
): ListValue {
return new ListValue(
creator,
colors.map((row) => new ListValue(creator, row))
colors.map((row) => new ListValue(creator, row)),
);
}

Expand Down Expand Up @@ -300,34 +300,34 @@ const DEFAULT_HEIGHT = 32;

export function createCameraDefinition(
locales: Locales,
ColorType: StructureDefinition
ColorType: StructureDefinition,
) {
const frameType = ListType.make(
ListType.make(new StructureType(ColorType))
ListType.make(new StructureType(ColorType)),
);

const WidthBind = Bind.make(
getDocLocales(locales, (locale) => locale.input.Camera.width.doc),
getNameLocales(locales, (locale) => locale.input.Camera.width.names),
UnionType.make(NumberType.make(Unit.reuse(['px'])), NoneType.make()),
NumberLiteral.make(DEFAULT_WIDTH, Unit.reuse(['px']))
NumberLiteral.make(DEFAULT_WIDTH, Unit.reuse(['px'])),
);

const HeightBind = Bind.make(
getDocLocales(locales, (locale) => locale.input.Camera.height.doc),
getNameLocales(locales, (locale) => locale.input.Camera.height.names),
UnionType.make(NumberType.make(Unit.reuse(['px'])), NoneType.make()),
NumberLiteral.make(DEFAULT_HEIGHT, Unit.reuse(['px']))
NumberLiteral.make(DEFAULT_HEIGHT, Unit.reuse(['px'])),
);

const FrequencyBind = Bind.make(
getDocLocales(locales, (locale) => locale.input.Camera.frequency.doc),
getNameLocales(
locales,
(locale) => locale.input.Camera.frequency.names
(locale) => locale.input.Camera.frequency.names,
),
UnionType.make(NumberType.make(Unit.reuse(['ms'])), NoneType.make()),
NumberLiteral.make(DEFAULT_FREQUENCY, Unit.reuse(['ms']))
NumberLiteral.make(DEFAULT_FREQUENCY, Unit.reuse(['ms'])),
);

return StreamDefinition.make(
Expand All @@ -339,14 +339,14 @@ export function createCameraDefinition(
Camera,
(evaluation) =>
new Camera(
evaluation.getEvaluator(),
evaluation,
evaluation.get(WidthBind.names, NumberValue)?.toNumber() ??
DEFAULT_FREQUENCY,
evaluation.get(HeightBind.names, NumberValue)?.toNumber() ??
DEFAULT_WIDTH,
evaluation
.get(FrequencyBind.names, NumberValue)
?.toNumber() ?? DEFAULT_HEIGHT
?.toNumber() ?? DEFAULT_HEIGHT,
),
(stream, evaluation) => {
stream.frequency =
Expand All @@ -359,8 +359,8 @@ export function createCameraDefinition(
evaluation
.get(FrequencyBind.names, NumberValue)
?.toNumber() ?? DEFAULT_FREQUENCY;
}
},
),
frameType.clone()
frameType.clone(),
);
}
18 changes: 9 additions & 9 deletions src/input/Chat.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import StreamValue from '@values/StreamValue';
import type Evaluator from '@runtime/Evaluator';
import StreamDefinition from '../nodes/StreamDefinition';
import { getDocLocales } from '../locale/getDocLocales';
import { getNameLocales } from '../locale/getNameLocales';
Expand All @@ -8,14 +7,15 @@ import TextValue from '../values/TextValue';
import StreamType from '../nodes/StreamType';
import createStreamEvaluator from './createStreamEvaluator';
import type Locales from '../locale/Locales';
import type Evaluation from '@runtime/Evaluation';

export default class Chat extends StreamValue<TextValue, string> {
constructor(evaluator: Evaluator) {
constructor(evaluation: Evaluation) {
super(
evaluator,
evaluator.project.shares.input.Chat,
new TextValue(evaluator.getMain(), ''),
''
evaluation,
evaluation.getEvaluator().project.shares.input.Chat,
new TextValue(evaluation.getCreator(), ''),
'',
);
}

Expand Down Expand Up @@ -48,9 +48,9 @@ export function createChatDefinition(locales: Locales) {
createStreamEvaluator(
TextType.make(),
Chat,
(evaluation) => new Chat(evaluation.getEvaluator()),
(stream) => stream.configure()
(evaluation) => new Chat(evaluation),
(stream) => stream.configure(),
),
TextType.make()
TextType.make(),
);
}
21 changes: 11 additions & 10 deletions src/input/Choice.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import StreamValue from '@values/StreamValue';
import type Evaluator from '@runtime/Evaluator';
import StreamDefinition from '../nodes/StreamDefinition';
import { getDocLocales } from '../locale/getDocLocales';
import { getNameLocales } from '../locale/getNameLocales';
Expand All @@ -8,22 +7,24 @@ import TextValue from '../values/TextValue';
import StreamType from '../nodes/StreamType';
import createStreamEvaluator from './createStreamEvaluator';
import type Locales from '../locale/Locales';
import type Evaluation from '@runtime/Evaluation';
import type Evaluator from '@runtime/Evaluator';

/** A series of selected output, chosen by mouse or keyboard, allowing for programs that work for both mouse and keyboard. */
export default class Choice extends StreamValue<TextValue, string> {
readonly evaluator: Evaluator;

on = true;

constructor(evaluator: Evaluator) {
constructor(evaluation: Evaluation) {
super(
evaluator,
evaluator.project.shares.input.Choice,
new TextValue(evaluator.getMain(), ''),
''
evaluation,
evaluation.getEvaluator().project.shares.input.Choice,
new TextValue(evaluation.getCreator(), ''),
'',
);

this.evaluator = evaluator;
this.evaluator = evaluation.getEvaluator();
}

configure() {
Expand Down Expand Up @@ -56,9 +57,9 @@ export function createChoiceDefinition(locales: Locales) {
createStreamEvaluator(
TextType.make(),
Choice,
(evaluation) => new Choice(evaluation.getEvaluator()),
(stream) => stream.configure()
(evaluation) => new Choice(evaluation),
(stream) => stream.configure(),
),
TextType.make()
TextType.make(),
);
}
Loading

0 comments on commit 235b0a6

Please sign in to comment.