UNPKG

@tamgl/colyseus-schema

Version:

Binary state serializer with delta encoding for games

116 lines (92 loc) 3.37 kB
import { Class, Property, File, getCommentHeader, getInheritanceTree, Context } from "../types"; import { GenerateOptions } from "../api"; const typeMaps = { "string": "string", "number": "number", "boolean": "boolean", "int8": "number", "uint8": "number", "int16": "number", "uint16": "number", "int32": "number", "uint32": "number", "int64": "number", "uint64": "number", "float32": "number", "float64": "number", } const distinct = (value, index, self) => self.indexOf(value) === index; export function generate (context: Context, options: GenerateOptions): File[] { return context.classes.map(klass => ({ name: klass.name + ".js", content: generateClass(klass, options.namespace, context.classes) })); } function generateClass(klass: Class, namespace: string, allClasses: Class[]) { const allRefs: Property[] = []; klass.properties.forEach(property => { let type = property.type; // keep all refs list if ((type === "ref" || type === "array" || type === "map")) { allRefs.push(property); } }); return `${getCommentHeader()} const schema = require("@colyseus/schema"); const Schema = schema.Schema; const type = schema.type; ${allRefs. filter(ref => ref.childType && typeMaps[ref.childType] === undefined). map(ref => ref.childType). concat(getInheritanceTree(klass, allClasses, false).map(klass => klass.name)). filter(distinct). map(childType => `const ${childType} = require("./${childType}");`). join("\n")} class ${klass.name} extends ${klass.extends} { constructor () { super(); ${klass.properties. filter(prop => prop.childType !== undefined). map(prop => " " + generatePropertyInitializer(prop)).join("\n")} } } ${klass.properties.map(prop => generatePropertyDeclaration(klass.name, prop)).join("\n")} export default ${klass.name}; `; } function generatePropertyDeclaration(className: string, prop: Property) { let typeArgs: string; if (prop.childType) { const isUpcaseFirst = prop.childType.match(/^[A-Z]/); if (isUpcaseFirst) { typeArgs += `, ${prop.childType}`; } else { typeArgs += `, "${prop.childType}"`; } if(prop.type === "ref") { typeArgs = `${prop.childType}`; } else if(prop.type === "array") { typeArgs = (isUpcaseFirst) ? `[ ${prop.childType} ]` : `[ "${prop.childType}" ]`; } else if(prop.type === "map") { typeArgs = (isUpcaseFirst) ? `{ map: ${prop.childType} }` : `{ map: "${prop.childType}" }`; } } else { typeArgs = `"${prop.type}"`; } return `type(${typeArgs})(${className}.prototype, "${prop.name}");`; } function generatePropertyInitializer(prop: Property) { let initializer = ""; if(prop.type === "ref") { initializer = `new ${prop.childType}()`; } else if(prop.type === "array") { initializer = `new schema.ArraySchema()`; } else if(prop.type === "map") { initializer = `new schema.MapSchema()`; } return `this.${prop.name} = ${initializer}`; }