Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REFACTOR] Converts VM to use tracking internally #19093

Merged
merged 1 commit into from
Aug 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@
},
"devDependencies": {
"@babel/preset-env": "^7.9.5",
"@glimmer/compiler": "^0.56.1",
"@glimmer/compiler": "^0.57.2",
"@glimmer/env": "^0.1.7",
"@glimmer/interfaces": "^0.56.1",
"@glimmer/node": "^0.56.1",
"@glimmer/opcode-compiler": "^0.56.1",
"@glimmer/program": "^0.56.1",
"@glimmer/reference": "^0.56.1",
"@glimmer/runtime": "^0.56.1",
"@glimmer/validator": "^0.56.1",
"@glimmer/interfaces": "^0.57.2",
"@glimmer/node": "^0.57.2",
"@glimmer/opcode-compiler": "^0.57.2",
"@glimmer/program": "^0.57.2",
"@glimmer/reference": "^0.57.2",
"@glimmer/runtime": "^0.57.2",
"@glimmer/validator": "^0.57.2",
"@simple-dom/document": "^1.4.0",
"@types/qunit": "^2.9.1",
"@types/rsvp": "^4.0.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import {
PreparedArguments,
VMArguments,
} from '@glimmer/interfaces';
import { VersionedPathReference } from '@glimmer/reference';
import { Tag } from '@glimmer/validator';
import { PathReference } from '@glimmer/reference';
import { SimpleElement } from '@simple-dom/interface';
import { EmberVMEnvironment } from '../environment';

Expand All @@ -23,16 +22,18 @@ export default abstract class AbstractManager<T, U> implements ComponentManager<
return null;
}

abstract getDebugName(state: U): string;

abstract create(
env: EmberVMEnvironment,
definition: U,
args: VMArguments,
dynamicScope: DynamicScope,
caller: VersionedPathReference<void | {}>,
caller: PathReference<void | {}>,
hasDefaultBlock: boolean
): T;

abstract getSelf(component: T): VersionedPathReference<unknown>;
abstract getSelf(component: T): PathReference<unknown>;
abstract getCapabilities(state: U): ComponentCapabilities;

didCreateElement(_component: T, _element: SimpleElement, _operations: ElementOperations): void {
Expand All @@ -47,8 +48,6 @@ export default abstract class AbstractManager<T, U> implements ComponentManager<
// noop
}

abstract getTag(_bucket: T): Tag;

update(_bucket: T, _dynamicScope: DynamicScope): void {
// noop
}
Expand Down
65 changes: 46 additions & 19 deletions packages/@ember/-internals/glimmer/lib/component-managers/curly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,18 @@ import {
WithJitDynamicLayout,
WithJitStaticLayout,
} from '@glimmer/interfaces';
import { RootReference, VersionedPathReference } from '@glimmer/reference';
import { PathReference, RootReference } from '@glimmer/reference';
import { PrimitiveReference, registerDestructor } from '@glimmer/runtime';
import { EMPTY_ARRAY, unwrapTemplate } from '@glimmer/util';
import { combine, Tag, validateTag, valueForTag } from '@glimmer/validator';
import {
beginTrackFrame,
beginUntrackFrame,
consumeTag,
endTrackFrame,
endUntrackFrame,
validateTag,
valueForTag,
} from '@glimmer/validator';
import { SimpleElement } from '@simple-dom/interface';
import { BOUNDS, DIRTY_TAG, HAS_BLOCK, IS_DISPATCHING_ATTRS } from '../component';
import { EmberVMEnvironment } from '../environment';
Expand Down Expand Up @@ -62,8 +70,7 @@ function applyAttributeBindings(
attributeBindings: Array<string>,
component: Component,
rootRef: RootReference<Component>,
operations: ElementOperations,
environment: EmberVMEnvironment
operations: ElementOperations
) {
let seen: string[] = [];
let i = attributeBindings.length - 1;
Expand All @@ -75,7 +82,7 @@ function applyAttributeBindings(

if (seen.indexOf(attribute) === -1) {
seen.push(attribute);
AttributeBinding.install(component, rootRef, parsed, operations, environment);
AttributeBinding.install(component, rootRef, parsed, operations);
}

i--;
Expand All @@ -91,12 +98,12 @@ function applyAttributeBindings(
installIsVisibleBinding !== undefined &&
seen.indexOf('style') === -1
) {
installIsVisibleBinding(rootRef, operations, environment);
installIsVisibleBinding(rootRef, operations);
}
}

const DEFAULT_LAYOUT = P`template:components/-default`;
const EMPTY_POSITIONAL_ARGS: VersionedPathReference[] = [];
const EMPTY_POSITIONAL_ARGS: PathReference[] = [];

debugFreeze(EMPTY_POSITIONAL_ARGS);

Expand Down Expand Up @@ -167,7 +174,7 @@ export default class CurlyComponentManager
positional: EMPTY_POSITIONAL_ARGS,
named: {
...rest,
...(__ARGS__.value() as { [key: string]: VersionedPathReference<unknown> }),
...(__ARGS__.value() as { [key: string]: PathReference<unknown> }),
},
};

Expand Down Expand Up @@ -227,7 +234,7 @@ export default class CurlyComponentManager
state: DefinitionState,
args: VMArguments,
dynamicScope: DynamicScope,
callerSelfRef: VersionedPathReference,
callerSelfRef: PathReference,
hasBlock: boolean
): ComponentStateBucket {
// Get the nearest concrete component instance from the scope. "Virtual"
Expand All @@ -240,7 +247,10 @@ export default class CurlyComponentManager
// Capture the arguments, which tells Glimmer to give us our own, stable
// copy of the Arguments object that is safe to hold on to between renders.
let capturedArgs = args.named.capture();

beginTrackFrame();
let props = processComponentArgs(capturedArgs);
let argsTag = endTrackFrame();

// Alias `id` argument to `elementId` property on the component instance.
aliasIdToElementId(args, props);
Expand Down Expand Up @@ -271,6 +281,7 @@ export default class CurlyComponentManager

// Now that we've built up all of the properties to set on the component instance,
// actually create it.
beginUntrackFrame();
let component = factory.create(props);

let finalizer = _instrumentStart('render.component', initialRenderInstrumentDetails, component);
Expand Down Expand Up @@ -308,6 +319,7 @@ export default class CurlyComponentManager
environment,
component,
capturedArgs,
argsTag,
finalizer,
hasWrappedElement
);
Expand All @@ -324,6 +336,8 @@ export default class CurlyComponentManager
component.trigger('willRender');
}

endUntrackFrame();

if (ENV._DEBUG_RENDER_TREE) {
environment.extra.debugRenderTree.create(bucket, {
type: 'component',
Expand All @@ -338,10 +352,18 @@ export default class CurlyComponentManager
});
}

// consume every argument so we always run again
consumeTag(bucket.argsTag);
consumeTag(component[DIRTY_TAG]);

return bucket;
}

getSelf({ rootRef }: ComponentStateBucket): VersionedPathReference {
getDebugName({ name }: DefinitionState) {
return name;
}

getSelf({ rootRef }: ComponentStateBucket): PathReference {
return rootRef;
}

Expand All @@ -356,12 +378,12 @@ export default class CurlyComponentManager
let { attributeBindings, classNames, classNameBindings } = component;

if (attributeBindings && attributeBindings.length) {
applyAttributeBindings(attributeBindings, component, rootRef, operations, environment);
applyAttributeBindings(attributeBindings, component, rootRef, operations);
} else {
let id = component.elementId ? component.elementId : guidFor(component);
operations.setAttribute('id', PrimitiveReference.create(id), false, null);
if (EMBER_COMPONENT_IS_VISIBLE) {
installIsVisibleBinding!(rootRef, operations, environment);
installIsVisibleBinding!(rootRef, operations);
}
}

Expand Down Expand Up @@ -403,10 +425,6 @@ export default class CurlyComponentManager
}
}

getTag({ args, component }: ComponentStateBucket): Tag {
return args ? combine([args.tag, component[DIRTY_TAG]]) : component[DIRTY_TAG];
}

didCreate({ component, environment }: ComponentStateBucket): void {
if (environment.isInteractive) {
component._transitionTo('inDOM');
Expand All @@ -416,18 +434,22 @@ export default class CurlyComponentManager
}

update(bucket: ComponentStateBucket): void {
let { component, args, argsRevision, environment } = bucket;
let { component, args, argsTag, argsRevision, environment } = bucket;

if (ENV._DEBUG_RENDER_TREE) {
environment.extra.debugRenderTree.update(bucket);
}

bucket.finalizer = _instrumentStart('render.component', rerenderInstrumentDetails, component);

if (args && !validateTag(args.tag, argsRevision)) {
beginUntrackFrame();

if (args !== null && !validateTag(argsTag, argsRevision)) {
beginTrackFrame();
let props = processComponentArgs(args!);
argsTag = bucket.argsTag = endTrackFrame();

bucket.argsRevision = valueForTag(args!.tag);
bucket.argsRevision = valueForTag(argsTag);

component[IS_DISPATCHING_ATTRS] = true;
component.setProperties(props);
Expand All @@ -441,6 +463,11 @@ export default class CurlyComponentManager
component.trigger('willUpdate');
component.trigger('willRender');
}

endUntrackFrame();

consumeTag(argsTag);
consumeTag(component[DIRTY_TAG]);
}

didUpdateLayout(bucket: ComponentStateBucket, bounds: Bounds): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
import { ComponentRootReference, PathReference } from '@glimmer/reference';
import { registerDestructor } from '@glimmer/runtime';
import { unwrapTemplate } from '@glimmer/util';
import { consumeTag, createTag, isConstTagged, Tag } from '@glimmer/validator';
import { track } from '@glimmer/validator';
import { EmberVMEnvironment } from '../environment';
import RuntimeResolver from '../resolver';
import { OwnedTemplate } from '../template';
Expand Down Expand Up @@ -194,17 +194,14 @@ export default class CustomComponentManager<ComponentInstance>

if (EMBER_CUSTOM_COMPONENT_ARG_PROXY) {
let getTag = (key: string) => {
return namedArgs.get(key).tag;
return track(() => namedArgs.get(key).value());
};

if (HAS_NATIVE_PROXY) {
let handler: ProxyHandler<{}> = {
get(_target, prop) {
if (namedArgs.has(prop as string)) {
let ref = namedArgs.get(prop as string);
consumeTag(ref.tag);

return ref.value();
return namedArgs.get(prop as string).value();
} else if (prop === CUSTOM_TAG_FOR) {
return getTag;
}
Expand Down Expand Up @@ -256,10 +253,7 @@ export default class CustomComponentManager<ComponentInstance>
enumerable: true,
configurable: true,
get() {
let ref = namedArgs.get(name);
consumeTag(ref.tag);

return ref.value();
return namedArgs.get(name).value();
},
});
});
Expand Down Expand Up @@ -294,6 +288,10 @@ export default class CustomComponentManager<ComponentInstance>
return bucket;
}

getDebugName({ name }: CustomComponentDefinitionState<ComponentInstance>) {
return name;
}

update(bucket: CustomComponentState<ComponentInstance>) {
if (ENV._DEBUG_RENDER_TREE) {
bucket.env.extra.debugRenderTree.update(bucket);
Expand Down Expand Up @@ -353,15 +351,6 @@ export default class CustomComponentManager<ComponentInstance>
});
}

getTag({ args }: CustomComponentState<ComponentInstance>): Tag {
if (isConstTagged(args)) {
// returning a const tag skips the update hook (VM BUG?)
return createTag();
} else {
return args.tag;
}
}

didRenderLayout(bucket: CustomComponentState<ComponentInstance>, bounds: Bounds) {
if (ENV._DEBUG_RENDER_TREE) {
bucket.env.extra.debugRenderTree.didRender(bucket, bounds);
Expand Down
27 changes: 10 additions & 17 deletions packages/@ember/-internals/glimmer/lib/component-managers/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import {
PreparedArguments,
VMArguments,
} from '@glimmer/interfaces';
import { ComponentRootReference, ConstReference, VersionedPathReference } from '@glimmer/reference';
import { ComponentRootReference, ConstReference, PathReference } from '@glimmer/reference';
import { registerDestructor } from '@glimmer/runtime';
import { CONSTANT_TAG, createTag, isConstTagged } from '@glimmer/validator';
import { EmberVMEnvironment } from '../environment';
import InternalComponentManager, { InternalDefinitionState } from './internal';

Expand All @@ -34,11 +33,11 @@ const CAPABILITIES: ComponentCapabilities = {

export interface InputComponentState {
env: EmberVMEnvironment;
type: VersionedPathReference;
type: PathReference;
instance: Destroyable;
}

const EMPTY_POSITIONAL_ARGS: VersionedPathReference[] = [];
const EMPTY_POSITIONAL_ARGS: PathReference[] = [];

debugFreeze(EMPTY_POSITIONAL_ARGS);

Expand All @@ -53,7 +52,7 @@ export default class InputComponentManager extends InternalComponentManager<Inpu
args.positional.length === 0
);

let __ARGS__: Dict<VersionedPathReference> = args.named.capture().map;
let __ARGS__: Dict<PathReference> = args.named.capture().map;

return {
positional: EMPTY_POSITIONAL_ARGS,
Expand All @@ -69,9 +68,9 @@ export default class InputComponentManager extends InternalComponentManager<Inpu
{ ComponentClass, layout }: InternalDefinitionState,
args: VMArguments,
_dynamicScope: DynamicScope,
caller: VersionedPathReference
caller: PathReference
): InputComponentState {
assert('caller must be const', isConstTagged(caller));
assert('caller must be const', caller.isConst());

let type = args.named.get('type');

Expand All @@ -97,18 +96,12 @@ export default class InputComponentManager extends InternalComponentManager<Inpu
return state;
}

getSelf({ env, instance }: InputComponentState): VersionedPathReference {
return new ComponentRootReference(instance, env);
getDebugName() {
return 'input';
}

getTag() {
if (ENV._DEBUG_RENDER_TREE) {
// returning a const tag skips the update hook (VM BUG?)
return createTag();
} else {
// an outlet has no hooks
return CONSTANT_TAG;
}
getSelf({ env, instance }: InputComponentState): PathReference {
return new ComponentRootReference(instance, env);
}

didRenderLayout(state: InputComponentState, bounds: Bounds): void {
Expand Down
Loading