Skip to content

Commit

Permalink
Merge pull request #1090 from glimmerjs/feat/adds-cache-api
Browse files Browse the repository at this point in the history
[FEATURE] Adds `cache` api
  • Loading branch information
rwjblue authored May 13, 2020
2 parents 140af2a + 790508c commit e8e2fc6
Show file tree
Hide file tree
Showing 11 changed files with 389 additions and 137 deletions.
4 changes: 2 additions & 2 deletions packages/@glimmer/integration-tests/lib/render-test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Dict, Maybe, Option, RenderResult, Helper } from '@glimmer/interfaces';
import { ASTPluginBuilder } from '@glimmer/syntax';
import { bump, isConst } from '@glimmer/validator';
import { bump, isConstTagged } from '@glimmer/validator';
import { clearElement, dict, expect, assign } from '@glimmer/util';
import { SimpleElement, SimpleNode } from '@simple-dom/interface';
import {
Expand Down Expand Up @@ -393,7 +393,7 @@ export class RenderTest implements IRenderTest {

let self = this.delegate.getSelf(this.context);

if (!isConst(self)) {
if (!isConstTagged(self)) {
(self as UpdatableRootReference).forceUpdate(this.context);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/@glimmer/reference/lib/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
updateTag,
track,
Revision,
isConst,
isConstTagged,
isConstTag,
valueForTag,
validateTag,
Expand Down Expand Up @@ -150,7 +150,7 @@ export class HelperRootReference<T = unknown> extends RootReference<T> {
this.didSetupDebugContext = true;
}

if (isConst(args)) {
if (isConstTagged(args)) {
this.compute();
}

Expand Down
4 changes: 2 additions & 2 deletions packages/@glimmer/runtime/lib/compiled/opcodes/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
ModifierManager,
} from '@glimmer/interfaces';
import { VersionedPathReference, VersionedReference } from '@glimmer/reference';
import { CONSTANT_TAG, isConst, isConstTag, Tag } from '@glimmer/validator';
import { CONSTANT_TAG, isConstTagged, isConstTag, Tag } from '@glimmer/validator';
import {
assert,
dict,
Expand Down Expand Up @@ -538,7 +538,7 @@ function setDeferredAttr(
vm.elements().setStaticAttribute(name, value, namespace);
} else {
let attribute = vm.elements().setDynamicAttribute(name, value.value(), trusting, namespace);
if (!isConst(value)) {
if (!isConstTagged(value)) {
vm.updateWith(new UpdateDynamicAttributeOpcode(value, attribute));
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/@glimmer/runtime/lib/compiled/opcodes/content.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Reference } from '@glimmer/reference';
import { Tag, isConst } from '@glimmer/validator';
import { Tag, isConstTagged } from '@glimmer/validator';
import {
check,
CheckString,
Expand Down Expand Up @@ -77,7 +77,7 @@ APPEND_OPCODES.add(Op.AppendText, vm => {

let node = vm.elements().appendDynamicText(value);

if (!isConst(reference)) {
if (!isConstTagged(reference)) {
vm.updateWith(new DynamicTextContent(node, reference, value));
}
});
Expand Down
15 changes: 11 additions & 4 deletions packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { Reference, ReferenceCache, VersionedReference } from '@glimmer/reference';
import { Revision, Tag, isConst, isConstTag, valueForTag, validateTag } from '@glimmer/validator';
import {
Revision,
Tag,
isConstTagged,
isConstTag,
valueForTag,
validateTag,
} from '@glimmer/validator';
import { check, CheckString, CheckElement, CheckOption, CheckNode } from '@glimmer/debug';
import { Op, Option, ModifierManager } from '@glimmer/interfaces';
import { $t0 } from '@glimmer/vm';
Expand Down Expand Up @@ -43,7 +50,7 @@ APPEND_OPCODES.add(Op.PushRemoteElement, vm => {
let insertBefore: Maybe<SimpleNode>;
let guid = guidRef.value() as string;

if (isConst(elementRef)) {
if (isConstTagged(elementRef)) {
element = check(elementRef.value(), CheckElement);
} else {
let cache = new ReferenceCache(elementRef as Reference<SimpleElement>);
Expand All @@ -52,7 +59,7 @@ APPEND_OPCODES.add(Op.PushRemoteElement, vm => {
}

if (insertBeforeRef.value() !== undefined) {
if (isConst(insertBeforeRef)) {
if (isConstTagged(insertBeforeRef)) {
insertBefore = check(insertBeforeRef.value(), CheckOption(CheckNode));
} else {
let cache = new ReferenceCache(insertBeforeRef as Reference<Option<SimpleNode>>);
Expand Down Expand Up @@ -163,7 +170,7 @@ APPEND_OPCODES.add(Op.DynamicAttr, (vm, { op1: _name, op2: trusting, op3: _names

let attribute = vm.elements().setDynamicAttribute(name, value, !!trusting, namespace);

if (!isConst(reference)) {
if (!isConstTagged(reference)) {
vm.updateWith(new UpdateDynamicAttributeOpcode(reference, attribute));
}
});
Expand Down
15 changes: 11 additions & 4 deletions packages/@glimmer/runtime/lib/compiled/opcodes/vm.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { CompilableTemplate, Option, Op } from '@glimmer/interfaces';
import { isModified, ReferenceCache } from '@glimmer/reference';
import { CONSTANT_TAG, isConst, Revision, Tag, valueForTag, validateTag } from '@glimmer/validator';
import {
CONSTANT_TAG,
isConstTagged,
Revision,
Tag,
valueForTag,
validateTag,
} from '@glimmer/validator';
import { initializeGuid, assert, isHandle, HandleConstants, decodeHandle } from '@glimmer/util';
import {
CheckNumber,
Expand Down Expand Up @@ -160,7 +167,7 @@ APPEND_OPCODES.add(Op.InvokeYield, vm => {
APPEND_OPCODES.add(Op.JumpIf, (vm, { op1: target }) => {
let reference = check(vm.stack.pop(), CheckReference);

if (isConst(reference)) {
if (isConstTagged(reference)) {
if (reference.value()) {
vm.goto(target);
}
Expand All @@ -178,7 +185,7 @@ APPEND_OPCODES.add(Op.JumpIf, (vm, { op1: target }) => {
APPEND_OPCODES.add(Op.JumpUnless, (vm, { op1: target }) => {
let reference = check(vm.stack.pop(), CheckReference);

if (isConst(reference)) {
if (isConstTagged(reference)) {
if (!reference.value()) {
vm.goto(target);
}
Expand All @@ -204,7 +211,7 @@ APPEND_OPCODES.add(Op.JumpEq, (vm, { op1: target, op2: comparison }) => {
APPEND_OPCODES.add(Op.AssertSame, vm => {
let reference = check(vm.stack.peek(), CheckReference);

if (!isConst(reference)) {
if (!isConstTagged(reference)) {
vm.updateWith(Assert.initialize(new ReferenceCache(reference)));
}
});
Expand Down
9 changes: 7 additions & 2 deletions packages/@glimmer/validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export {
EntityTag,
EntityTagged,
INITIAL,
isConst,
isConstTagged,
isConstTag,
Revision,
Tag,
Expand All @@ -39,12 +39,17 @@ export {
consumeTag,
isTracking,
track,
trackedData,
memo,
untrack,
isConstMemo,
Cache,
createCache,
isConst,
getValue,
} from './lib/tracking';

export { trackedData } from './lib/tracked-data';

export {
setAutotrackingTransactionEnv,
runInAutotrackingTransaction,
Expand Down
42 changes: 42 additions & 0 deletions packages/@glimmer/validator/lib/tracked-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { DEBUG } from '@glimmer/env';
import { tagFor, dirtyTagFor } from './meta';
import { assertTagNotConsumed } from './debug';
import { consumeTag } from './tracking';

export type Getter<T, K extends keyof T> = (self: T) => T[K] | undefined;
export type Setter<T, K extends keyof T> = (self: T, value: T[K]) => void;

export function trackedData<T extends object, K extends keyof T>(
key: K,
initializer?: (this: T) => T[K]
): { getter: Getter<T, K>; setter: Setter<T, K> } {
let values = new WeakMap<T, T[K]>();
let hasInitializer = typeof initializer === 'function';

function getter(self: T) {
consumeTag(tagFor(self, key));

let value;

// If the field has never been initialized, we should initialize it
if (hasInitializer && !values.has(self)) {
value = initializer!.call(self);
values.set(self, value);
} else {
value = values.get(self);
}

return value;
}

function setter(self: T, value: T[K]): void {
if (DEBUG) {
assertTagNotConsumed!(tagFor(self, key), self, key, true);
}

dirtyTagFor(self, key);
values.set(self, value);
}

return { getter, setter };
}
Loading

0 comments on commit e8e2fc6

Please sign in to comment.