Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Commit

Permalink
feat(func-x): allow separate properties for relative functions (for p…
Browse files Browse the repository at this point in the history
…erformance reasons)
  • Loading branch information
basvanmeurs committed Apr 24, 2020
1 parent 74aedbd commit 0f47dcd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 30 deletions.
65 changes: 40 additions & 25 deletions src/runtime/nodes/Node.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Base } from "./Base";
import { Element, FunctionH, FunctionW, FunctionX, FunctionY } from "tree2d";
import { Element, RelativeFunction } from "tree2d";
import {
eventTranslators,
SupportedEvents,
Expand All @@ -16,7 +16,7 @@ import {
ElementTextureErrorEventCallback,
} from "tree2d";
import { VugelStage } from "../../wrapper";
import { ensureBoolean, ensureColor, ensureFloat, isString, parseFloatStrict } from "../utils/TypeUtils";
import { ensureBoolean, ensureColor, ensureFloat, isString } from "../utils/TypeUtils";

export type NodeEvents = {
onAuxclick?: VugelEventListener<VugelMouseEvent>;
Expand Down Expand Up @@ -141,20 +141,36 @@ export class Node extends Base {
return this.el.core.convertWorldCoordsToLocal(worldX, worldY);
}

set x(v: number | FunctionX | string) {
this.el.x = convertRelValue(v, "w");
set x(v: number) {
this.el.x = ensureFloat(v);
}

set y(v: number | FunctionY | string) {
this.el.y = convertRelValue(v, "h");
set "func-x"(v: RelativeFunction | string | undefined) {
this.el.funcX = ensureRelativeFunction(v);
}

set w(v: number | FunctionW | string) {
this.el.w = convertRelValue(v, "w");
set y(v: number) {
this.el.y = v;
}

set h(v: number | FunctionH) {
this.el.h = convertRelValue(v, "h");
set "func-y"(v: RelativeFunction | string | undefined) {
this.el.funcY = ensureRelativeFunction(v);
}

set w(v: number) {
this.el.w = v;
}

set "func-w"(v: RelativeFunction | string | undefined) {
this.el.funcW = ensureRelativeFunction(v);
}

set h(v: number) {
this.el.h = v;
}

set "func-h"(v: RelativeFunction | string | undefined) {
this.el.funcH = ensureRelativeFunction(v);
}

set "scale-x"(v: number) {
Expand Down Expand Up @@ -512,24 +528,23 @@ export class Node extends Base {
}
}

export function convertRelValue(v: number | RelFunction | string, argName: string) {
function ensureRelativeFunction(v: RelativeFunction | string | undefined) {
if (isString(v)) {
const floatValue = parseFloatStrict(v);
if (isNaN(floatValue)) {
// Convert to function.
return convertToRelFunction(v, argName);
} else {
return floatValue;
}
// Convert to function.
return convertRelativeFunction(v);
} else {
return isFunction(v) ? v : ensureFloat(v);
return v;
}
}

export function convertToRelFunction(body: string, argName: string): RelFunction {
return new Function(argName, `return ${body}`) as RelFunction;
// We hold a cache because string-based vue properties will otherwise result in a new relative function on every vnode
// update, with performance implications.
const cachedRelFunctions = new Map<string, RelativeFunction>();
function convertRelativeFunction(body: string): RelativeFunction {
let fn = cachedRelFunctions.get(body);
if (!fn) {
fn = new Function("w", "h", `return ${body}`) as RelativeFunction;
cachedRelFunctions.set(body, fn);
}
return fn;
}

type RelFunction = (v: number) => number;

const isFunction = (val: unknown): val is Function => typeof val === "function";
2 changes: 1 addition & 1 deletion src/runtime/nodes/Paragraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Paragraph extends Node {
const el = new Element(this.stage);
if (word === Paragraph.newlinePattern) {
// Force line break.
el.w = (w: number) => w;
el.funcW = (w: number) => w;
el.h = 0;
} else {
const texture = new TextTexture(this.stage);
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/nodes/textures/DynamicSizeTexture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export abstract class DynamicSizeTexture extends Container {
this.background.skipInLayout = true;

this.wrapper.skipInLayout = true;
this.wrapper.w = (w: number) => w;
this.wrapper.h = (h: number) => h;
this.wrapper.funcW = (w: number) => w;
this.wrapper.funcH = (w: number, h: number) => h;
this.containerElement = this.wrapper;

this.wrapper.onResize = ({ element, w, h }) => this.handleResize(element, w, h);
Expand Down
4 changes: 2 additions & 2 deletions src/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export const Vugel: {
stageRoot = new Root(stage, stage.root);

// Auto-inherit dimensions.
stageRoot.w = (w: number) => w;
stageRoot.h = (h: number) => h;
stageRoot["func-w"] = (w: number) => w;
stageRoot["func-h"] = (w: number, h: number) => h;
}

const defaultSlot = setupContext.slots.default;
Expand Down

0 comments on commit 0f47dcd

Please sign in to comment.