From 92c8656bce2dd44b6553f2fc1250eb5281093bf4 Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Thu, 25 Jul 2019 16:32:26 -0400 Subject: [PATCH 1/5] [Implement] Naive basic EventEmitter class --- assembly/events/index.ts | 58 ++++++++++++++++++++++++++++++++++++++++ tests/events.spec.ts | 19 +++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 assembly/events/index.ts create mode 100644 tests/events.spec.ts diff --git a/assembly/events/index.ts b/assembly/events/index.ts new file mode 100644 index 0000000..c22b86a --- /dev/null +++ b/assembly/events/index.ts @@ -0,0 +1,58 @@ +import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common"; +import { E_INVALIDLENGTH } from "util/error"; + +class EventList { + count: usize; + + // adapted from https://github.com/AssemblyScript/assemblyscript/blob/master/std/assembly/array.ts#L11 + ensureSize(minSize: usize): EventList { + let currentSize = changetype(changetype(this) - BLOCK_OVERHEAD).rtSize; + let byteLength = (minSize + 2) << alignof(); + if (byteLength > currentSize) { + if (byteLength > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); + let oldData = changetype(this); + let newData = __realloc(oldData, byteLength); + // don't need to fill because they won't be used + // memory.fill(newData + currentSize, 0, byteLength - currentSize); + return changetype(newData); + } + return this; + } +} + +export class EventEmitter { + private _events: Map = new Map(); + + private _ensureEvent(event: string): void { + if (!this._events.has(event)) { + let byteLength = offsetof() + (sizeof() << 2); + let list = changetype(__alloc(byteLength, idof())); + this._events.set(event, list); + } + } + + public on(event: string, callback: T): EventEmitter { + if (!isFunction()) { + ERROR("EventEmitter#on can only be called with a callback of type T where T is a static function."); + } + this._ensureEvent(event); + let list = this._events.get(event); + list.count += 1; + list = list.ensureSize(list.count); + store(changetype(list) + ((list.count) << alignof()), changetype(callback)); + return this; + } + + public emit(event: string, data: T): EventEmitter { + if (this._events.has(event)) { + let list = this._events.get(event); + let count = list.count; + let start = changetype(list) + sizeof(); + for (let i: usize = 0; i < count; i++) { + call_indirect(load(start), data); + start += sizeof(); + } + } + return this; + } +} \ No newline at end of file diff --git a/tests/events.spec.ts b/tests/events.spec.ts new file mode 100644 index 0000000..e1e33d6 --- /dev/null +++ b/tests/events.spec.ts @@ -0,0 +1,19 @@ +import { EventEmitter } from "events"; + +let calls: i32 = 0; + +type i32Callback = (value: i32) => void; + +describe("events", () => { + test("events", () => { + let t = new EventEmitter(); + t.on("data", (value: i32) => { + calls += 1; + expect(value).toBe(42); + }); + t.emit("data", 42); + t.emit("data", 42); + t.emit("data", 42); + expect(calls).toBe(3); + }); +}); \ No newline at end of file From a99518de1a5b810f1a469c373fa2d9a577d183e1 Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Thu, 25 Jul 2019 18:54:48 -0400 Subject: [PATCH 2/5] [Implement] idof>() for runtime callback type checking --- assembly/events/index.ts | 68 ++++++++++++++++++---------------------- tests/events.spec.ts | 8 +++-- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/assembly/events/index.ts b/assembly/events/index.ts index c22b86a..3dbe936 100644 --- a/assembly/events/index.ts +++ b/assembly/events/index.ts @@ -1,56 +1,50 @@ -import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common"; -import { E_INVALIDLENGTH } from "util/error"; +import { BLOCK_OVERHEAD, BLOCK } from "rt/common"; -class EventList { - count: usize; - - // adapted from https://github.com/AssemblyScript/assemblyscript/blob/master/std/assembly/array.ts#L11 - ensureSize(minSize: usize): EventList { - let currentSize = changetype(changetype(this) - BLOCK_OVERHEAD).rtSize; - let byteLength = (minSize + 2) << alignof(); - if (byteLength > currentSize) { - if (byteLength > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); - let oldData = changetype(this); - let newData = __realloc(oldData, byteLength); - // don't need to fill because they won't be used - // memory.fill(newData + currentSize, 0, byteLength - currentSize); - return changetype(newData); - } - return this; - } -} +class Callback {} +class Dummy {} export class EventEmitter { - private _events: Map = new Map(); - - private _ensureEvent(event: string): void { - if (!this._events.has(event)) { - let byteLength = offsetof() + (sizeof() << 2); - let list = changetype(__alloc(byteLength, idof())); - this._events.set(event, list); + public static EventMap: Map> = new Map>(); + public static registerEventCallback(event: string): void { + if (!isFunction()) { + ERROR("Cannot register event callback of type U where U is not a function."); + } + if (!EventEmitter.EventMap.has(idof())) { + EventEmitter.EventMap.set(idof(), new Map()); } + let ClassEvents = EventEmitter.EventMap.get(idof()); + if (ClassEvents.has(event)) { + throw new Error("EventMap already contains a definition for event: " + event); + } + ClassEvents.set(event, idof>()); } + private _events: Map = new Map(); + public on(event: string, callback: T): EventEmitter { if (!isFunction()) { ERROR("EventEmitter#on can only be called with a callback of type T where T is a static function."); } - this._ensureEvent(event); - let list = this._events.get(event); - list.count += 1; - list = list.ensureSize(list.count); - store(changetype(list) + ((list.count) << alignof()), changetype(callback)); + let rtId = changetype(changetype(this) - BLOCK_OVERHEAD).rtId; + let EventMap = EventEmitter.EventMap; + if (!EventMap.has(rtId)) throw new Error("Cannot attach events to an EventEmitter with no EventMap definitions."); + let ClassEvents = EventMap.get(rtId); + if (!ClassEvents.has(event)) throw new Error("Event does not exist: " + event); + let cbId = idof>(); + let classEventCallbackID = ClassEvents.get(event); + assert(cbId == classEventCallbackID); + if (!this._events.has(event)) this._events.set(event, new Array()); + let eventList = this._events.get(event); + eventList.push(changetype(callback)); return this; } public emit(event: string, data: T): EventEmitter { if (this._events.has(event)) { let list = this._events.get(event); - let count = list.count; - let start = changetype(list) + sizeof(); - for (let i: usize = 0; i < count; i++) { - call_indirect(load(start), data); - start += sizeof(); + let length = list.length; + for (let i: i32 = 0; i < length; i++) { + call_indirect(unchecked(list[i]), data); } } return this; diff --git a/tests/events.spec.ts b/tests/events.spec.ts index e1e33d6..80b6a3a 100644 --- a/tests/events.spec.ts +++ b/tests/events.spec.ts @@ -4,10 +4,14 @@ let calls: i32 = 0; type i32Callback = (value: i32) => void; +class CustomEventEmitter extends EventEmitter {} + +EventEmitter.registerEventCallback("data"); + describe("events", () => { test("events", () => { - let t = new EventEmitter(); - t.on("data", (value: i32) => { + let t = new CustomEventEmitter(); + t.on("data", (value: i32) => { calls += 1; expect(value).toBe(42); }); From 5f12802f69197c197f62808323b90ea23b1e6a82 Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Fri, 26 Jul 2019 15:55:45 -0400 Subject: [PATCH 3/5] [Implement] Multiple Parameter Callbacks with --- assembly/events/index.ts | 85 ++++++++++++++++++++++++++++++++++------ package-lock.json | 4 +- package.json | 2 +- tests/events.spec.ts | 26 +++++++++--- 4 files changed, 98 insertions(+), 19 deletions(-) diff --git a/assembly/events/index.ts b/assembly/events/index.ts index 3dbe936..2a5dc3b 100644 --- a/assembly/events/index.ts +++ b/assembly/events/index.ts @@ -1,22 +1,22 @@ import { BLOCK_OVERHEAD, BLOCK } from "rt/common"; -class Callback {} -class Dummy {} export class EventEmitter { - public static EventMap: Map> = new Map>(); - public static registerEventCallback(event: string): void { + public static EventMap: Map> = new Map>(); + public static registerEventCallback(event: string, length: u32 = 1): void { if (!isFunction()) { ERROR("Cannot register event callback of type U where U is not a function."); } if (!EventEmitter.EventMap.has(idof())) { - EventEmitter.EventMap.set(idof(), new Map()); + EventEmitter.EventMap.set(idof(), new Map()); } let ClassEvents = EventEmitter.EventMap.get(idof()); if (ClassEvents.has(event)) { throw new Error("EventMap already contains a definition for event: " + event); } - ClassEvents.set(event, idof>()); + let definition: u64 = idof() | (length << 32); + ClassEvents.set(event, definition); + log(definition); } private _events: Map = new Map(); @@ -30,8 +30,9 @@ export class EventEmitter { if (!EventMap.has(rtId)) throw new Error("Cannot attach events to an EventEmitter with no EventMap definitions."); let ClassEvents = EventMap.get(rtId); if (!ClassEvents.has(event)) throw new Error("Event does not exist: " + event); - let cbId = idof>(); - let classEventCallbackID = ClassEvents.get(event); + let cbId = idof(); + let classEventSignature = ClassEvents.get(event); + let classEventCallbackID = (classEventSignature & 0xFFFFFFFF); assert(cbId == classEventCallbackID); if (!this._events.has(event)) this._events.set(event, new Array()); let eventList = this._events.get(event); @@ -39,12 +40,74 @@ export class EventEmitter { return this; } - public emit(event: string, data: T): EventEmitter { + public emit + (event: string, a: A = null, b: B = null, c: C = null, d: D = null, e: E = null, f: F = null, g: G = null, h: H = null, i: I = null, j: J = null): EventEmitter { if (this._events.has(event)) { + let rtId = changetype(changetype(this) - BLOCK_OVERHEAD).rtId; + let ClassEvents = EventEmitter.EventMap.get(rtId); + assert(ClassEvents.has(event), "No event definition."); + let classEventSignature = ClassEvents.get(event); + let classEventArgLength = (classEventSignature >> 32) & 0xFFFFFFFF; + let classEventCallbackID = (classEventSignature & 0xFFFFFFFF); let list = this._events.get(event); let length = list.length; - for (let i: i32 = 0; i < length; i++) { - call_indirect(unchecked(list[i]), data); + switch (classEventArgLength) { + case 0: { + assert(classEventCallbackID == idof<() => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z])); + break; + } + case 1: { + assert(classEventCallbackID == idof<(a: A) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a); + break; + } + case 2: { + assert(classEventCallbackID == idof<(a: A, b: B) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b); + break; + } + case 3: { + assert(classEventCallbackID == idof<(a: A, b: B, c: C) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b, c); + break; + } + case 4: { + assert(classEventCallbackID == idof<(a: A, b: B, c: C, d: D) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b, c, d); + break; + } + case 5: { + assert(classEventCallbackID == idof<(a: A, b: B, c: C, d: D, e: E) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b, c, d, e); + break; + } + case 6: { + assert(classEventCallbackID == idof<(a: A, b: B, c: C, d: D, e: E, f: F) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b, c, d, e, f); + break; + } + case 7: { + assert(classEventCallbackID == idof<(a: A, b: B, c: C, d: D, e: E, f: F, g: G) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b, c, d, e, f, g); + break; + } + case 8: { + assert(classEventCallbackID == idof<(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b, c, d, e, f, g, h); + break; + } + case 9: { + assert(classEventCallbackID == idof<(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b, c, d, e, f, g, h, i); + break; + } + case 10: { + assert(classEventCallbackID == idof<(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) => void>()); + for (let z = 0; z < length; z++) call_indirect(unchecked(list[z]), a, b, c, d, e, f, g, h, i, j); + break; + } + default: assert(false); } } return this; diff --git a/package-lock.json b/package-lock.json index 1d4efe9..27277bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,8 +38,8 @@ } }, "assemblyscript": { - "version": "github:assemblyscript/assemblyscript#4c938f7689c39e3a1ad813356781e2689fd4ec70", - "from": "github:assemblyscript/assemblyscript", + "version": "github:jtenner/assemblyscript#a93c3de2b51deccc24bf3d6971f5ca8da3d53dd6", + "from": "github:jtenner/assemblyscript#idof-dist", "dev": true, "requires": { "@protobufjs/utf8": "^1.1.0", diff --git a/package.json b/package.json index ff4bc6b..f006230 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "devDependencies": { "@as-pect/core": "^2.3.1", - "assemblyscript": "github:assemblyscript/assemblyscript", + "assemblyscript": "github:jtenner/assemblyscript#idof-dist", "glob": "^7.1.4", "wasi": "github:devsnek/node-wasi" }, diff --git a/tests/events.spec.ts b/tests/events.spec.ts index 80b6a3a..42600bf 100644 --- a/tests/events.spec.ts +++ b/tests/events.spec.ts @@ -2,22 +2,38 @@ import { EventEmitter } from "events"; let calls: i32 = 0; -type i32Callback = (value: i32) => void; - +type i32Callback = (a: i32) => void; +type i64Callback = (a: i64, b: i64) => void; class CustomEventEmitter extends EventEmitter {} -EventEmitter.registerEventCallback("data"); +EventEmitter.registerEventCallback("data", 1); +EventEmitter.registerEventCallback("data2", 2); describe("events", () => { test("events", () => { let t = new CustomEventEmitter(); - t.on("data", (value: i32) => { + calls = 0; + t.on("data", (wrongName: i32) => { calls += 1; - expect(value).toBe(42); + expect(wrongName).toBe(42); }); t.emit("data", 42); t.emit("data", 42); t.emit("data", 42); expect(calls).toBe(3); }); + + test("events2", () => { + let t = new CustomEventEmitter(); + calls = 0; + t.on("data2", (a: i64, b: i64) => { + calls += 1; + expect(a).toBe(42); + expect(b).toBe(42); + }); + t.emit("data2", 42, 42); + t.emit("data2", 42, 42); + t.emit("data2", 42, 42); + expect(calls).toBe(3); + }); }); \ No newline at end of file From 1ff2d68539b4cc6c5290bda7883705d428c6deb2 Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Tue, 30 Jul 2019 15:33:02 -0400 Subject: [PATCH 4/5] [Fix] Veryify function type is void, obtain function parameter length --- assembly/events/index.ts | 14 ++++++------ assembly/node.d.ts | 9 ++++++++ package-lock.json | 47 ++++++++++++---------------------------- package.json | 5 +++-- tests/events.spec.ts | 6 ++--- 5 files changed, 36 insertions(+), 45 deletions(-) diff --git a/assembly/events/index.ts b/assembly/events/index.ts index 2a5dc3b..20f2a76 100644 --- a/assembly/events/index.ts +++ b/assembly/events/index.ts @@ -1,12 +1,14 @@ import { BLOCK_OVERHEAD, BLOCK } from "rt/common"; - -export class EventEmitter { +export abstract class EventEmitter { public static EventMap: Map> = new Map>(); - public static registerEventCallback(event: string, length: u32 = 1): void { + public static registerEventCallback(event: string): void { if (!isFunction()) { ERROR("Cannot register event callback of type U where U is not a function."); } + if (!isVoid>()) { + ERROR("Cannot register event callback of type U where ReturnType is not void."); + } if (!EventEmitter.EventMap.has(idof())) { EventEmitter.EventMap.set(idof(), new Map()); } @@ -14,9 +16,8 @@ export class EventEmitter { if (ClassEvents.has(event)) { throw new Error("EventMap already contains a definition for event: " + event); } - let definition: u64 = idof() | (length << 32); + let definition: u64 = idof() | (ParameterCount() << 32); ClassEvents.set(event, definition); - log(definition); } private _events: Map = new Map(); @@ -30,10 +31,9 @@ export class EventEmitter { if (!EventMap.has(rtId)) throw new Error("Cannot attach events to an EventEmitter with no EventMap definitions."); let ClassEvents = EventMap.get(rtId); if (!ClassEvents.has(event)) throw new Error("Event does not exist: " + event); - let cbId = idof(); let classEventSignature = ClassEvents.get(event); let classEventCallbackID = (classEventSignature & 0xFFFFFFFF); - assert(cbId == classEventCallbackID); + assert(idof() == classEventCallbackID); if (!this._events.has(event)) this._events.set(event, new Array()); let eventList = this._events.get(event); eventList.push(changetype(callback)); diff --git a/assembly/node.d.ts b/assembly/node.d.ts index d6da2cb..b874f7e 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -14,3 +14,12 @@ declare class Buffer extends Uint8Array { /** Reads a signed integer at the designated offset. */ readInt8(offset?: i32): i8; } + +export abstract class EventEmitter { + /** Call this function globally to setup a callback on your EventEmitter type `T`, with callback type `U`, and eventName `event`. */ + public static registerEventCallback(event: string): void; + /** Register a callback event of type `T` with eventName `event`. Multiple calls passing the same combination of eventName and listener will result in the listener being added, and called, multiple times. */ + public on(event: string, callback: T): this; + /** Emit a callback event with the given parameters (up to 10.) */ + public emit(...args: T): this; +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 27277bb..945e341 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,8 +25,7 @@ "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "dev": true + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "ansi-styles": { "version": "3.2.1", @@ -38,9 +37,8 @@ } }, "assemblyscript": { - "version": "github:jtenner/assemblyscript#a93c3de2b51deccc24bf3d6971f5ca8da3d53dd6", - "from": "github:jtenner/assemblyscript#idof-dist", - "dev": true, + "version": "github:jtenner/assemblyscript#544fdfe4beff1272875950b833e8badf549c989e", + "from": "github:jtenner/assemblyscript#builtins-dist", "requires": { "@protobufjs/utf8": "^1.1.0", "binaryen": "87.0.0-nightly.20190716", @@ -53,14 +51,12 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "binaryen": { "version": "87.0.0-nightly.20190716", "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-87.0.0-nightly.20190716.tgz", - "integrity": "sha512-qRGfV8cLV4HVVo1oUCtTaDmOhbwctaW7vyW0G6HKftywWOJI9t9IsCrUEFKya50RqyEnanuS2w3nfOg4bxTGqg==", - "dev": true + "integrity": "sha512-qRGfV8cLV4HVVo1oUCtTaDmOhbwctaW7vyW0G6HKftywWOJI9t9IsCrUEFKya50RqyEnanuS2w3nfOg4bxTGqg==" }, "bindings": { "version": "1.5.0", @@ -75,7 +71,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -84,8 +79,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "chalk": { "version": "2.4.2", @@ -116,8 +110,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "csv-stringify": { "version": "5.3.0", @@ -144,14 +137,12 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -171,7 +162,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -180,8 +170,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "lodash.get": { "version": "4.4.2", @@ -193,14 +182,12 @@ "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -209,7 +196,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -217,26 +203,22 @@ "opencollective-postinstall": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-support": { "version": "0.5.12", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -262,8 +244,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" } } } diff --git a/package.json b/package.json index f006230..6b1d294 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,13 @@ }, "devDependencies": { "@as-pect/core": "^2.3.1", - "assemblyscript": "github:jtenner/assemblyscript#idof-dist", "glob": "^7.1.4", "wasi": "github:devsnek/node-wasi" }, "scripts": { "test": "node tests/node" }, - "dependencies": {} + "dependencies": { + "assemblyscript": "github:jtenner/assemblyscript#builtins-dist" + } } diff --git a/tests/events.spec.ts b/tests/events.spec.ts index 42600bf..fba978a 100644 --- a/tests/events.spec.ts +++ b/tests/events.spec.ts @@ -6,8 +6,8 @@ type i32Callback = (a: i32) => void; type i64Callback = (a: i64, b: i64) => void; class CustomEventEmitter extends EventEmitter {} -EventEmitter.registerEventCallback("data", 1); -EventEmitter.registerEventCallback("data2", 2); +EventEmitter.registerEventCallback("data"); +EventEmitter.registerEventCallback("data2"); describe("events", () => { test("events", () => { @@ -17,7 +17,7 @@ describe("events", () => { calls += 1; expect(wrongName).toBe(42); }); - t.emit("data", 42); + t.emit("data", 42,); t.emit("data", 42); t.emit("data", 42); expect(calls).toBe(3); From 9da090e525f84538018e2a5c3ead7fa20278bfbd Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Wed, 31 Jul 2019 16:36:39 -0400 Subject: [PATCH 5/5] [Update] experimental builtins in assemblyscript package --- assembly/events/index.ts | 23 +++++------------- package-lock.json | 51 +++++++++++++++++++++++++++------------- package.json | 5 ++-- 3 files changed, 43 insertions(+), 36 deletions(-) diff --git a/assembly/events/index.ts b/assembly/events/index.ts index 20f2a76..8514a08 100644 --- a/assembly/events/index.ts +++ b/assembly/events/index.ts @@ -3,29 +3,18 @@ import { BLOCK_OVERHEAD, BLOCK } from "rt/common"; export abstract class EventEmitter { public static EventMap: Map> = new Map>(); public static registerEventCallback(event: string): void { - if (!isFunction()) { - ERROR("Cannot register event callback of type U where U is not a function."); - } - if (!isVoid>()) { - ERROR("Cannot register event callback of type U where ReturnType is not void."); - } - if (!EventEmitter.EventMap.has(idof())) { - EventEmitter.EventMap.set(idof(), new Map()); - } + if (!isFunction()) ERROR("Cannot register event callback of type U where U is not a function."); + if (!isVoid>()) ERROR("Cannot register event callback of type U where ReturnType is not void."); + if (!EventEmitter.EventMap.has(idof())) EventEmitter.EventMap.set(idof(), new Map()); let ClassEvents = EventEmitter.EventMap.get(idof()); - if (ClassEvents.has(event)) { - throw new Error("EventMap already contains a definition for event: " + event); - } - let definition: u64 = idof() | (ParameterCount() << 32); - ClassEvents.set(event, definition); + if (ClassEvents.has(event)) throw new Error("EventMap already contains a definition for event: " + event); + ClassEvents.set(event, idof() | (lengthof() << 32)); } private _events: Map = new Map(); public on(event: string, callback: T): EventEmitter { - if (!isFunction()) { - ERROR("EventEmitter#on can only be called with a callback of type T where T is a static function."); - } + if (!isFunction()) ERROR("EventEmitter#on can only be called with a callback of type T where T is a static function."); let rtId = changetype(changetype(this) - BLOCK_OVERHEAD).rtId; let EventMap = EventEmitter.EventMap; if (!EventMap.has(rtId)) throw new Error("Cannot attach events to an EventEmitter with no EventMap definitions."); diff --git a/package-lock.json b/package-lock.json index 945e341..b4520b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,8 @@ "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", + "dev": true }, "ansi-styles": { "version": "3.2.1", @@ -37,8 +38,9 @@ } }, "assemblyscript": { - "version": "github:jtenner/assemblyscript#544fdfe4beff1272875950b833e8badf549c989e", + "version": "github:jtenner/assemblyscript#dd04610acdfea0fd914ab5dba02412f788174728", "from": "github:jtenner/assemblyscript#builtins-dist", + "dev": true, "requires": { "@protobufjs/utf8": "^1.1.0", "binaryen": "87.0.0-nightly.20190716", @@ -51,12 +53,14 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "binaryen": { "version": "87.0.0-nightly.20190716", "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-87.0.0-nightly.20190716.tgz", - "integrity": "sha512-qRGfV8cLV4HVVo1oUCtTaDmOhbwctaW7vyW0G6HKftywWOJI9t9IsCrUEFKya50RqyEnanuS2w3nfOg4bxTGqg==" + "integrity": "sha512-qRGfV8cLV4HVVo1oUCtTaDmOhbwctaW7vyW0G6HKftywWOJI9t9IsCrUEFKya50RqyEnanuS2w3nfOg4bxTGqg==", + "dev": true }, "bindings": { "version": "1.5.0", @@ -71,6 +75,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -79,7 +84,8 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, "chalk": { "version": "2.4.2", @@ -110,7 +116,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "csv-stringify": { "version": "5.3.0", @@ -137,12 +144,14 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -162,6 +171,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -170,7 +180,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "lodash.get": { "version": "4.4.2", @@ -182,12 +193,14 @@ "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -196,6 +209,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -203,22 +217,26 @@ "opencollective-postinstall": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==" + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true }, "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -244,7 +262,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true } } } diff --git a/package.json b/package.json index 6b1d294..cb65b0c 100644 --- a/package.json +++ b/package.json @@ -13,13 +13,12 @@ }, "devDependencies": { "@as-pect/core": "^2.3.1", + "assemblyscript": "github:jtenner/assemblyscript#builtins-dist", "glob": "^7.1.4", "wasi": "github:devsnek/node-wasi" }, "scripts": { "test": "node tests/node" }, - "dependencies": { - "assemblyscript": "github:jtenner/assemblyscript#builtins-dist" - } + "dependencies": {} }