import { IMAGES, SPRITE_SPECS, SpriteSpec, Sprites } from "../config"; import { Entity, EntityNames } from "."; import { BoundingBox, ComponentNames, Grid, Highlight, Interactable, LambdaTerm, Modal, Pushable, Sprite, } from "../components"; import { Coord2D } from "../interfaces"; export class FunctionBox extends Entity { private static spriteSpec: SpriteSpec = SPRITE_SPECS.get( Sprites.FUNCTION_BOX ) as SpriteSpec; constructor( gridPosition: Coord2D, private readonly code: string ) { super(EntityNames.FunctionBox); this.addComponent( new BoundingBox( { x: 0, y: 0, }, { width: FunctionBox.spriteSpec.width, height: FunctionBox.spriteSpec.height, }, 0 ) ); this.addComponent(new Pushable()); this.addComponent(new Grid(gridPosition)); this.addComponent( new Sprite( IMAGES.get(FunctionBox.spriteSpec.sheet)!, { x: 0, y: 0 }, { width: FunctionBox.spriteSpec.width, height: FunctionBox.spriteSpec.height, }, FunctionBox.spriteSpec.msPerFrame, FunctionBox.spriteSpec.frames ) ); this.addComponent(new LambdaTerm(code)); this.addComponent( new Highlight(this.onHighlight.bind(this), this.onUnhighlight.bind(this)) ); } private interaction() { const codeConsumer = (_code: string) => { this.removeComponent(ComponentNames.Modal); return { consumed: true }; }; const { last } = this.getComponent(ComponentNames.LambdaTerm); this.addComponent( new Modal({ type: "CODE_EDITOR", codeInit: { code: this.code, codeConsumer, readonly: true, result: { error: last?.error && `Error: ${last.error.message}`, }, }, }) ); } public onHighlight() { this.addComponent(new Interactable(this.interaction.bind(this))); } public onUnhighlight() { this.removeComponent(ComponentNames.Interactable); } }