diff --git a/demo/chat/chat.js b/demo/chat/chat.js index 99a042d..f76a074 100644 --- a/demo/chat/chat.js +++ b/demo/chat/chat.js @@ -37,16 +37,7 @@ var server; class MyChat extends IResource { - // void (string, string)->void - static get templateOld() { - return { - namespace: "Chat", - properties: [["title", String], ["messages", Array], ["users", Array]], - events: [["message", Map], ["voice", 0, {listenable: true }], ["login"], ["logout"]], - functions: [[ "send", [["msg", String, {optional: true}] ]]] - }; - } - + static get template() { return new TemplateDescriber("Chat",[ new Prop("title", String), new Prop("messages", Array), new Prop("users", Array), diff --git a/demo/mongo/mongo.js b/demo/mongo/mongo.js index 07ce67a..597a415 100644 --- a/demo/mongo/mongo.js +++ b/demo/mongo/mongo.js @@ -15,7 +15,7 @@ import { Prop, TemplateDescriber } from "../../src/Resource/Template/TemplateDes class User extends IResource { static get template() { - return new TemplateDescriber("Esiur", [new Prop("username", String), new Prop("password", String)]); + return new TemplateDescriber("Demo", [new Prop("username", String), new Prop("password", String)]); } } diff --git a/src/Data/DataSerializer.js b/src/Data/DataSerializer.js index 4a55835..782b6cf 100644 --- a/src/Data/DataSerializer.js +++ b/src/Data/DataSerializer.js @@ -135,16 +135,16 @@ export default class DataSerializer { return new DataSerializerComposeResults( TransmissionTypeIdentifier.Null, new DC(0)); - var cts = template.constants.where((x) => x.value == value); + var cts = template.constants.filter((x) => x.value == value); - if (cts.isEmpty) + if (cts.length == 0) return new DataSerializerComposeResults( TransmissionTypeIdentifier.Null, new DC(0)); var rt = BinaryList(); rt.addGuid(template.classId); - rt.addUint8(cts.first.index); + rt.addUint8(cts[0].index); return new DataSerializerComposeResults( TransmissionTypeIdentifier.Enum, rt.toDC()); diff --git a/src/Data/KeyList.js b/src/Data/KeyList.js index 9227c64..bca53e8 100644 --- a/src/Data/KeyList.js +++ b/src/Data/KeyList.js @@ -132,6 +132,13 @@ export default class KeyList this.removeAt(0); } + first(selector) { + for(let v of this.values) + if (selector(v)) + return v; + return null; + } + filter(selector) { if (selector instanceof Function){ diff --git a/src/Proxy/ResourceProxy.js b/src/Proxy/ResourceProxy.js index fccfdf6..4596b63 100644 --- a/src/Proxy/ResourceProxy.js +++ b/src/Proxy/ResourceProxy.js @@ -3,38 +3,85 @@ import Warehouse from "../Resource/Warehouse.js"; export default class ResourceProxy { static cache = {}; - static getProxy(type) { - let template = Warehouse.getTemplateByType(type); - let className = type.prototype.constructor.name; - let classUrl = "esiur://" + template.className.replace('.', '/'); + static getBase(type) { + if (type.baseType != null) + return type.baseType; + + return type; + } - if (template.namespace != null) { - className = template.namespace + "_" + className; - } + static getProxy(type) { + + if (type.baseType != null) + return type; + + let template = Warehouse.getTemplateByType(type); + let className = template.className; + if (ResourceProxy.cache[className]) return ResourceProxy.cache[className]; + + //let classUrl = "esiur://" + className.replace('.', '/'); - var code = `return ( class E_${className} extends b { constructor() {super();} `; + // var code = `return ( class E_${className.replace('.', '/')} extends b { constructor() {super();} `; - // generate class - for (var i = 0; i < template.properties.length; i++) { + // // generate class + // for (var i = 0; i < template.properties.length; i++) { + // let pt = template.properties[i]; + // let desc = Object.getOwnPropertyDescriptor(type.prototype, pt.name); + // if (desc) { + // code += `\r\n\tset ${pt.name}(v) {\r\n\t\tsuper.${pt.name} = v; \r\n\t\t if (this.instance) this.instance.emitModification(this.instance.template.properties[${i}], v); } \r\n\tget ${pt.name}() { \r\n\t\treturn super.${pt.name};}`; + // } + // else { + // code += `\r\n\tset ${pt.name}(v) {\r\n\t\tsuper._${pt.name} = v; \r\n\t\t if (this.instance) this.instance.emitModification(this.instance.template.properties[${i}], v); } \r\n\tget ${pt.name}() { \r\n\t\treturn this._${pt.name};}`; + // } + // } + + // var func = new Function("b", `//# sourceURL=${classUrl} \r\n ${code}});`); + // let proxyType = func.call(type /* this */, type); + + + const makeClass = (name) => ({[name] : class extends type {}})[name]; + + let proxyType = makeClass(className.replace('.', '_')); + + for (let i = 0; i < template.properties.length; i++) { let pt = template.properties[i]; let desc = Object.getOwnPropertyDescriptor(type.prototype, pt.name); if (desc) { - code += `\r\n set ${pt.name}(v) { \r\n super.${pt.name} = v; \r\n if (this.instance) this.instance.emitModification(this.instance.template.properties[${i}], v); } \r\n get ${pt.name}() { \r\n return super.${pt.name};}`; + Object.defineProperty(proxyType.prototype, pt.name, { + get() { + // call parent getter + return desc.get?.apply(this); + }, + set(value) { + // call parent setter + desc.set?.call(this, value); + this.instance?.emitModification(pt, value); + } + }); } else { - code += `\r\n set ${pt.name}(v) { \r\n super._${pt.name} = v; \r\n if (this.instance) this.instance.emitModification(this.instance.template.properties[${i}], v); } \r\n get ${pt.name}() { \r\n return this._${pt.name};}`; + Object.defineProperty(proxyType.prototype, pt.name, { + get() { + // get the backing field + return this["_" + pt.name]; + }, + set(value) { + // set the backing field + this["_" + pt.name] = value; + this.instance?.emitModification(pt, value); + } + }); } } - var func = new Function("b", `//# sourceURL=${classUrl} \r\n ${code}});`); - - var proxyType = func.call(type /* this */, type); - ResourceProxy.cache[className] = proxyType; + Object.defineProperty(proxyType, "baseType", {value: type}); + //Object.defineProperty(proxyType, "name", {value: className.replace('.', '_')}); + return proxyType; } diff --git a/src/Proxy/TemplateGenerator.js b/src/Proxy/TemplateGenerator.js index 01b94c8..4b0e2f2 100644 --- a/src/Proxy/TemplateGenerator.js +++ b/src/Proxy/TemplateGenerator.js @@ -333,11 +333,13 @@ export default class TemplateGenerator { rt += `export default class ${className} extends Esiur.Data.IEnum {\r\n`; + let options = []; template.constants.forEach((c) => { rt += `\tstatic ${c.name} = new ${className}(${c.index}, ${c.value}, '${c.name}');\r\n`; + options.push(`this.${c.name}`); }); - rt += "\r\n"; + rt += `\r\n\tstatic options = [${options.join(', ')}];\r\n`; // add template var descConsts = template.constants.map((p) => { @@ -396,14 +398,14 @@ export default class TemplateGenerator { // rt += "}\r\n"; template.constants.forEach((c) => { - var ctTypeName = this.getTypeName(template, c.valueType, templates, dependencies); + let ctTypeName = this.getTypeName(template, c.valueType, templates, dependencies); rt += `\tstatic ${c.name} = new ${ctTypeName}(${c.value});\r\n`; }); template.functions.filter((f) => !f.inherited).forEach((f) => { - var rtTypeName = this.getDecoratedTypeName(template, f.returnType, templates); - var positionalArgs = f.args.filter((x) => !x.optional); - var optionalArgs = f.args.filter((x) => x.optional); + let rtTypeName = this.getDecoratedTypeName(template, f.returnType, templates); + let positionalArgs = f.args.filter((x) => !x.optional); + let optionalArgs = f.args.filter((x) => x.optional); if (f.isStatic) { //rt += `static AsyncReply<${rtTypeName}> ${f.name}(DistributedConnection connection`; diff --git a/src/Resource/Warehouse.js b/src/Resource/Warehouse.js index c43bc3f..fbf1cce 100644 --- a/src/Resource/Warehouse.js +++ b/src/Resource/Warehouse.js @@ -315,6 +315,12 @@ export class WH extends IEventHandler if (type == null) return null; + // search our records + + let template = this.templates.first(x=> x.defineType == type); + if (template != null) + return template; + let templateType; if (type.prototype instanceof IResource) @@ -334,22 +340,22 @@ export class WH extends IEventHandler || type.prototype instanceof IRecord)) return false; - let className = type.prototype.constructor.name; + // let className = type.prototype.constructor.name; - if (className.startsWith("E_")) - className = className.substr(2); + // if (className.startsWith("E_")) + // className = className.substr(2); - className = type.template.namespace + "." + (type.template.className ?? className); + // className = type.template.namespace + "." + (type.template.className ?? className); - var templates = this.templates.get(templateType); + // var templates = this.templates.get(templateType); - // loaded ? - for(var i = 0; i < templates.length; i++) - if (templates.at(i).className == className) - return templates.at(i); + // // loaded ? + // for(var i = 0; i < templates.length; i++) + // if (templates.at(i).className == className) + // return templates.at(i); - var template = new TypeTemplate(type, true); + template = new TypeTemplate(type, true); return template; }