@zcomponent/core 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,7 @@ export class ActionBehavior extends Behavior {
24
24
  }
25
25
  };
26
26
  const env = contextManager.get(EnvironmentContext);
27
- this.register(env.editTime, this._updateRegistration);
28
- this.register(this.enabledResolved, this._updateRegistration);
27
+ this.register(env.editTime, this._updateRegistration, { bindWhenDisabled: true });
28
+ this.register(this.enabledResolved, this._updateRegistration, { bindWhenDisabled: true });
29
29
  }
30
30
  }
package/lib/behavior.d.ts CHANGED
@@ -7,7 +7,6 @@ export type BehaviorConstructorProps = {
7
7
  [id: string]: unknown;
8
8
  };
9
9
  export declare class Behavior<InstanceType extends Component = Component> extends Entity {
10
- protected readonly contextManager: ContextManager;
11
10
  readonly instance: InstanceType;
12
11
  /**
13
12
  * Constructs this behavior
package/lib/behavior.js CHANGED
@@ -7,8 +7,7 @@ export class Behavior extends Entity {
7
7
  * @param instance The instance of the component that this behavior is attached to
8
8
  */
9
9
  constructor(contextManager, instance) {
10
- super();
11
- this.contextManager = contextManager;
10
+ super(contextManager);
12
11
  this.instance = instance;
13
12
  this._updateEnabledResolved = () => {
14
13
  let newValue = this.enabled.value;
@@ -7,7 +7,7 @@ export type ConstructorForComponent<ComponentType extends Component = Component>
7
7
  export type ComponentChild<ComponentType extends Component> = [ConstructorForComponent<ComponentType>, ComponentType extends Component<any, infer U> ? U : never] | [
8
8
  ConstructorForComponent<ComponentType>,
9
9
  ComponentType extends Component<any, infer U> ? U : never,
10
- Observable<ComponentType>
10
+ Observable<ComponentType | undefined>
11
11
  ];
12
12
  export type ComponentChildren = ComponentChild<Component>[];
13
13
  export interface ConstructorProps {
@@ -15,7 +15,6 @@ export interface ConstructorProps {
15
15
  children?: ComponentChildren;
16
16
  }
17
17
  export declare class Component<ElementType = any, ConstructorPropsType extends ConstructorProps = ConstructorProps> extends Entity {
18
- readonly contextManager: ContextManager;
19
18
  protected constructorProps?: ConstructorPropsType | undefined;
20
19
  /**
21
20
  * The raw element(s) that this component exposes
package/lib/component.js CHANGED
@@ -3,8 +3,7 @@ import { Entity } from './entity';
3
3
  import { Observable } from './observable';
4
4
  export class Component extends Entity {
5
5
  constructor(contextManager, constructorProps) {
6
- super();
7
- this.contextManager = contextManager;
6
+ super(contextManager);
8
7
  this.constructorProps = constructorProps;
9
8
  this.children = [];
10
9
  /**
@@ -5,6 +5,7 @@ export interface CanvasContextOptions {
5
5
  canvas?: HTMLCanvasElement;
6
6
  overlay?: HTMLDivElement;
7
7
  }
8
+ /** @zcontext */
8
9
  export declare class CanvasContext extends Context {
9
10
  constructorProps: CanvasContextOptions;
10
11
  onBeforeRender: Event<[number]>;
@@ -12,6 +13,7 @@ export declare class CanvasContext extends Context {
12
13
  canvas: HTMLCanvasElement;
13
14
  overlayDefault: HTMLDivElement;
14
15
  overlay: Observable<HTMLDivElement>;
16
+ /** @zui */
15
17
  size: Observable<[number, number]>;
16
18
  private _resizeObserver;
17
19
  constructor(contextManager: ContextManager, constructorProps: CanvasContextOptions);
@@ -1,6 +1,7 @@
1
1
  import { Context } from '../context';
2
2
  import { Event } from '../event';
3
3
  import { Observable } from '../observable';
4
+ /** @zcontext */
4
5
  export class CanvasContext extends Context {
5
6
  constructor(contextManager, constructorProps) {
6
7
  super(contextManager, constructorProps);
@@ -36,7 +37,7 @@ export class CanvasContext extends Context {
36
37
  this.size = new Observable([this.canvas.clientWidth, this.canvas.clientHeight]);
37
38
  this._resizeObserver.observe(this.canvas);
38
39
  let lastRect;
39
- this.onBeforeRender.bindfn(() => {
40
+ this.onBeforeRender.addListener(() => {
40
41
  const rect = this.canvas.getBoundingClientRect();
41
42
  if (lastRect && lastRect.top === rect.top && lastRect.left === rect.left && lastRect.width === rect.width && lastRect.height === rect.height)
42
43
  return;
@@ -48,8 +49,8 @@ export class CanvasContext extends Context {
48
49
  });
49
50
  }
50
51
  dispose() {
51
- this.onBeforeRender.clear();
52
- this.onAfterRender.clear();
52
+ this.onBeforeRender.clearListeners();
53
+ this.onAfterRender.clearListeners();
53
54
  this._resizeObserver.disconnect();
54
55
  if (!this.constructorProps.canvas)
55
56
  this.canvas.remove();
@@ -1,9 +1,19 @@
1
1
  import { ContextManager, Context } from '../context';
2
2
  import { Observable } from '../observable';
3
+ /** @zcontext */
3
4
  export declare class EnvironmentContext extends Context {
5
+ /** @zprop */
4
6
  designTime: Observable<boolean, never>;
7
+ /** @zprop */
5
8
  editTime: Observable<boolean, never>;
9
+ /** @zprop */
10
+ runTime: Observable<boolean, never>;
11
+ /** @zprop */
12
+ developmentBuild: Observable<boolean, never>;
13
+ /** @zprop */
14
+ productionBuild: Observable<boolean, never>;
6
15
  }
7
16
  export declare function isDesignTime(ctx: ContextManager): boolean;
8
17
  export declare function isEditTime(ctx: ContextManager): boolean;
9
18
  export declare function isDevelopmentBuild(ctx: ContextManager): boolean;
19
+ export declare function isProductionBuild(ctx: ContextManager): boolean;
@@ -1,10 +1,19 @@
1
1
  import { Context } from '../context';
2
2
  import { Observable } from '../observable';
3
+ /** @zcontext */
3
4
  export class EnvironmentContext extends Context {
4
5
  constructor() {
5
6
  super(...arguments);
7
+ /** @zprop */
6
8
  this.designTime = new Observable(false);
9
+ /** @zprop */
7
10
  this.editTime = new Observable(false);
11
+ /** @zprop */
12
+ this.runTime = new Observable(true);
13
+ /** @zprop */
14
+ this.developmentBuild = new Observable(typeof process !== 'undefined' && process?.env?.NODE_ENV === 'development');
15
+ /** @zprop */
16
+ this.productionBuild = new Observable(!this.developmentBuild.value);
8
17
  }
9
18
  }
10
19
  export function isDesignTime(ctx) {
@@ -14,5 +23,8 @@ export function isEditTime(ctx) {
14
23
  return ctx.get(EnvironmentContext).editTime.value;
15
24
  }
16
25
  export function isDevelopmentBuild(ctx) {
17
- return (typeof process !== 'undefined' && process?.env?.NODE_ENV === 'development');
26
+ return ctx.get(EnvironmentContext).developmentBuild.value;
27
+ }
28
+ export function isProductionBuild(ctx) {
29
+ return ctx.get(EnvironmentContext).productionBuild.value;
18
30
  }
@@ -1,9 +1,14 @@
1
1
  import { ContextManager, Context } from '../context';
2
2
  import { Observable } from '../observable';
3
+ /** @zcontext */
3
4
  export declare class LoadContext extends Context {
5
+ /** @zui */
4
6
  isConstructed: Observable<boolean, never>;
7
+ /** @zui */
5
8
  isLoaded: Observable<boolean, never>;
9
+ /** @zui */
6
10
  isStarted: Observable<boolean, never>;
11
+ /** @zui */
7
12
  progressPercent: Observable<number, never>;
8
13
  private _startedResolved;
9
14
  started: Promise<void>;
@@ -1,11 +1,16 @@
1
1
  import { Context } from '../context';
2
2
  import { Observable } from '../observable';
3
+ /** @zcontext */
3
4
  export class LoadContext extends Context {
4
5
  constructor() {
5
6
  super(...arguments);
7
+ /** @zui */
6
8
  this.isConstructed = new Observable(false);
9
+ /** @zui */
7
10
  this.isLoaded = new Observable(false);
11
+ /** @zui */
8
12
  this.isStarted = new Observable(false);
13
+ /** @zui */
9
14
  this.progressPercent = new Observable(0);
10
15
  this.started = new Promise(resolve => this._startedResolved = resolve);
11
16
  this._loadables = new Set();
package/lib/data.d.ts CHANGED
@@ -1,8 +1,13 @@
1
- import { BehaviorByID, BehaviorData, ComputedHierarchy, NodeByID, NodeData, ZComponentData } from "./interfaces";
1
+ import { BehaviorByID, BehaviorData, ComputedHierarchy, EntityPropOverride, NodeByID, NodeData, ZComponentData } from "./interfaces";
2
+ import { Prop } from "./types";
2
3
  export declare function computeNodeHierarchy(nodes: NodeByID): ComputedHierarchy;
3
4
  export declare function computeBehaviorHierarchy(behaviors: BehaviorByID): ComputedHierarchy;
4
5
  export declare function addNode(zcomp: ZComponentData, info: NodeDataCombined): void;
5
6
  export declare function addBehavior(zcomp: ZComponentData, info: BehaviorDataCombined): void;
7
+ export declare function updateComponentProp(zcomp: ZComponentData, prop: string, isConstructorProp: boolean, newValue: Prop | undefined, newIsConstructorProp: boolean): void;
8
+ export declare function addEntityPropOverride(zcomp: ZComponentData, o: EntityPropOverride): void;
9
+ export declare function deleteEntityPropOverride(zcomp: ZComponentData, id: string): void;
10
+ export declare function clone<T>(obj: T): T;
6
11
  export declare function addEntity(zcomp: ZComponentData, id: string, info: EntityDataCombined): void;
7
12
  export declare function moveNodes(zcomp: ZComponentData, nodeIDs: string[], newParentID: string, indx: number): void;
8
13
  export declare function deleteNode(zcomp: ZComponentData, id: string): void;
package/lib/data.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { generateKeyBetween, generateNKeysBetween } from "./fractionalindexing";
2
+ import { EntityPropOverrideType } from "./interfaces";
2
3
  // Simple memoizing of computed hierarchy
3
4
  const computedHierarchies = new Map();
4
5
  const computedBehaviors = new Map();
@@ -66,6 +67,80 @@ export function addBehavior(zcomp, info) {
66
67
  addEntity(zcomp, info.data.id, info);
67
68
  computedBehaviors.delete(zcomp.behaviors);
68
69
  }
70
+ export function updateComponentProp(zcomp, prop, isConstructorProp, newValue, newIsConstructorProp) {
71
+ if (zcomp.constructorProps === undefined)
72
+ zcomp.constructorProps = {};
73
+ if (newValue === undefined) {
74
+ if (isConstructorProp)
75
+ delete zcomp.constructorProps[prop];
76
+ else
77
+ delete zcomp.props[prop];
78
+ if (zcomp.entityPropOverrides) {
79
+ for (const [id, override] of Object.entries(zcomp.entityPropOverrides)) {
80
+ if (override.type !== EntityPropOverrideType.ComponentProp)
81
+ continue;
82
+ if (override.isConstructorProp !== isConstructorProp)
83
+ continue;
84
+ if (override.propName !== prop)
85
+ continue;
86
+ delete zcomp.entityPropOverrides[id];
87
+ }
88
+ }
89
+ return;
90
+ }
91
+ if (newValue.name !== prop || isConstructorProp !== newIsConstructorProp) {
92
+ if (isConstructorProp)
93
+ delete zcomp.constructorProps[prop];
94
+ else
95
+ delete zcomp.props[prop];
96
+ if (zcomp.entityPropOverrides) {
97
+ for (const [id, override] of Object.entries(zcomp.entityPropOverrides)) {
98
+ if (override.type !== EntityPropOverrideType.ComponentProp)
99
+ continue;
100
+ if (override.isConstructorProp !== isConstructorProp)
101
+ continue;
102
+ if (override.propName !== prop)
103
+ continue;
104
+ delete zcomp.entityPropOverrides[id];
105
+ if (!(override.entityPropIsConstructor && !newIsConstructorProp)) {
106
+ const newOverride = clone(override);
107
+ newOverride.propName = newValue.name;
108
+ newOverride.id = idForEntityPropOverride(override);
109
+ zcomp.entityPropOverrides[newOverride.id] = newOverride;
110
+ }
111
+ }
112
+ }
113
+ }
114
+ newValue.type.isObservable = !newIsConstructorProp;
115
+ if (newIsConstructorProp)
116
+ zcomp.constructorProps[newValue.name] = newValue;
117
+ else
118
+ zcomp.props[newValue.name] = newValue;
119
+ }
120
+ export function addEntityPropOverride(zcomp, o) {
121
+ if (!zcomp.entityPropOverrides)
122
+ zcomp.entityPropOverrides = {};
123
+ o.id = idForEntityPropOverride(o);
124
+ zcomp.entityPropOverrides[o.id] = o;
125
+ }
126
+ export function deleteEntityPropOverride(zcomp, id) {
127
+ if (!zcomp.entityPropOverrides)
128
+ return;
129
+ delete zcomp.entityPropOverrides[id];
130
+ }
131
+ function idForEntityPropOverride(override) {
132
+ return override.type + ":" + (override.entityPropIsConstructor ? 'constructorprop' : 'prop') + ":" + override.entityID + ":" + override.entityPropPath.join('.');
133
+ }
134
+ export function clone(obj) {
135
+ try {
136
+ if (typeof structuredClone !== 'undefined')
137
+ return structuredClone(obj);
138
+ }
139
+ catch {
140
+ // Ignore
141
+ }
142
+ return JSON.parse(JSON.stringify(obj));
143
+ }
69
144
  export function addEntity(zcomp, id, info) {
70
145
  zcomp.entityProps[id] = info.props;
71
146
  zcomp.entityConstructorProps[id] = info.constructorProps;
@@ -265,6 +340,13 @@ export function changeNodeScriptName(zcomp, id, newScriptName) {
265
340
  export function deleteEntity(zcomp, id) {
266
341
  delete zcomp.entityProps[id];
267
342
  delete zcomp.entityConstructorProps[id];
343
+ if (zcomp.entityPropOverrides) {
344
+ for (const [overrideID, override] of Object.entries(zcomp.entityPropOverrides)) {
345
+ if (override.entityID !== id)
346
+ continue;
347
+ delete zcomp.entityPropOverrides[overrideID];
348
+ }
349
+ }
268
350
  }
269
351
  export function forEachNodeAncestor(zcomp, id, fn) {
270
352
  const node = zcomp.nodes[id];
@@ -0,0 +1,25 @@
1
+ import { Observable } from "./observable";
2
+ export declare class Emitter<Args extends Array<any> = []> {
3
+ hasListeners: Observable<boolean, never>;
4
+ private _funcs;
5
+ private _emitting;
6
+ private _toUnbind;
7
+ private _needsSort;
8
+ clearListeners(): void;
9
+ /**
10
+ * Add a new handler function
11
+ * @param f - The callback function to be bound.
12
+ */
13
+ addListener(f: (...args: Args) => void, priority?: number): void;
14
+ /**
15
+ * Unbind an existing function
16
+ * @param f - The callback function to be unbound.
17
+ */
18
+ removeListener(f: (...args: Args) => void): void;
19
+ /**
20
+ * Emit an event
21
+ *
22
+ * @param a - The argument to pass to handler functions.
23
+ */
24
+ protected _emit(...args: Args): void;
25
+ }
package/lib/emitter.js ADDED
@@ -0,0 +1,69 @@
1
+ import { Observable } from "./observable";
2
+ export class Emitter {
3
+ constructor() {
4
+ this.hasListeners = new Observable(false);
5
+ this._funcs = [];
6
+ this._emitting = false;
7
+ this._toUnbind = new Set();
8
+ this._needsSort = false;
9
+ }
10
+ clearListeners() {
11
+ this._funcs = [];
12
+ this.hasListeners.value = false;
13
+ this._needsSort = false;
14
+ }
15
+ /**
16
+ * Add a new handler function
17
+ * @param f - The callback function to be bound.
18
+ */
19
+ addListener(f, priority = 0) {
20
+ this._funcs.push([f, priority]);
21
+ this._needsSort = true;
22
+ if (!this.hasListeners.value)
23
+ this.hasListeners.value = true;
24
+ }
25
+ /**
26
+ * Unbind an existing function
27
+ * @param f - The callback function to be unbound.
28
+ */
29
+ removeListener(f) {
30
+ if (this._emitting) {
31
+ this._toUnbind.add(f);
32
+ return;
33
+ }
34
+ this._toUnbind.delete(f);
35
+ const indx = this._funcs.findIndex(entry => entry[0] === f);
36
+ if (indx > -1) {
37
+ this._funcs.splice(indx, 1);
38
+ }
39
+ if (this._funcs.length === 0 && this.hasListeners.value)
40
+ this.hasListeners.value = false;
41
+ }
42
+ /**
43
+ * Emit an event
44
+ *
45
+ * @param a - The argument to pass to handler functions.
46
+ */
47
+ _emit(...args) {
48
+ if (this._needsSort) {
49
+ this._funcs.sort((a, b) => b[1] - a[1]);
50
+ this._needsSort = false;
51
+ }
52
+ this._emitting = true;
53
+ for (let i = 0, total = this._funcs.length; i < total; i++) {
54
+ const fn = this._funcs[i][0];
55
+ try {
56
+ if (this._toUnbind.has(fn))
57
+ continue;
58
+ fn(...args);
59
+ }
60
+ catch (ex) {
61
+ console.log('Exception in event handler', ex);
62
+ }
63
+ }
64
+ this._emitting = false;
65
+ if (this._toUnbind.size > 0) {
66
+ this._toUnbind.forEach(fn => this.removeListener(fn));
67
+ }
68
+ }
69
+ }
package/lib/entity.d.ts CHANGED
@@ -1,16 +1,19 @@
1
1
  import { ConstructorForComponent } from "./component";
2
+ import { ContextManager } from "./context";
2
3
  import { Event } from "./event";
3
4
  import { Observable } from "./observable";
4
5
  import { ZComponent } from "./zcomponent";
5
6
  export declare class Entity {
7
+ readonly contextManager: ContextManager;
6
8
  private _registered;
9
+ private _handlersBound;
7
10
  private _zcomponent;
8
11
  private _disposed;
9
12
  /**
10
13
  * An event that is fired as the last act of this entity being destroyed.
11
14
  */
12
15
  readonly onDispose: Event<[]>;
13
- constructor();
16
+ constructor(contextManager: ContextManager);
14
17
  get disposed(): boolean;
15
18
  private set disposed(value);
16
19
  /**
@@ -62,6 +65,7 @@ export declare class Entity {
62
65
  getZComponentInstance<T extends ZComponent = ZComponent>(type?: ConstructorForComponent<T>): T;
63
66
  /**
64
67
  * Register a function to be called when an Event is fired, or an Observable's value changes.
68
+ * The function will only be bound to the underlying Event or Observable while this entity is enabled.
65
69
  *
66
70
  * Using this function, rather than attaching your handler directly to the Event or Observable,
67
71
  * ensures your handler is automatically released when this entity is disposed.
@@ -69,8 +73,10 @@ export declare class Entity {
69
73
  * @param evt The Event or Observable to listen to
70
74
  * @param fn A function that will be called when the event fires, or the Observable value changes
71
75
  */
72
- register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
73
- register<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
76
+ register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void, priority?: number): any;
77
+ register<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void, options?: RegisterOptions): any;
78
+ register<Type>(observable: Observable<Type>, fn: (v: Type) => void, priority?: number): any;
79
+ register<Type>(observable: Observable<Type>, fn: (v: Type) => void, options?: RegisterOptions): any;
74
80
  /**
75
81
  * Unregisters a function that was previously registered to an Event or Observable.
76
82
  *
@@ -79,6 +85,7 @@ export declare class Entity {
79
85
  */
80
86
  unregister<Args extends Array<any>>(evt: Event<Args>, fn: (...args: Args) => void): any;
81
87
  unregister<Type>(observable: Observable<Type>, fn: (v: Type) => void): any;
88
+ private _updateHandlers;
82
89
  /**
83
90
  * Destroy this entity, cleaning up any resources that it has created and
84
91
  * handler functions or callbacks it has registered.
@@ -100,3 +107,7 @@ export declare class Entity {
100
107
  dispose(): never;
101
108
  private static callSuperDispose;
102
109
  }
110
+ export interface RegisterOptions {
111
+ priority?: number;
112
+ bindWhenDisabled?: boolean;
113
+ }
package/lib/entity.js CHANGED
@@ -2,8 +2,10 @@ import { Event } from "./event";
2
2
  import { Observable } from "./observable";
3
3
  import { getCurrentZComponentConstruction } from "./zcomponentconstruction";
4
4
  export class Entity {
5
- constructor() {
5
+ constructor(contextManager) {
6
+ this.contextManager = contextManager;
6
7
  this._registered = [];
8
+ this._handlersBound = false;
7
9
  this._disposed = false;
8
10
  /**
9
11
  * An event that is fired as the last act of this entity being destroyed.
@@ -45,7 +47,24 @@ export class Entity {
45
47
  * Disabled entities will typically remain visible (if they have a visible appearance).
46
48
  */
47
49
  this.enabledResolved = new Observable(true);
50
+ this._updateHandlers = (enabled) => {
51
+ if (enabled && !this._handlersBound) {
52
+ for (const [e, fn, priority] of this._registered) {
53
+ e.addListener(fn, priority);
54
+ }
55
+ this._handlersBound = true;
56
+ }
57
+ if (!enabled && this._handlersBound) {
58
+ for (const [e, fn, _, bindWhenDisabled] of this._registered) {
59
+ if (bindWhenDisabled)
60
+ continue;
61
+ e.removeListener(fn);
62
+ }
63
+ this._handlersBound = false;
64
+ }
65
+ };
48
66
  this._zcomponent = getCurrentZComponentConstruction();
67
+ this.enabledResolved.addListener(this._updateHandlers);
49
68
  }
50
69
  get disposed() {
51
70
  return this._disposed;
@@ -72,18 +91,20 @@ export class Entity {
72
91
  return this._zcomponent;
73
92
  throw new Error("getZComponentInstance called in entity passing wrong kind of ZComponent");
74
93
  }
75
- register(e, fn) {
76
- if (e instanceof Event)
77
- e.bindfn(fn);
78
- else if (e instanceof Observable)
79
- e.withValue(fn);
80
- this._registered.push([e, fn]);
94
+ register(e, fn, priorityOrOptions) {
95
+ const priority = (typeof priorityOrOptions === 'number' ? priorityOrOptions : priorityOrOptions?.priority);
96
+ const bindWhenDisabled = (typeof priorityOrOptions === 'number' ? false : priorityOrOptions?.bindWhenDisabled);
97
+ for (const entry of this._registered) {
98
+ if (entry[0] === e && entry[1] === fn)
99
+ return;
100
+ }
101
+ this._registered.push([e, fn, priority, bindWhenDisabled ?? false]);
102
+ if (this._handlersBound || bindWhenDisabled) {
103
+ e.addListener(fn, priority);
104
+ }
81
105
  }
82
106
  unregister(e, fn) {
83
- if (e instanceof Event)
84
- e.unbindfn(fn);
85
- else if (e instanceof Observable)
86
- e.removeWithValue(fn);
107
+ e.removeListener(fn);
87
108
  this._registered = this._registered.filter(entry => (entry[0] !== e || entry[1] !== fn));
88
109
  }
89
110
  /**
@@ -105,15 +126,13 @@ export class Entity {
105
126
  * @returns The result of a call to super.dispose()
106
127
  */
107
128
  dispose() {
129
+ this.enabledResolved.removeListener(this._updateHandlers);
108
130
  for (const entry of this._registered) {
109
- if (entry[0] instanceof Event)
110
- entry[0].unbindfn(entry[1]);
111
- else if (entry[0] instanceof Observable)
112
- entry[0].removeWithValue(entry[1]);
131
+ entry[0].removeListener(entry[1]);
113
132
  }
114
133
  this._registered = [];
115
134
  this.onDispose.emit();
116
- this.onDispose.clear();
135
+ this.onDispose.clearListeners();
117
136
  this.disposed = true;
118
137
  return undefined;
119
138
  }
package/lib/event.d.ts CHANGED
@@ -1,20 +1,5 @@
1
- import { Observable } from "./observable";
2
- export declare class Event<Args extends Array<any> = []> {
3
- hasBindings: Observable<boolean, never>;
4
- private _funcs;
5
- private _emitting;
6
- private _toUnbind;
7
- clear(): void;
8
- /**
9
- * Bind new handler function.
10
- * @param f - The callback function to be bound.
11
- */
12
- bindfn(f: (...args: Args) => void): void;
13
- /**
14
- * Unbind an existing function.
15
- * @param f - The callback function to be unbound.
16
- */
17
- unbindfn(f: (...args: Args) => void): void;
1
+ import { Emitter } from "./emitter";
2
+ export declare class Event<Args extends Array<any> = []> extends Emitter<Args> {
18
3
  /**
19
4
  * Emit an event.
20
5
  *
package/lib/event.js CHANGED
@@ -1,61 +1,11 @@
1
- import { Observable } from "./observable";
2
- export class Event {
3
- constructor() {
4
- this.hasBindings = new Observable(false);
5
- this._funcs = [];
6
- this._emitting = false;
7
- this._toUnbind = new Set();
8
- }
9
- clear() {
10
- this._funcs = [];
11
- this.hasBindings.value = false;
12
- }
13
- /**
14
- * Bind new handler function.
15
- * @param f - The callback function to be bound.
16
- */
17
- bindfn(f) {
18
- this._funcs.push(f);
19
- if (!this.hasBindings.value)
20
- this.hasBindings.value = true;
21
- }
22
- /**
23
- * Unbind an existing function.
24
- * @param f - The callback function to be unbound.
25
- */
26
- unbindfn(f) {
27
- if (this._emitting) {
28
- this._toUnbind.add(f);
29
- return;
30
- }
31
- this._toUnbind.delete(f);
32
- const indx = this._funcs.indexOf(f);
33
- if (indx > -1) {
34
- this._funcs.splice(indx, 1);
35
- }
36
- if (this._funcs.length === 0 && this.hasBindings.value)
37
- this.hasBindings.value = false;
38
- }
1
+ import { Emitter } from "./emitter";
2
+ export class Event extends Emitter {
39
3
  /**
40
4
  * Emit an event.
41
5
  *
42
6
  * @param a - The argument to pass to handler functions.
43
7
  */
44
8
  emit(...args) {
45
- this._emitting = true;
46
- for (let i = 0, total = this._funcs.length; i < total; i++) {
47
- try {
48
- if (this._toUnbind.has(this._funcs[i]))
49
- continue;
50
- this._funcs[i](...args);
51
- }
52
- catch (ex) {
53
- console.log('Exception in event handler', ex);
54
- }
55
- }
56
- this._emitting = false;
57
- if (this._toUnbind.size > 0) {
58
- this._toUnbind.forEach(fn => this.unbindfn(fn));
59
- }
9
+ super._emit(...args);
60
10
  }
61
11
  }