From d26d60fbba6705b78f895381a34a538d469c709f Mon Sep 17 00:00:00 2001 From: bilou84 Date: Sat, 17 Dec 2016 17:59:20 +0100 Subject: [PATCH 1/8] Make server side build precompile scripts rather than doing it at runtime (client build not working yet) --- .../default/gameSettings/build/buildGame.ts | 8 +- .../typescript/compiler/compileGame.ts | 84 +++++++++++++++ .../compileTypeScript.ts | 0 .../default/typescript/data/ScriptAsset.ts | 6 +- plugins/default/typescript/runtime/script.ts | 100 +----------------- server/index.ts | 34 +++++- 6 files changed, 124 insertions(+), 108 deletions(-) create mode 100644 plugins/default/typescript/compiler/compileGame.ts rename plugins/default/typescript/{runtime => compiler}/compileTypeScript.ts (100%) diff --git a/plugins/default/gameSettings/build/buildGame.ts b/plugins/default/gameSettings/build/buildGame.ts index d438d294e..d088c23ff 100644 --- a/plugins/default/gameSettings/build/buildGame.ts +++ b/plugins/default/gameSettings/build/buildGame.ts @@ -58,7 +58,11 @@ function onEntriesReceived(theEntries: SupCore.Data.Entries) { // Assets entries.walk((entry) => { - if (entry.type != null) { + if (entry.type === "script") + { + // TODO: do something :D + } + else if (entry.type != null) { // Only subscribe to assets that can be exported if (SupCore.system.data.assetClasses[entry.type].prototype.clientExport != null) { const subscriber = { onAssetReceived }; @@ -144,7 +148,7 @@ function onEntriesReceived(theEntries: SupCore.Data.Entries) { function onManifestReceived(err: string, manifestPub: SupCore.Data.ProjectManifestPub) { projectClient.socket.emit("unsub", "manifest"); - const exportedProject = { name: manifestPub.name, assets: entries.getForStorage() }; + const exportedProject = { name: manifestPub.name, assets: entries.getForStorage(["script"]) }; const json = JSON.stringify(exportedProject, null, 2); const projectPath = `${settings.outputFolder}/project.json`; diff --git a/plugins/default/typescript/compiler/compileGame.ts b/plugins/default/typescript/compiler/compileGame.ts new file mode 100644 index 000000000..e9c46d938 --- /dev/null +++ b/plugins/default/typescript/compiler/compileGame.ts @@ -0,0 +1,84 @@ +/// + +import compileTypescript from "./compileTypeScript"; +import * as convert from "convert-source-map"; + +// No definition file for combine-source-map module +/* tslint:disable-next-line */ +const combine: any = require("combine-source-map"); + +export default function compileGame(server: ProjectServer, scriptNames: string[], scripts: { [name: string]: string }, callback: (err: string, code: string) => void) { + const globalNames: string[] = []; + const globals: {[name: string]: string} = {}; + const globalDefs: {[name: string]: string} = {}; + + const actorComponentAccessors: string[] = []; + + const plugins = server.system.getPlugins("typescriptAPI"); + for (const pluginName in plugins) { + const plugin = plugins[pluginName]; + if (plugin.code != null) { + globalNames.push(`${pluginName}.ts`); + globals[`${pluginName}.ts`] = plugin.code; + } + + if (plugin.defs != null) globalDefs[`${pluginName}.d.ts`] = plugin.defs; + if (plugin.exposeActorComponent != null) actorComponentAccessors.push(`${plugin.exposeActorComponent.propertyName}: ${plugin.exposeActorComponent.className};`); + } + + // Plug component accessors exposed by plugins into Sup.Actor class + const joinedActorComponentAccessors = actorComponentAccessors.join("\n "); + globals["Sup.Actor.ts"] = globals["Sup.Actor.ts"].replace("// INSERT_COMPONENT_ACCESSORS", joinedActorComponentAccessors); + globalDefs["Sup.Actor.d.ts"] = globalDefs["Sup.Actor.d.ts"].replace("// INSERT_COMPONENT_ACCESSORS", joinedActorComponentAccessors); + + // Make sure the Sup namespace, Sup.Actor and Sup.ActorComponent are compiled before everything else + globalNames.unshift(globalNames.splice(globalNames.indexOf("Sup.Actor.ts"), 1)[0]); + globalNames.unshift(globalNames.splice(globalNames.indexOf("Sup.ts"), 1)[0]); + + // Compile plugin globals + const libSource = `${globalDefs["lib.d.ts"]}\ndeclare var console, window, localStorage, player, SupEngine, SupRuntime, require;`; + const jsGlobals = compileTypescript(globalNames, globals, libSource, { sourceMap: false }); + if (jsGlobals.errors.length > 0) { + for (const error of jsGlobals.errors) console.log(`${error.file}(${error.position.line}): ${error.message}`); + callback("Compilation failed. Check the devtools (F12) for errors.", null); + return; + } + + // Compile game scripts + let concatenatedGlobalDefs = ""; + for (const name in globalDefs) concatenatedGlobalDefs += globalDefs[name]; + const results = compileTypescript(scriptNames, scripts, concatenatedGlobalDefs, { sourceMap: true }); + if (results.errors.length > 0) { + for (const error of results.errors) console.log(`${error.file}(${error.position.line}): ${error.message}`); + callback("Compilation failed. Check the devtools (F12) for errors.", null); + return; + } + + // Prepare source maps + const getLineCounts = (text: string) => { + let count = 1, index = -1; + while (true) { + index = text.indexOf("\n", index + 1); + if (index === -1) break; + count++; + } + return count; + }; + + jsGlobals.script = `(function() { +var player = _player; _player = undefined; +${jsGlobals.script} +})(); +`; + + let line = getLineCounts(jsGlobals.script) + 2; + const combinedSourceMap = combine.create("bundle.js"); + for (const file of results.files) { + const comment = convert.fromObject(results.sourceMaps[file.name]).toComment(); + combinedSourceMap.addFile({ sourceFile: `${server.data.manifest.pub.name}/${file.name}`, source: file.text + `\n${comment}` }, { line }); + line += getLineCounts(file.text); + } + + const code = `${jsGlobals.script}${results.script}//# sourceMappingURL=data:application/json;charset=utf-8;base64,${combinedSourceMap.base64()}`; + callback(null, code); +} diff --git a/plugins/default/typescript/runtime/compileTypeScript.ts b/plugins/default/typescript/compiler/compileTypeScript.ts similarity index 100% rename from plugins/default/typescript/runtime/compileTypeScript.ts rename to plugins/default/typescript/compiler/compileTypeScript.ts diff --git a/plugins/default/typescript/data/ScriptAsset.ts b/plugins/default/typescript/data/ScriptAsset.ts index 108894050..d56fa779e 100644 --- a/plugins/default/typescript/data/ScriptAsset.ts +++ b/plugins/default/typescript/data/ScriptAsset.ts @@ -34,7 +34,7 @@ let globalDefs = ""; if ((global).window == null) { const serverRequire = require; ts = serverRequire("typescript"); - compileTypeScript = serverRequire("../runtime/compileTypeScript").default; + compileTypeScript = serverRequire("../compiler/compileTypeScript").default; SupCore.system.requireForAllPlugins("typescriptAPI/index.js"); const plugins = SupCore.system.getPlugins("typescriptAPI"); @@ -220,10 +220,6 @@ Sup.registerBehavior(${behaviorName}); }); } - clientExport(outputPath: string, callback: (err: Error) => void) { - this.write(SupApp.writeFile, outputPath, callback); - } - private write(writeFile: Function, outputPath: string, callback: (err: Error) => void) { writeFile(path.join(outputPath, "script.ts"), this.pub.text, { encoding: "utf8" }, callback); } diff --git a/plugins/default/typescript/runtime/script.ts b/plugins/default/typescript/runtime/script.ts index cdc65b217..2f4d0d6e5 100644 --- a/plugins/default/typescript/runtime/script.ts +++ b/plugins/default/typescript/runtime/script.ts @@ -1,21 +1,6 @@ /// -import * as convert from "convert-source-map"; -// No definition file for combine-source-map module -/* tslint:disable */ -const combine: any = require("combine-source-map"); -/* tslint:enable */ -import compileTypeScript from "./compileTypeScript"; - -const globalNames: string[] = []; -const globals: {[name: string]: string} = {}; -const globalDefs: {[name: string]: string} = {}; - -const scriptNames: string[] = []; -const scripts: {[name: string]: string} = {}; - const actorComponentTypesByName: {[name: string]: any} = {}; -const actorComponentAccessors: string[] = []; export function init(player: any, callback: Function) { player.behaviorClasses = {}; @@ -44,91 +29,14 @@ export function init(player: any, callback: Function) { return new actorComponentTypesByName[type](actor); } }; - - for (const pluginName in plugins) { - const plugin = plugins[pluginName]; - if (plugin.code != null) { - globalNames.push(`${pluginName}.ts`); - globals[`${pluginName}.ts`] = plugin.code; - } - - if (plugin.defs != null) globalDefs[`${pluginName}.d.ts`] = plugin.defs; - if (plugin.exposeActorComponent != null) actorComponentAccessors.push(`${plugin.exposeActorComponent.propertyName}: ${plugin.exposeActorComponent.className};`); - } callback(); } export function start(player: SupRuntime.Player, callback: Function) { - console.log("Compiling scripts..."); - - // Plug component accessors exposed by plugins into Sup.Actor class - const joinedActorComponentAccessors = actorComponentAccessors.join("\n "); - globals["Sup.Actor.ts"] = globals["Sup.Actor.ts"].replace("// INSERT_COMPONENT_ACCESSORS", joinedActorComponentAccessors); - globalDefs["Sup.Actor.d.ts"] = globalDefs["Sup.Actor.d.ts"].replace("// INSERT_COMPONENT_ACCESSORS", joinedActorComponentAccessors); - - // Make sure the Sup namespace, Sup.Actor and Sup.ActorComponent are compiled before everything else - globalNames.unshift(globalNames.splice(globalNames.indexOf("Sup.Actor.ts"), 1)[0]); - globalNames.unshift(globalNames.splice(globalNames.indexOf("Sup.ts"), 1)[0]); - - // Compile plugin globals - const jsGlobals = compileTypeScript(globalNames, globals, `${globalDefs["lib.d.ts"]}\ndeclare var console, window, localStorage, player, SupEngine, SupRuntime, require;`, { sourceMap: false }); - if (jsGlobals.errors.length > 0) { - for (const error of jsGlobals.errors) console.log(`${error.file}(${error.position.line}): ${error.message}`); - callback(new Error("Compilation failed. Check the devtools (F12) for errors.")); - return; - } - - // Compile game scripts - let concatenatedGlobalDefs = ""; - for (const name in globalDefs) concatenatedGlobalDefs += globalDefs[name]; - const results = compileTypeScript(scriptNames, scripts, concatenatedGlobalDefs, { sourceMap: true }); - if (results.errors.length > 0) { - for (const error of results.errors) console.log(`${error.file}(${error.position.line}): ${error.message}`); - callback(new Error("Compilation failed. Check the devtools (F12) for errors.")); - return; - } - - console.log("Compilation successful!"); - - // Prepare source maps - const getLineCounts = (text: string) => { - let count = 1, index = -1; - while (true) { - index = text.indexOf("\n", index + 1); - if (index === -1) break; - count++; - } - return count; - }; - - jsGlobals.script = `(function() { -var player = _player; _player = undefined; -${jsGlobals.script} -})(); -`; - - let line = getLineCounts(jsGlobals.script) + 2; - const combinedSourceMap = combine.create("bundle.js"); - for (const file of results.files) { - const comment = convert.fromObject(results.sourceMaps[file.name]).toComment(); - combinedSourceMap.addFile({ sourceFile: `/${player.gameName}/${file.name}`, source: file.text + `\n${comment}` }, { line }); - line += getLineCounts(file.text); - } - - const code = `${jsGlobals.script}${results.script} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,${combinedSourceMap.base64()}`; - - // Execute the generated code - const scriptFunction = new Function("_player", code); - scriptFunction(player); - - callback(); -} + player.getAssetData(`script.js`, "text", (err, script) => { + const scriptFunction = new Function("_player", script); + scriptFunction(player); -export function loadAsset(player: SupRuntime.Player, entry: any, callback: (err: Error, asset?: any) => any) { - scriptNames.push(`${entry.path}.ts`); - player.getAssetData(`assets/${entry.storagePath}/script.ts`, "text", (err, script) => { - scripts[`${entry.path}.ts`] = `${script}\n`; - callback(null, script); + callback(); }); } diff --git a/server/index.ts b/server/index.ts index 992c852ed..208ed3e17 100644 --- a/server/index.ts +++ b/server/index.ts @@ -4,18 +4,33 @@ import * as fs from "fs"; import * as async from "async"; import * as mkdirp from "mkdirp"; -SupCore.system.serverBuild = (server: ProjectServer, buildPath: string, callback: (err: string) => void) => { - const exportedProject = { name: server.data.manifest.pub.name, assets: server.data.entries.getForStorage() }; +import compileGame from "../plugins/default/typescript/compiler/compileGame"; - fs.mkdirSync(`${buildPath}/assets`); +const scriptNames: string[] = []; +const scripts: {[name: string]: string} = {}; +SupCore.system.serverBuild = (server: ProjectServer, buildPath: string, callback: (err: string) => void) => { const assetIdsToExport: string[] = []; server.data.entries.walk((entry: SupCore.Data.EntryNode, parent: SupCore.Data.EntryNode) => { if (entry.type != null) assetIdsToExport.push(entry.id); }); + fs.mkdirSync(`${buildPath}/assets`); + scriptNames.length = 0; + async.each(assetIdsToExport, (assetId, cb) => { server.data.assets.acquire(assetId, null, (err: Error, asset: SupCore.Data.Base.Asset) => { + const entry = server.data.entries.byId[assetId]; + if (entry.type === "script") { + const scriptName = `${server.data.entries.getPathFromId(assetId)}.ts`; + scriptNames.push(scriptName); + scripts[scriptName] = `${asset.pub.text}\n`; + + server.data.assets.release(assetId, null); + cb(); + return; + } + const folderPath = `${buildPath}/assets/${server.data.entries.getStoragePathFromId(assetId)}`; mkdirp(folderPath, (err) => { asset.save(folderPath, (err) => { @@ -42,11 +57,20 @@ SupCore.system.serverBuild = (server: ProjectServer, buildPath: string, callback }, (err) => { if (err != null) { callback("Could not export all resources"); return; } - const json = JSON.stringify(exportedProject, null, 2); + const json = JSON.stringify({ name: server.data.manifest.pub.name, assets: server.data.entries.getForStorage(["script"]) }, null, 2); fs.writeFile(`${buildPath}/project.json`, json, { encoding: "utf8" }, (err) => { if (err != null) { callback("Could not save project.json"); return; } - callback(null); + // Pre-compile scripts + compileGame(server, scriptNames, scripts, (err, code) => { + if (err != null) { callback("Could not compile game"); return; } + + fs.writeFile(`${buildPath}/script.js`, code, { encoding: "utf8" }, (err) => { + if (err != null) { callback("Could not save script.js"); return; } + + callback(null); + }); + }); }); }); }); From ce29a03954c8156af121fd8e49217b9ee3baef54 Mon Sep 17 00:00:00 2001 From: bilou84 Date: Sat, 17 Dec 2016 19:31:19 +0100 Subject: [PATCH 2/8] Make client-side build precompile scripts too --- .../default/gameSettings/build/buildGame.ts | 60 ++++++++++++++----- .../typescript/compiler/compileGame.ts | 6 +- server/index.ts | 5 +- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/plugins/default/gameSettings/build/buildGame.ts b/plugins/default/gameSettings/build/buildGame.ts index d088c23ff..2d795b1aa 100644 --- a/plugins/default/gameSettings/build/buildGame.ts +++ b/plugins/default/gameSettings/build/buildGame.ts @@ -1,6 +1,8 @@ import * as async from "async"; import * as path from "path"; +import compileGame from "../../typescript/compiler/compileGame"; + let projectClient: SupClient.ProjectClient; const subscribersByAssetId: { [assetId: string]: SupClient.AssetSubscriber } = {}; const subscribersByResourceId: { [resourceId: string] : SupClient.ResourceSubscriber } = {}; @@ -15,6 +17,10 @@ const statusElt = document.querySelector(".status"); const progressElt = document.querySelector("progress") as HTMLProgressElement; const detailsListElt = document.querySelector(".details ol") as HTMLOListElement; +let gameName: string; +const scriptNames: string[] = []; +const scripts: {[name: string]: string} = {}; + interface ClientExportableAsset extends SupCore.Data.Base.Asset { clientExport: (outputPath: string, callback: (err: Error) => void) => void; } @@ -30,7 +36,7 @@ function loadPlugins(callback: Function) { (cb) => { async.each(SupCore.system.pluginsInfo.list, (pluginName, cb) => { const pluginPath = `/systems/${SupCore.system.id}/plugins/${pluginName}`; - async.each([ "data", "componentConfigs" ], (name, cb) => { + async.each([ "data", "componentConfigs", "typescriptAPI" ], (name, cb) => { SupClient.loadScript(`${pluginPath}/bundles/${name}.js`, cb); }, cb); }, cb); @@ -50,7 +56,6 @@ export default function build(socket: SocketIOClient.Socket, theSettings: GameBu function onEntriesReceived(theEntries: SupCore.Data.Entries) { entries = theEntries; - projectClient.unsubEntries(entriesSubscriber); // Manifest projectClient.socket.emit("sub", "manifest", null, onManifestReceived); @@ -58,18 +63,14 @@ function onEntriesReceived(theEntries: SupCore.Data.Entries) { // Assets entries.walk((entry) => { - if (entry.type === "script") - { - // TODO: do something :D - } - else if (entry.type != null) { - // Only subscribe to assets that can be exported - if (SupCore.system.data.assetClasses[entry.type].prototype.clientExport != null) { + if (entry.type != null) { + // Only subscribe to assets that can be exported and scripts + if (SupCore.system.data.assetClasses[entry.type].prototype.clientExport != null || entry.type === "script") { const subscriber = { onAssetReceived }; subscribersByAssetId[entry.id] = subscriber; projectClient.subAsset(entry.id, entry.type, subscriber); - progress.total++; + if (entry.type !== "script") progress.total++; } } }); @@ -148,7 +149,8 @@ function onEntriesReceived(theEntries: SupCore.Data.Entries) { function onManifestReceived(err: string, manifestPub: SupCore.Data.ProjectManifestPub) { projectClient.socket.emit("unsub", "manifest"); - const exportedProject = { name: manifestPub.name, assets: entries.getForStorage(["script"]) }; + gameName = manifestPub.name; + const exportedProject = { name: gameName, assets: entries.getForStorage(["script"]) }; const json = JSON.stringify(exportedProject, null, 2); const projectPath = `${settings.outputFolder}/project.json`; @@ -169,10 +171,33 @@ function updateProgress() { if (progress.index < progress.total) { statusElt.textContent = SupClient.i18n.t("builds:game.progress", { path: settings.outputFolder, index: progress.index, total: progress.total }); - } else if (progress.errors > 0) { - statusElt.textContent = SupClient.i18n.t("builds:game.doneWithErrors", { path: settings.outputFolder, total: progress.total, errors: progress.errors }); } else { - statusElt.textContent = SupClient.i18n.t("builds:game.done", { path: settings.outputFolder, total: progress.total }); + projectClient.unsubEntries(entriesSubscriber); + + statusElt.textContent = "Compiling scripts..."; + + compileGame(gameName, SupCore.system, scriptNames, scripts, (err, code) => { + if (err != null) { + progress.errors++; + SupClient.html("li", { parent: detailsListElt, textContent: "Compilation failed."}); + + statusElt.textContent = SupClient.i18n.t("builds:game.doneWithErrors", { path: settings.outputFolder, total: progress.total, errors: progress.errors }); + } else { + const outputPath = `${settings.outputFolder}/script.js`; + SupApp.writeFile(outputPath, code, { encoding: "utf8" }, (err) => { + if (err != null) { + progress.errors++; + SupClient.html("li", { parent: detailsListElt, textContent: SupClient.i18n.t("builds:game.errors.exportFailed", { path: outputPath }) }); + } + + if (progress.errors > 0) { + statusElt.textContent = SupClient.i18n.t("builds:game.doneWithErrors", { path: settings.outputFolder, total: progress.total, errors: progress.errors }); + } else { + statusElt.textContent = SupClient.i18n.t("builds:game.done", { path: settings.outputFolder, total: progress.total }); + } + }); + } + }); } } @@ -180,6 +205,13 @@ function onAssetReceived(assetId: string, asset: ClientExportableAsset) { projectClient.unsubAsset(assetId, subscribersByAssetId[assetId]); delete subscribersByAssetId[assetId]; + if (projectClient.entries.byId[assetId].type === "script") { + const scriptName = `${projectClient.entries.getPathFromId(assetId)}.ts`; + scriptNames.push(scriptName); + scripts[scriptName] = `${asset.pub.text}\n`; + return; + } + const outputFolder = `${settings.outputFolder}/assets/${entries.getStoragePathFromId(assetId)}`; SupApp.mkdirp(outputFolder, () => { diff --git a/plugins/default/typescript/compiler/compileGame.ts b/plugins/default/typescript/compiler/compileGame.ts index e9c46d938..5efb20f9e 100644 --- a/plugins/default/typescript/compiler/compileGame.ts +++ b/plugins/default/typescript/compiler/compileGame.ts @@ -7,14 +7,14 @@ import * as convert from "convert-source-map"; /* tslint:disable-next-line */ const combine: any = require("combine-source-map"); -export default function compileGame(server: ProjectServer, scriptNames: string[], scripts: { [name: string]: string }, callback: (err: string, code: string) => void) { +export default function compileGame(gameName: string, system: SupCore.System, scriptNames: string[], scripts: { [name: string]: string }, callback: (err: string, code: string) => void) { const globalNames: string[] = []; const globals: {[name: string]: string} = {}; const globalDefs: {[name: string]: string} = {}; const actorComponentAccessors: string[] = []; - const plugins = server.system.getPlugins("typescriptAPI"); + const plugins = system.getPlugins("typescriptAPI"); for (const pluginName in plugins) { const plugin = plugins[pluginName]; if (plugin.code != null) { @@ -75,7 +75,7 @@ ${jsGlobals.script} const combinedSourceMap = combine.create("bundle.js"); for (const file of results.files) { const comment = convert.fromObject(results.sourceMaps[file.name]).toComment(); - combinedSourceMap.addFile({ sourceFile: `${server.data.manifest.pub.name}/${file.name}`, source: file.text + `\n${comment}` }, { line }); + combinedSourceMap.addFile({ sourceFile: `${gameName}/${file.name}`, source: file.text + `\n${comment}` }, { line }); line += getLineCounts(file.text); } diff --git a/server/index.ts b/server/index.ts index 208ed3e17..9544826a0 100644 --- a/server/index.ts +++ b/server/index.ts @@ -57,12 +57,13 @@ SupCore.system.serverBuild = (server: ProjectServer, buildPath: string, callback }, (err) => { if (err != null) { callback("Could not export all resources"); return; } - const json = JSON.stringify({ name: server.data.manifest.pub.name, assets: server.data.entries.getForStorage(["script"]) }, null, 2); + const gameName = server.data.manifest.pub.name; + const json = JSON.stringify({ name: gameName, assets: server.data.entries.getForStorage(["script"]) }, null, 2); fs.writeFile(`${buildPath}/project.json`, json, { encoding: "utf8" }, (err) => { if (err != null) { callback("Could not save project.json"); return; } // Pre-compile scripts - compileGame(server, scriptNames, scripts, (err, code) => { + compileGame(gameName, server.system, scriptNames, scripts, (err, code) => { if (err != null) { callback("Could not compile game"); return; } fs.writeFile(`${buildPath}/script.js`, code, { encoding: "utf8" }, (err) => { From d7984d5f35cb22e5e8b48834e4da1fef10bb8fd8 Mon Sep 17 00:00:00 2001 From: bilou84 Date: Sun, 18 Dec 2016 00:23:32 +0100 Subject: [PATCH 3/8] Remove SupCore.js and typescriptAPI bundles from the build as we don't them anymore --- SupRuntime/SupRuntime.d.ts | 1 + SupRuntime/src/index.jade | 1 - SupRuntime/src/index.ts | 4 +--- plugins/default/arcadePhysics2D/runtime/ArcadeBody2D.ts | 2 ++ plugins/default/arcadePhysics2D/typescriptAPI/index.ts | 2 +- plugins/default/cubicModel/runtime/CubicModelRenderer.ts | 2 ++ plugins/default/cubicModel/typescriptAPI/index.ts | 2 +- plugins/default/font/runtime/TextRenderer.ts | 2 ++ plugins/default/font/typescriptAPI/index.ts | 2 +- plugins/default/gameSettings/build/buildGame.ts | 3 +-- plugins/default/light/runtime/Light.ts | 2 ++ plugins/default/light/typescriptAPI/index.ts | 2 +- plugins/default/model/runtime/ModelRenderer.ts | 2 ++ plugins/default/model/typescriptAPI/index.ts | 2 +- plugins/default/scene/runtime/Camera.ts | 2 ++ plugins/default/sprite/runtime/SpriteRenderer.ts | 2 ++ plugins/default/sprite/typescriptAPI/index.ts | 2 +- plugins/default/tileMap/runtime/TileMapRenderer.ts | 2 ++ plugins/default/tileMap/typescriptAPI/index.ts | 2 +- plugins/default/typescript/compiler/compileGame.ts | 2 +- plugins/default/typescript/data/ScriptAsset.ts | 2 +- plugins/default/typescript/editors/apiBrowser/index.ts | 4 ++-- plugins/default/typescript/editors/script/network.ts | 2 +- plugins/default/typescript/runtime/Behavior.ts | 2 ++ plugins/default/typescript/runtime/script.ts | 4 +--- .../default/typescript/typescriptAPI/TypeScriptAPIPlugin.d.ts | 2 +- plugins/default/typescript/typescriptAPI/index.ts | 2 +- plugins/extra/cannonjs/runtime/CannonBody.ts | 2 ++ plugins/extra/cannonjs/typescriptAPI/index.ts | 2 +- plugins/extra/p2js/runtime/P2Body.ts | 2 ++ plugins/extra/p2js/typescriptAPI/index.ts | 2 +- 31 files changed, 42 insertions(+), 25 deletions(-) diff --git a/SupRuntime/SupRuntime.d.ts b/SupRuntime/SupRuntime.d.ts index e2bfd2b77..0ef822ac5 100644 --- a/SupRuntime/SupRuntime.d.ts +++ b/SupRuntime/SupRuntime.d.ts @@ -5,6 +5,7 @@ declare namespace SupRuntime { loadAsset?(player: Player, entry: any, callback: (err: Error, asset?: any) => any): void; createOuterAsset?(player: Player, asset: any): any; setupComponent?(player: SupRuntime.Player, component: any, config: any): void; + componentClassName?: string; init?(player: Player, callback: Function): void; start?(player: Player, callback: Function): void; lateStart?(player: Player, callback: Function): void; diff --git a/SupRuntime/src/index.jade b/SupRuntime/src/index.jade index 947964dbb..75d8f4c43 100644 --- a/SupRuntime/src/index.jade +++ b/SupRuntime/src/index.jade @@ -11,6 +11,5 @@ html img(src="images/superpowers-splash.svg",draggable="false") progress(max="100",value="0") - script(src="SupCore.js") script(src="SupEngine.js") script(src="SupRuntime.js") diff --git a/SupRuntime/src/index.ts b/SupRuntime/src/index.ts index 67dd6fb11..7d0e2e08c 100644 --- a/SupRuntime/src/index.ts +++ b/SupRuntime/src/index.ts @@ -32,8 +32,6 @@ export function registerResource(name: string, plugin: SupRuntime.RuntimeResourc resourcePlugins[name] = plugin; } -SupCore.system = new SupCore.System("", ""); - // Setup SupApp if ((global as any).SupApp == null) { (global as any).SupApp = null; @@ -123,7 +121,7 @@ const onLoaded = (err: Error) => { }; // Load plugins -const pluginBundleNames = [ "components", "runtime", "typescriptAPI" ]; +const pluginBundleNames = [ "components", "runtime" ]; supFetch("plugins.json", "json", (err: Error, pluginsInfo: SupCore.PluginsInfo) => { if (err != null) { diff --git a/plugins/default/arcadePhysics2D/runtime/ArcadeBody2D.ts b/plugins/default/arcadePhysics2D/runtime/ArcadeBody2D.ts index aafdc1860..aef7cda5f 100644 --- a/plugins/default/arcadePhysics2D/runtime/ArcadeBody2D.ts +++ b/plugins/default/arcadePhysics2D/runtime/ArcadeBody2D.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.ArcadePhysics2D.Body"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { if (config.type === "box") component.setupBox(config); diff --git a/plugins/default/arcadePhysics2D/typescriptAPI/index.ts b/plugins/default/arcadePhysics2D/typescriptAPI/index.ts index 317765b05..4f2198ddf 100644 --- a/plugins/default/arcadePhysics2D/typescriptAPI/index.ts +++ b/plugins/default/arcadePhysics2D/typescriptAPI/index.ts @@ -10,5 +10,5 @@ SupCore.system.registerPlugin("typescriptAPI", "Sup SupCore.system.registerPlugin("typescriptAPI", "ArcadeBody2D", { code: fs.readFileSync(`${__dirname}/Sup.ArcadePhysics2D.Body.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.ArcadePhysics2D.Body.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "arcadeBody2D", className: "Sup.ArcadePhysics2D.Body" }, + exposeActorComponent: "arcadeBody2D: Sup.ArcadePhysics2D.Body;" }); diff --git a/plugins/default/cubicModel/runtime/CubicModelRenderer.ts b/plugins/default/cubicModel/runtime/CubicModelRenderer.ts index 87320f439..2bad926e0 100644 --- a/plugins/default/cubicModel/runtime/CubicModelRenderer.ts +++ b/plugins/default/cubicModel/runtime/CubicModelRenderer.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.CubicModelRenderer"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { // component.castShadow = config.castShadow; // component.receiveShadow = config.receiveShadow; diff --git a/plugins/default/cubicModel/typescriptAPI/index.ts b/plugins/default/cubicModel/typescriptAPI/index.ts index b7ee15e0f..5efeccf49 100644 --- a/plugins/default/cubicModel/typescriptAPI/index.ts +++ b/plugins/default/cubicModel/typescriptAPI/index.ts @@ -10,5 +10,5 @@ SupCore.system.registerPlugin("typescriptAPI", "Sup SupCore.system.registerPlugin("typescriptAPI", "CubicModelRenderer", { code: fs.readFileSync(`${__dirname}/Sup.CubicModelRenderer.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.CubicModelRenderer.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "cubicModelRenderer", className: "Sup.CubicModelRenderer" } + exposeActorComponent: "cubicModelRenderer: Sup.CubicModelRenderer;" }); diff --git a/plugins/default/font/runtime/TextRenderer.ts b/plugins/default/font/runtime/TextRenderer.ts index 94be3f429..a9e069b68 100644 --- a/plugins/default/font/runtime/TextRenderer.ts +++ b/plugins/default/font/runtime/TextRenderer.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.TextRenderer"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { component.setText(config.text); component.setOptions({ alignment: config.alignment, verticalAlignment: config.verticalAlignment, size: config.size, color: config.color }); diff --git a/plugins/default/font/typescriptAPI/index.ts b/plugins/default/font/typescriptAPI/index.ts index b88538868..8a714567c 100644 --- a/plugins/default/font/typescriptAPI/index.ts +++ b/plugins/default/font/typescriptAPI/index.ts @@ -10,5 +10,5 @@ SupCore.system.registerPlugin("typescriptAPI", "Sup SupCore.system.registerPlugin("typescriptAPI", "TextRenderer", { code: fs.readFileSync(`${__dirname}/Sup.TextRenderer.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.TextRenderer.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "textRenderer", className: "Sup.TextRenderer" } + exposeActorComponent: "textRenderer: Sup.TextRenderer;" }); diff --git a/plugins/default/gameSettings/build/buildGame.ts b/plugins/default/gameSettings/build/buildGame.ts index 2d795b1aa..0ee89f3ba 100644 --- a/plugins/default/gameSettings/build/buildGame.ts +++ b/plugins/default/gameSettings/build/buildGame.ts @@ -88,14 +88,13 @@ function onEntriesReceived(theEntries: SupCore.Data.Entries) { } // TODO: Extra build files - const systemBuildFiles = [ "/SupCore.js" ]; + const systemBuildFiles = []; const pluginsInfo = SupCore.system.pluginsInfo; const systemPath = `/systems/${SupCore.system.id}`; for (const plugin of pluginsInfo.list) { systemBuildFiles.push(`${systemPath}/plugins/${plugin}/bundles/components.js`); systemBuildFiles.push(`${systemPath}/plugins/${plugin}/bundles/runtime.js`); - systemBuildFiles.push(`${systemPath}/plugins/${plugin}/bundles/typescriptAPI.js`); } systemBuildFiles.push(`${systemPath}/plugins.json`); diff --git a/plugins/default/light/runtime/Light.ts b/plugins/default/light/runtime/Light.ts index 40470fc60..2eec8cb43 100644 --- a/plugins/default/light/runtime/Light.ts +++ b/plugins/default/light/runtime/Light.ts @@ -16,6 +16,8 @@ export function init(player: any, callback: Function) { callback(); } +export const componentClassName = "Sup.Light"; + export function setupComponent(player: SupRuntime.Player, component: Light, config: any) { (component).__outer.type = ["ambient", "point", "spot", "directional"].indexOf(config.type); component.color = parseInt(config.color, 16); diff --git a/plugins/default/light/typescriptAPI/index.ts b/plugins/default/light/typescriptAPI/index.ts index bbeb5f1c1..1f46596fc 100644 --- a/plugins/default/light/typescriptAPI/index.ts +++ b/plugins/default/light/typescriptAPI/index.ts @@ -5,5 +5,5 @@ import * as fs from "fs"; SupCore.system.registerPlugin("typescriptAPI", "Light", { code: fs.readFileSync(`${__dirname}/Sup.Light.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.Light.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "light", className: "Sup.Light" } + exposeActorComponent: "light: Sup.Light;" }); diff --git a/plugins/default/model/runtime/ModelRenderer.ts b/plugins/default/model/runtime/ModelRenderer.ts index 743a799ef..fb06c7ad7 100644 --- a/plugins/default/model/runtime/ModelRenderer.ts +++ b/plugins/default/model/runtime/ModelRenderer.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.ModelRenderer"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { component.castShadow = config.castShadow; component.receiveShadow = config.receiveShadow; diff --git a/plugins/default/model/typescriptAPI/index.ts b/plugins/default/model/typescriptAPI/index.ts index 06f3589a6..b57a3518c 100644 --- a/plugins/default/model/typescriptAPI/index.ts +++ b/plugins/default/model/typescriptAPI/index.ts @@ -10,5 +10,5 @@ SupCore.system.registerPlugin("typescriptAPI", "Sup SupCore.system.registerPlugin("typescriptAPI", "ModelRenderer", { code: fs.readFileSync(`${__dirname}/Sup.ModelRenderer.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.ModelRenderer.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "modelRenderer", className: "Sup.ModelRenderer" } + exposeActorComponent: "modelRenderer: Sup.ModelRenderer;" }); diff --git a/plugins/default/scene/runtime/Camera.ts b/plugins/default/scene/runtime/Camera.ts index 789ae843a..2a9a057fc 100644 --- a/plugins/default/scene/runtime/Camera.ts +++ b/plugins/default/scene/runtime/Camera.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.Camera"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { component.setOrthographicMode(config.mode === "orthographic"); component.setFOV(config.fov); diff --git a/plugins/default/sprite/runtime/SpriteRenderer.ts b/plugins/default/sprite/runtime/SpriteRenderer.ts index a339de072..206544596 100644 --- a/plugins/default/sprite/runtime/SpriteRenderer.ts +++ b/plugins/default/sprite/runtime/SpriteRenderer.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.SpriteRenderer"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { component.castShadow = config.castShadow; component.receiveShadow = config.receiveShadow; diff --git a/plugins/default/sprite/typescriptAPI/index.ts b/plugins/default/sprite/typescriptAPI/index.ts index 6247cee22..cf281ec20 100644 --- a/plugins/default/sprite/typescriptAPI/index.ts +++ b/plugins/default/sprite/typescriptAPI/index.ts @@ -10,5 +10,5 @@ SupCore.system.registerPlugin("typescriptAPI", "Sup SupCore.system.registerPlugin("typescriptAPI", "SpriteRenderer", { code: fs.readFileSync(`${__dirname}/Sup.SpriteRenderer.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.SpriteRenderer.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "spriteRenderer", className: "Sup.SpriteRenderer" } + exposeActorComponent: "spriteRenderer: Sup.SpriteRenderer;" }); diff --git a/plugins/default/tileMap/runtime/TileMapRenderer.ts b/plugins/default/tileMap/runtime/TileMapRenderer.ts index 5c384d4ce..41434ace0 100644 --- a/plugins/default/tileMap/runtime/TileMapRenderer.ts +++ b/plugins/default/tileMap/runtime/TileMapRenderer.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.TileMapRenderer"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { if (config.tileMapAssetId == null) return; diff --git a/plugins/default/tileMap/typescriptAPI/index.ts b/plugins/default/tileMap/typescriptAPI/index.ts index 6c5748dad..becf492f7 100644 --- a/plugins/default/tileMap/typescriptAPI/index.ts +++ b/plugins/default/tileMap/typescriptAPI/index.ts @@ -15,5 +15,5 @@ SupCore.system.registerPlugin("typescriptAPI", "Sup SupCore.system.registerPlugin("typescriptAPI", "TileMapRenderer", { code: fs.readFileSync(`${__dirname}/Sup.TileMapRenderer.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.TileMapRenderer.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "tileMapRenderer", className: "Sup.TileMapRenderer" } + exposeActorComponent: "tileMapRenderer: Sup.TileMapRenderer;" }); diff --git a/plugins/default/typescript/compiler/compileGame.ts b/plugins/default/typescript/compiler/compileGame.ts index 5efb20f9e..ec698b822 100644 --- a/plugins/default/typescript/compiler/compileGame.ts +++ b/plugins/default/typescript/compiler/compileGame.ts @@ -23,7 +23,7 @@ export default function compileGame(gameName: string, system: SupCore.System, sc } if (plugin.defs != null) globalDefs[`${pluginName}.d.ts`] = plugin.defs; - if (plugin.exposeActorComponent != null) actorComponentAccessors.push(`${plugin.exposeActorComponent.propertyName}: ${plugin.exposeActorComponent.className};`); + if (plugin.exposeActorComponent != null) actorComponentAccessors.push(plugin.exposeActorComponent); } // Plug component accessors exposed by plugins into Sup.Actor class diff --git a/plugins/default/typescript/data/ScriptAsset.ts b/plugins/default/typescript/data/ScriptAsset.ts index d56fa779e..2d75c1b2f 100644 --- a/plugins/default/typescript/data/ScriptAsset.ts +++ b/plugins/default/typescript/data/ScriptAsset.ts @@ -42,7 +42,7 @@ if ((global).window == null) { for (const pluginName in plugins) { const plugin = plugins[pluginName]; if (plugin.defs != null) globalDefs += plugin.defs; - if (plugin.exposeActorComponent != null) actorComponentAccessors.push(`${plugin.exposeActorComponent.propertyName}: ${plugin.exposeActorComponent.className};`); + if (plugin.exposeActorComponent != null) actorComponentAccessors.push(plugin.exposeActorComponent); } globalDefs = globalDefs.replace("// INSERT_COMPONENT_ACCESSORS", actorComponentAccessors.join("\n ")); diff --git a/plugins/default/typescript/editors/apiBrowser/index.ts b/plugins/default/typescript/editors/apiBrowser/index.ts index 30e1c9cbd..54892619d 100644 --- a/plugins/default/typescript/editors/apiBrowser/index.ts +++ b/plugins/default/typescript/editors/apiBrowser/index.ts @@ -59,8 +59,8 @@ function onAPILoaded() { if (name === "lib") name = "Built-ins"; if (plugin.exposeActorComponent != null) { - name = plugin.exposeActorComponent.className; - actorComponentAccessors.push(`${plugin.exposeActorComponent.propertyName}: ${plugin.exposeActorComponent.className};`); + name = `Sup.${name}`; + actorComponentAccessors.push(plugin.exposeActorComponent); } if (plugin.defs != null) allDefs[name] = plugin.defs.replace(/\r\n/g, "\n"); } diff --git a/plugins/default/typescript/editors/script/network.ts b/plugins/default/typescript/editors/script/network.ts index ed02bf698..3a295230f 100644 --- a/plugins/default/typescript/editors/script/network.ts +++ b/plugins/default/typescript/editors/script/network.ts @@ -364,7 +364,7 @@ function loadPlugins() { for (const pluginName in plugins) { const plugin = plugins[pluginName]; if (plugin.defs != null) globalDefs += plugin.defs; - if (plugin.exposeActorComponent != null) actorComponentAccessors.push(`${plugin.exposeActorComponent.propertyName}: ${plugin.exposeActorComponent.className};`); + if (plugin.exposeActorComponent != null) actorComponentAccessors.push(plugin.exposeActorComponent); } globalDefs = globalDefs.replace("// INSERT_COMPONENT_ACCESSORS", actorComponentAccessors.join("\n ")); diff --git a/plugins/default/typescript/runtime/Behavior.ts b/plugins/default/typescript/runtime/Behavior.ts index fc4950781..bf6488398 100644 --- a/plugins/default/typescript/runtime/Behavior.ts +++ b/plugins/default/typescript/runtime/Behavior.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.Behavior"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { if (config.propertyValues == null) return; diff --git a/plugins/default/typescript/runtime/script.ts b/plugins/default/typescript/runtime/script.ts index 2f4d0d6e5..8520d8c58 100644 --- a/plugins/default/typescript/runtime/script.ts +++ b/plugins/default/typescript/runtime/script.ts @@ -9,8 +9,6 @@ export function init(player: any, callback: Function) { return new (window).Sup.Actor(name, parentActor, options); }; - const plugins = SupCore.system.getPlugins("typescriptAPI"); - player.createComponent = (type: string, actor: any, config: any) => { if (type === "Behavior") { const behaviorClass = player.behaviorClasses[config.behaviorName]; @@ -23,7 +21,7 @@ export function init(player: any, callback: Function) { } else { if (actorComponentTypesByName[type] == null) { actorComponentTypesByName[type] = window; - const parts = plugins[type].exposeActorComponent.className.split("."); + const parts = SupRuntime.plugins[type].componentClassName.split("."); for (const part of parts) actorComponentTypesByName[type] = actorComponentTypesByName[type][part]; } return new actorComponentTypesByName[type](actor); diff --git a/plugins/default/typescript/typescriptAPI/TypeScriptAPIPlugin.d.ts b/plugins/default/typescript/typescriptAPI/TypeScriptAPIPlugin.d.ts index ec8dd078e..60b35f57d 100644 --- a/plugins/default/typescript/typescriptAPI/TypeScriptAPIPlugin.d.ts +++ b/plugins/default/typescript/typescriptAPI/TypeScriptAPIPlugin.d.ts @@ -2,6 +2,6 @@ declare namespace SupCore { export interface TypeScriptAPIPlugin { code: string; defs: string; - exposeActorComponent?: { propertyName: string; className: string; }; + exposeActorComponent?: string; } } diff --git a/plugins/default/typescript/typescriptAPI/index.ts b/plugins/default/typescript/typescriptAPI/index.ts index 2616b1b74..5593d76cd 100644 --- a/plugins/default/typescript/typescriptAPI/index.ts +++ b/plugins/default/typescript/typescriptAPI/index.ts @@ -40,7 +40,7 @@ SupCore.system.registerPlugin("typescriptAPI", "Sup SupCore.system.registerPlugin("typescriptAPI", "Camera", { code: fs.readFileSync(`${__dirname}/Sup.Camera.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.Camera.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "camera", className: "Sup.Camera" } + exposeActorComponent: "camera: Sup.Camera;" }); SupCore.system.registerPlugin("typescriptAPI", "Sup.Color", { diff --git a/plugins/extra/cannonjs/runtime/CannonBody.ts b/plugins/extra/cannonjs/runtime/CannonBody.ts index 07a25376e..b92d78673 100644 --- a/plugins/extra/cannonjs/runtime/CannonBody.ts +++ b/plugins/extra/cannonjs/runtime/CannonBody.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.Cannon.Body"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { component.setup(config); } diff --git a/plugins/extra/cannonjs/typescriptAPI/index.ts b/plugins/extra/cannonjs/typescriptAPI/index.ts index e858d7cc8..5ce25e1f2 100644 --- a/plugins/extra/cannonjs/typescriptAPI/index.ts +++ b/plugins/extra/cannonjs/typescriptAPI/index.ts @@ -10,5 +10,5 @@ SupCore.system.registerPlugin("typescriptAPI", "CAN SupCore.system.registerPlugin("typescriptAPI", "CannonBody", { code: fs.readFileSync(`${__dirname}/Sup.Cannon.Body.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.Cannon.Body.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "cannonBody", className: "Sup.Cannon.Body" } + exposeActorComponent: "cannonBody: Sup.Cannon.Body" }); diff --git a/plugins/extra/p2js/runtime/P2Body.ts b/plugins/extra/p2js/runtime/P2Body.ts index 07a25376e..73f8d1f08 100644 --- a/plugins/extra/p2js/runtime/P2Body.ts +++ b/plugins/extra/p2js/runtime/P2Body.ts @@ -1,3 +1,5 @@ +export const componentClassName = "Sup.P2.Body"; + export function setupComponent(player: SupRuntime.Player, component: any, config: any) { component.setup(config); } diff --git a/plugins/extra/p2js/typescriptAPI/index.ts b/plugins/extra/p2js/typescriptAPI/index.ts index 0f8339856..fcf36460e 100644 --- a/plugins/extra/p2js/typescriptAPI/index.ts +++ b/plugins/extra/p2js/typescriptAPI/index.ts @@ -10,5 +10,5 @@ SupCore.system.registerPlugin("typescriptAPI", "p2" SupCore.system.registerPlugin("typescriptAPI", "P2Body", { code: fs.readFileSync(`${__dirname}/Sup.P2.ts.txt`, { encoding: "utf8" }), defs: fs.readFileSync(`${__dirname}/Sup.P2.d.ts.txt`, { encoding: "utf8" }), - exposeActorComponent: { propertyName: "p2Body", className: "Sup.P2.Body" } + exposeActorComponent: "p2Body: Sup.P2.Body;" }); From 629c76abd59b65fa2f60cd23f20581592f2ea049 Mon Sep 17 00:00:00 2001 From: bilou84 Date: Sun, 18 Dec 2016 18:05:33 +0100 Subject: [PATCH 4/8] Only include scripts source map in the server side build for debugging purpose --- .../default/gameSettings/build/buildGame.ts | 2 +- .../typescript/compiler/compileGame.ts | 59 +++++++++++-------- server/index.ts | 2 +- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/plugins/default/gameSettings/build/buildGame.ts b/plugins/default/gameSettings/build/buildGame.ts index 0ee89f3ba..b13526002 100644 --- a/plugins/default/gameSettings/build/buildGame.ts +++ b/plugins/default/gameSettings/build/buildGame.ts @@ -175,7 +175,7 @@ function updateProgress() { statusElt.textContent = "Compiling scripts..."; - compileGame(gameName, SupCore.system, scriptNames, scripts, (err, code) => { + compileGame(gameName, SupCore.system, false, scriptNames, scripts, (err, code) => { if (err != null) { progress.errors++; SupClient.html("li", { parent: detailsListElt, textContent: "Compilation failed."}); diff --git a/plugins/default/typescript/compiler/compileGame.ts b/plugins/default/typescript/compiler/compileGame.ts index ec698b822..c93adb01c 100644 --- a/plugins/default/typescript/compiler/compileGame.ts +++ b/plugins/default/typescript/compiler/compileGame.ts @@ -7,7 +7,9 @@ import * as convert from "convert-source-map"; /* tslint:disable-next-line */ const combine: any = require("combine-source-map"); -export default function compileGame(gameName: string, system: SupCore.System, scriptNames: string[], scripts: { [name: string]: string }, callback: (err: string, code: string) => void) { +export default function compileGame(gameName: string, system: SupCore.System, includeSourceMap: boolean, +scriptNames: string[], scripts: { [name: string]: string }, callback: (err: string, code: string) => void) { + const globalNames: string[] = []; const globals: {[name: string]: string} = {}; const globalDefs: {[name: string]: string} = {}; @@ -44,41 +46,46 @@ export default function compileGame(gameName: string, system: SupCore.System, sc return; } + jsGlobals.script = `(function() { +var player = _player; _player = undefined; +${jsGlobals.script} +})(); +`; + // Compile game scripts let concatenatedGlobalDefs = ""; for (const name in globalDefs) concatenatedGlobalDefs += globalDefs[name]; - const results = compileTypescript(scriptNames, scripts, concatenatedGlobalDefs, { sourceMap: true }); - if (results.errors.length > 0) { - for (const error of results.errors) console.log(`${error.file}(${error.position.line}): ${error.message}`); + const jsScripts = compileTypescript(scriptNames, scripts, concatenatedGlobalDefs, { sourceMap: true }); + if (jsScripts.errors.length > 0) { + for (const error of jsScripts.errors) console.log(`${error.file}(${error.position.line}): ${error.message}`); callback("Compilation failed. Check the devtools (F12) for errors.", null); return; } - // Prepare source maps - const getLineCounts = (text: string) => { - let count = 1, index = -1; - while (true) { - index = text.indexOf("\n", index + 1); - if (index === -1) break; - count++; - } - return count; - }; + let code = `${jsGlobals.script}${jsScripts.script}`; - jsGlobals.script = `(function() { -var player = _player; _player = undefined; -${jsGlobals.script} -})(); -`; + if (includeSourceMap) { + // Prepare source maps + const getLineCounts = (text: string) => { + let count = 1, index = -1; + while (true) { + index = text.indexOf("\n", index + 1); + if (index === -1) break; + count++; + } + return count; + }; + + let line = getLineCounts(jsGlobals.script) + 2; + const combinedSourceMap = combine.create("bundle.js"); + for (const file of jsScripts.files) { + const comment = convert.fromObject(jsScripts.sourceMaps[file.name]).toComment(); + combinedSourceMap.addFile({ sourceFile: `${gameName}/${file.name}`, source: file.text + `\n${comment}` }, { line }); + line += getLineCounts(file.text); + } - let line = getLineCounts(jsGlobals.script) + 2; - const combinedSourceMap = combine.create("bundle.js"); - for (const file of results.files) { - const comment = convert.fromObject(results.sourceMaps[file.name]).toComment(); - combinedSourceMap.addFile({ sourceFile: `${gameName}/${file.name}`, source: file.text + `\n${comment}` }, { line }); - line += getLineCounts(file.text); + code += `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${combinedSourceMap.base64()}`; } - const code = `${jsGlobals.script}${results.script}//# sourceMappingURL=data:application/json;charset=utf-8;base64,${combinedSourceMap.base64()}`; callback(null, code); } diff --git a/server/index.ts b/server/index.ts index 9544826a0..9057bc8d7 100644 --- a/server/index.ts +++ b/server/index.ts @@ -63,7 +63,7 @@ SupCore.system.serverBuild = (server: ProjectServer, buildPath: string, callback if (err != null) { callback("Could not save project.json"); return; } // Pre-compile scripts - compileGame(gameName, server.system, scriptNames, scripts, (err, code) => { + compileGame(gameName, server.system, true, scriptNames, scripts, (err, code) => { if (err != null) { callback("Could not compile game"); return; } fs.writeFile(`${buildPath}/script.js`, code, { encoding: "utf8" }, (err) => { From f6f46be87a06283028a0896ec2c7559160a182b1 Mon Sep 17 00:00:00 2001 From: bilou84 Date: Sun, 18 Dec 2016 18:17:11 +0100 Subject: [PATCH 5/8] Use uglify on SupEngine.js, reducing its size from 1055KB to 527KB --- SupEngine/gulpfile.js | 4 ++++ SupEngine/package.json | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/SupEngine/gulpfile.js b/SupEngine/gulpfile.js index 4729721c2..d1ff57a00 100644 --- a/SupEngine/gulpfile.js +++ b/SupEngine/gulpfile.js @@ -20,11 +20,15 @@ gulp.task("typescript", function() { // Browserify const browserify = require("browserify"); +const uglify = require('gulp-uglify'); const source = require("vinyl-source-stream"); +const buffer = require('vinyl-buffer'); gulp.task("browserify", [ "typescript" ], () => browserify("./src/index.js", { standalone: "SupEngine" }) .bundle() .pipe(source("SupEngine.js")) + .pipe(buffer()) + .pipe(uglify()) .pipe(gulp.dest("../public")) ); diff --git a/SupEngine/package.json b/SupEngine/package.json index 1746ad98d..1e8378bd0 100644 --- a/SupEngine/package.json +++ b/SupEngine/package.json @@ -12,6 +12,8 @@ "three": "0.81.2" }, "devDependencies": { - "@types/three": "0.0.24" + "@types/three": "0.0.24", + "gulp-uglify": "2.0.0", + "vinyl-buffer": "1.0.0" } } From b73490889dc9e9689cfc739a5e805001ab65baa0 Mon Sep 17 00:00:00 2001 From: bilou84 Date: Sun, 18 Dec 2016 18:26:33 +0100 Subject: [PATCH 6/8] Use uglifyjs to minimize exported script for client side build --- plugins/default/gameSettings/build/buildGame.ts | 2 +- plugins/default/typescript/compiler/compileGame.ts | 11 +++++++---- plugins/default/typescript/package.json | 6 ++++-- server/index.ts | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/plugins/default/gameSettings/build/buildGame.ts b/plugins/default/gameSettings/build/buildGame.ts index b13526002..8eb0a25a8 100644 --- a/plugins/default/gameSettings/build/buildGame.ts +++ b/plugins/default/gameSettings/build/buildGame.ts @@ -175,7 +175,7 @@ function updateProgress() { statusElt.textContent = "Compiling scripts..."; - compileGame(gameName, SupCore.system, false, scriptNames, scripts, (err, code) => { + compileGame(gameName, SupCore.system, true, scriptNames, scripts, (err, code) => { if (err != null) { progress.errors++; SupClient.html("li", { parent: detailsListElt, textContent: "Compilation failed."}); diff --git a/plugins/default/typescript/compiler/compileGame.ts b/plugins/default/typescript/compiler/compileGame.ts index c93adb01c..808069868 100644 --- a/plugins/default/typescript/compiler/compileGame.ts +++ b/plugins/default/typescript/compiler/compileGame.ts @@ -1,13 +1,14 @@ /// import compileTypescript from "./compileTypeScript"; +import * as uglify from "uglify-js"; import * as convert from "convert-source-map"; // No definition file for combine-source-map module /* tslint:disable-next-line */ const combine: any = require("combine-source-map"); -export default function compileGame(gameName: string, system: SupCore.System, includeSourceMap: boolean, +export default function compileGame(gameName: string, system: SupCore.System, minimizeSize: boolean, scriptNames: string[], scripts: { [name: string]: string }, callback: (err: string, code: string) => void) { const globalNames: string[] = []; @@ -62,9 +63,11 @@ ${jsGlobals.script} return; } - let code = `${jsGlobals.script}${jsScripts.script}`; + let code: string; - if (includeSourceMap) { + if (minimizeSize) { + code = uglify.minify(`${jsGlobals.script}${jsScripts.script}`, { fromString: true, mangle: false }).code; + } else { // Prepare source maps const getLineCounts = (text: string) => { let count = 1, index = -1; @@ -84,7 +87,7 @@ ${jsGlobals.script} line += getLineCounts(file.text); } - code += `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${combinedSourceMap.base64()}`; + code = `${jsGlobals.script}${jsScripts.script}//# sourceMappingURL=data:application/json;charset=utf-8;base64,${combinedSourceMap.base64()}`; } callback(null, code); diff --git a/plugins/default/typescript/package.json b/plugins/default/typescript/package.json index dacb842f4..d76357c9a 100644 --- a/plugins/default/typescript/package.json +++ b/plugins/default/typescript/package.json @@ -15,9 +15,11 @@ "convert-source-map": "^1.1.1", "highlight.js": "^9.0.0", "operational-transform": "^0.2.3", - "typescript": "~1.8.2" + "typescript": "~1.8.2", + "uglify-js": "2.7.5" }, "devDependencies": { - "@types/convert-source-map": "0.0.30" + "@types/convert-source-map": "0.0.30", + "@types/uglify-js": "^2.6.28" } } diff --git a/server/index.ts b/server/index.ts index 9057bc8d7..caf2e35b2 100644 --- a/server/index.ts +++ b/server/index.ts @@ -63,7 +63,7 @@ SupCore.system.serverBuild = (server: ProjectServer, buildPath: string, callback if (err != null) { callback("Could not save project.json"); return; } // Pre-compile scripts - compileGame(gameName, server.system, true, scriptNames, scripts, (err, code) => { + compileGame(gameName, server.system, false, scriptNames, scripts, (err, code) => { if (err != null) { callback("Could not compile game"); return; } fs.writeFile(`${buildPath}/script.js`, code, { encoding: "utf8" }, (err) => { From 71d2b9fd1fbded68098d5cbd67e83a812d9e6a56 Mon Sep 17 00:00:00 2001 From: bilou84 Date: Tue, 20 Dec 2016 10:25:46 +0100 Subject: [PATCH 7/8] Move typescriptCompiler to the root of the system as it is used by several pieces and is central to the system --- .gitignore | 1 + package.json | 10 ++++++++ .../default/gameSettings/build/buildGame.ts | 2 +- .../default/typescript/data/ScriptAsset.ts | 6 ++--- plugins/default/typescript/index.d.ts | 1 - plugins/default/typescript/package.json | 10 +------- .../default/typescript/typescriptAPI/index.ts | 2 +- server/index.ts | 2 +- .../compileGame.ts | 3 ++- .../compileTypeScript.ts | 0 typescriptCompiler/gulpfile.js | 23 +++++++++++++++++++ typescriptCompiler/tsconfig.json | 8 +++++++ 12 files changed, 51 insertions(+), 17 deletions(-) rename {plugins/default/typescript/compiler => typescriptCompiler}/compileGame.ts (96%) rename {plugins/default/typescript/compiler => typescriptCompiler}/compileTypeScript.ts (100%) create mode 100644 typescriptCompiler/gulpfile.js create mode 100644 typescriptCompiler/tsconfig.json diff --git a/.gitignore b/.gitignore index f4f2efe57..9ee1441e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ server/**/*.js +typescriptCompiler/**/*.js SupEngine/**/*.js SupRuntime/**/*.js diff --git a/package.json b/package.json index da7814b1d..8990445e8 100644 --- a/package.json +++ b/package.json @@ -9,5 +9,15 @@ }, "superpowers": { "systemId": "game" + }, + "dependencies": { + "combine-source-map": "^0.7.1", + "convert-source-map": "^1.1.1", + "typescript": "~1.8.2", + "uglify-js": "2.7.5" + }, + "devDependencies": { + "@types/convert-source-map": "0.0.30", + "@types/uglify-js": "^2.6.28" } } \ No newline at end of file diff --git a/plugins/default/gameSettings/build/buildGame.ts b/plugins/default/gameSettings/build/buildGame.ts index 8eb0a25a8..55eab7277 100644 --- a/plugins/default/gameSettings/build/buildGame.ts +++ b/plugins/default/gameSettings/build/buildGame.ts @@ -1,7 +1,7 @@ import * as async from "async"; import * as path from "path"; -import compileGame from "../../typescript/compiler/compileGame"; +import compileGame from "../../../../typescriptCompiler/compileGame"; let projectClient: SupClient.ProjectClient; const subscribersByAssetId: { [assetId: string]: SupClient.AssetSubscriber } = {}; diff --git a/plugins/default/typescript/data/ScriptAsset.ts b/plugins/default/typescript/data/ScriptAsset.ts index 2d75c1b2f..b60e717d5 100644 --- a/plugins/default/typescript/data/ScriptAsset.ts +++ b/plugins/default/typescript/data/ScriptAsset.ts @@ -1,6 +1,6 @@ /// -/// -/// +/// +/// import * as OT from "operational-transform"; import * as fs from "fs"; @@ -34,7 +34,7 @@ let globalDefs = ""; if ((global).window == null) { const serverRequire = require; ts = serverRequire("typescript"); - compileTypeScript = serverRequire("../compiler/compileTypeScript").default; + compileTypeScript = serverRequire("../../../../typescriptCompiler/compileTypescript").default; SupCore.system.requireForAllPlugins("typescriptAPI/index.js"); const plugins = SupCore.system.getPlugins("typescriptAPI"); diff --git a/plugins/default/typescript/index.d.ts b/plugins/default/typescript/index.d.ts index 619b1a0ab..d35cc9854 100644 --- a/plugins/default/typescript/index.d.ts +++ b/plugins/default/typescript/index.d.ts @@ -1,4 +1,3 @@ -/// /// /// /// diff --git a/plugins/default/typescript/package.json b/plugins/default/typescript/package.json index d76357c9a..15f1b1c4f 100644 --- a/plugins/default/typescript/package.json +++ b/plugins/default/typescript/package.json @@ -11,15 +11,7 @@ "build": "gulp --gulpfile=../../../../../scripts/pluginGulpfile.js --cwd=. --silent && gulp --gulpfile=workerGulpfile.js" }, "dependencies": { - "combine-source-map": "^0.7.1", - "convert-source-map": "^1.1.1", "highlight.js": "^9.0.0", - "operational-transform": "^0.2.3", - "typescript": "~1.8.2", - "uglify-js": "2.7.5" - }, - "devDependencies": { - "@types/convert-source-map": "0.0.30", - "@types/uglify-js": "^2.6.28" + "operational-transform": "^0.2.3" } } diff --git a/plugins/default/typescript/typescriptAPI/index.ts b/plugins/default/typescript/typescriptAPI/index.ts index 5593d76cd..07100955c 100644 --- a/plugins/default/typescript/typescriptAPI/index.ts +++ b/plugins/default/typescript/typescriptAPI/index.ts @@ -3,7 +3,7 @@ import * as fs from "fs"; SupCore.system.registerPlugin("typescriptAPI", "lib", { - defs: fs.readFileSync(`${__dirname}/../node_modules/typescript/lib/lib.core.d.ts`, { encoding: "utf8" }), + defs: fs.readFileSync(`${__dirname}/../../../../node_modules/typescript/lib/lib.core.d.ts`, { encoding: "utf8" }), code: "", }); diff --git a/server/index.ts b/server/index.ts index caf2e35b2..280c0339f 100644 --- a/server/index.ts +++ b/server/index.ts @@ -4,7 +4,7 @@ import * as fs from "fs"; import * as async from "async"; import * as mkdirp from "mkdirp"; -import compileGame from "../plugins/default/typescript/compiler/compileGame"; +import compileGame from "../typescriptCompiler/compileGame"; const scriptNames: string[] = []; const scripts: {[name: string]: string} = {}; diff --git a/plugins/default/typescript/compiler/compileGame.ts b/typescriptCompiler/compileGame.ts similarity index 96% rename from plugins/default/typescript/compiler/compileGame.ts rename to typescriptCompiler/compileGame.ts index 808069868..072ec0b4b 100644 --- a/plugins/default/typescript/compiler/compileGame.ts +++ b/typescriptCompiler/compileGame.ts @@ -1,4 +1,5 @@ -/// +/// +/// import compileTypescript from "./compileTypeScript"; import * as uglify from "uglify-js"; diff --git a/plugins/default/typescript/compiler/compileTypeScript.ts b/typescriptCompiler/compileTypeScript.ts similarity index 100% rename from plugins/default/typescript/compiler/compileTypeScript.ts rename to typescriptCompiler/compileTypeScript.ts diff --git a/typescriptCompiler/gulpfile.js b/typescriptCompiler/gulpfile.js new file mode 100644 index 000000000..f2c3940d2 --- /dev/null +++ b/typescriptCompiler/gulpfile.js @@ -0,0 +1,23 @@ +"use strict"; + +const gulp = require("gulp"); + +// TypeScript +const ts = require("gulp-typescript"); +const tsProject = ts.createProject("./tsconfig.json"); +const tslint = require("gulp-tslint"); + +gulp.task("typescript", function() { + let failed = false; + const tsResult = tsProject.src() + .pipe(tslint()) + .pipe(tslint.report("prose", { emitError: true })) + .on("error", (err) => { throw err; }) + .pipe(tsProject()) + .on("error", () => { failed = true; }) + .on("end", () => { if (failed) throw new Error("There were TypeScript errors."); }); + return tsResult.js.pipe(gulp.dest("./")); +}); + +// All +gulp.task("default", [ "typescript" ]); diff --git a/typescriptCompiler/tsconfig.json b/typescriptCompiler/tsconfig.json new file mode 100644 index 000000000..b755f2727 --- /dev/null +++ b/typescriptCompiler/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": true, + "typeRoots": [ "../../../node_modules/@types" ] + } +} From cc45232448fac918f4840f88222a8c88359bd69d Mon Sep 17 00:00:00 2001 From: bilou84 Date: Mon, 2 Jan 2017 01:40:50 +0100 Subject: [PATCH 8/8] Fix typo in import module path --- plugins/default/typescript/data/ScriptAsset.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/default/typescript/data/ScriptAsset.ts b/plugins/default/typescript/data/ScriptAsset.ts index b60e717d5..527f7cd46 100644 --- a/plugins/default/typescript/data/ScriptAsset.ts +++ b/plugins/default/typescript/data/ScriptAsset.ts @@ -34,7 +34,7 @@ let globalDefs = ""; if ((global).window == null) { const serverRequire = require; ts = serverRequire("typescript"); - compileTypeScript = serverRequire("../../../../typescriptCompiler/compileTypescript").default; + compileTypeScript = serverRequire("../../../../typescriptCompiler/compileTypeScript").default; SupCore.system.requireForAllPlugins("typescriptAPI/index.js"); const plugins = SupCore.system.getPlugins("typescriptAPI");