|
|
|
|
@ -3,6 +3,7 @@ import { valueToUI } from './valueToUI';
|
|
|
|
|
import { render, hitTest } from './ui';
|
|
|
|
|
import { evaluate } from './interpreter';
|
|
|
|
|
import { CGError } from './error';
|
|
|
|
|
import type { Env } from './env';
|
|
|
|
|
|
|
|
|
|
export type App = {
|
|
|
|
|
init: Value;
|
|
|
|
|
@ -10,7 +11,7 @@ export type App = {
|
|
|
|
|
view: Value; // State / UI
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function runApp(app: App, canvas: HTMLCanvasElement, source: string) {
|
|
|
|
|
export function runApp(app: App, canvas: HTMLCanvasElement, source: string, env: Env) {
|
|
|
|
|
let state = app.init;
|
|
|
|
|
|
|
|
|
|
type ComponentInstance = {
|
|
|
|
|
@ -221,23 +222,11 @@ export function runApp(app: App, canvas: HTMLCanvasElement, source: string) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event.kind === 'constructor' && event.name === 'Update') {
|
|
|
|
|
if (event.args.length === 2) {
|
|
|
|
|
const ref = event.args[0];
|
|
|
|
|
const transformFn = event.args[1];
|
|
|
|
|
|
|
|
|
|
if (ref.kind !== 'ref')
|
|
|
|
|
throw new Error('Update event expects a Ref')
|
|
|
|
|
|
|
|
|
|
if (transformFn.kind !== 'closure')
|
|
|
|
|
throw new Error('Update event expects a Ref')
|
|
|
|
|
|
|
|
|
|
const callEnv = new Map(transformFn.env);
|
|
|
|
|
callEnv.set(transformFn.params[0], ref.value);
|
|
|
|
|
const newValue = evaluate(transformFn.body, callEnv, source);
|
|
|
|
|
|
|
|
|
|
ref.value = newValue;
|
|
|
|
|
|
|
|
|
|
if (event.kind === 'constructor' && event.name === 'Rebind') {
|
|
|
|
|
if (event.args.length === 2 && event.args[0].kind === 'string') {
|
|
|
|
|
const name = event.args[0].value;
|
|
|
|
|
const value = event.args[1];
|
|
|
|
|
env.set(name, value);
|
|
|
|
|
rerender();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -275,7 +264,7 @@ export function runApp(app: App, canvas: HTMLCanvasElement, source: string) {
|
|
|
|
|
if (hitResult) {
|
|
|
|
|
const { event, relativeX, relativeY } = hitResult;
|
|
|
|
|
|
|
|
|
|
if (event.kind === 'constructor' && (event.name === 'Focus' || event.name === 'Update')) {
|
|
|
|
|
if (event.kind === 'constructor' && (event.name === 'Focus' || event.name === 'Rebind')) {
|
|
|
|
|
handleEvent(event);
|
|
|
|
|
} else if (event.kind === 'constructor' && event.name === 'FocusAndClick') {
|
|
|
|
|
const eventWithCoords: Value = {
|
|
|
|
|
|