Skip to content
This repository has been archived by the owner on Mar 5, 2021. It is now read-only.

Precompile scripts #179

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
server/**/*.js
typescriptCompiler/**/*.js
SupEngine/**/*.js
SupRuntime/**/*.js

Expand Down
4 changes: 4 additions & 0 deletions SupEngine/gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
);

Expand Down
4 changes: 3 additions & 1 deletion SupEngine/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
1 change: 1 addition & 0 deletions SupRuntime/SupRuntime.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion SupRuntime/src/index.jade
Original file line number Diff line number Diff line change
Expand Up @@ -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")
4 changes: 1 addition & 3 deletions SupRuntime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line at the end off the file is missed.

2 changes: 2 additions & 0 deletions plugins/default/arcadePhysics2D/runtime/ArcadeBody2D.ts
Original file line number Diff line number Diff line change
@@ -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);

Expand Down
2 changes: 1 addition & 1 deletion plugins/default/arcadePhysics2D/typescriptAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("typescriptAPI", "Sup
SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("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;"
});
2 changes: 2 additions & 0 deletions plugins/default/cubicModel/runtime/CubicModelRenderer.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
2 changes: 1 addition & 1 deletion plugins/default/cubicModel/typescriptAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("typescriptAPI", "Sup
SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("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;"
});
2 changes: 2 additions & 0 deletions plugins/default/font/runtime/TextRenderer.ts
Original file line number Diff line number Diff line change
@@ -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 });
Expand Down
2 changes: 1 addition & 1 deletion plugins/default/font/typescriptAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("typescriptAPI", "Sup
SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("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;"
});
57 changes: 46 additions & 11 deletions plugins/default/gameSettings/build/buildGame.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as async from "async";
import * as path from "path";

import compileGame from "../../../../typescriptCompiler/compileGame";

let projectClient: SupClient.ProjectClient;
const subscribersByAssetId: { [assetId: string]: SupClient.AssetSubscriber } = {};
const subscribersByResourceId: { [resourceId: string] : SupClient.ResourceSubscriber } = {};
Expand All @@ -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;
}
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -59,13 +64,13 @@ function onEntriesReceived(theEntries: SupCore.Data.Entries) {
// Assets
entries.walk((entry) => {
if (entry.type != null) {
// Only subscribe to assets that can be exported
if (SupCore.system.data.assetClasses[entry.type].prototype.clientExport != 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++;
}
}
});
Expand All @@ -83,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`);
Expand Down Expand Up @@ -144,7 +148,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() };
gameName = manifestPub.name;
const exportedProject = { name: gameName, assets: entries.getForStorage(["script"]) };
const json = JSON.stringify(exportedProject, null, 2);

const projectPath = `${settings.outputFolder}/project.json`;
Expand All @@ -165,17 +170,47 @@ 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, true, 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 });
}
});
}
});
}
}

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, () => {
Expand Down
2 changes: 2 additions & 0 deletions plugins/default/light/runtime/Light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
(<any>component).__outer.type = ["ambient", "point", "spot", "directional"].indexOf(config.type);
component.color = parseInt(config.color, 16);
Expand Down
2 changes: 1 addition & 1 deletion plugins/default/light/typescriptAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import * as fs from "fs";
SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("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;"
});
2 changes: 2 additions & 0 deletions plugins/default/model/runtime/ModelRenderer.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
2 changes: 1 addition & 1 deletion plugins/default/model/typescriptAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("typescriptAPI", "Sup
SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("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;"
});
2 changes: 2 additions & 0 deletions plugins/default/scene/runtime/Camera.ts
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
2 changes: 2 additions & 0 deletions plugins/default/sprite/runtime/SpriteRenderer.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
2 changes: 1 addition & 1 deletion plugins/default/sprite/typescriptAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("typescriptAPI", "Sup
SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("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;"
});
2 changes: 2 additions & 0 deletions plugins/default/tileMap/runtime/TileMapRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const componentClassName = "Sup.TileMapRenderer";

export function setupComponent(player: SupRuntime.Player, component: any, config: any) {
if (config.tileMapAssetId == null) return;

Expand Down
2 changes: 1 addition & 1 deletion plugins/default/tileMap/typescriptAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("typescriptAPI", "Sup
SupCore.system.registerPlugin<SupCore.TypeScriptAPIPlugin>("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;"
});
12 changes: 4 additions & 8 deletions plugins/default/typescript/data/ScriptAsset.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference path="../../../common/textEditorWidget/operational-transform.d.ts" />
/// <reference path="../node_modules/typescript/lib/typescriptServices.d.ts" />
/// <reference path="../../typescript/typescriptAPI/TypeScriptAPIPlugin.d.ts" />
/// <reference path="../../../../node_modules/typescript/lib/typescriptServices.d.ts" />
/// <reference path="../typescriptAPI/TypeScriptAPIPlugin.d.ts" />

import * as OT from "operational-transform";
import * as fs from "fs";
Expand Down Expand Up @@ -34,15 +34,15 @@ let globalDefs = "";
if ((<any>global).window == null) {
const serverRequire = require;
ts = serverRequire("typescript");
compileTypeScript = serverRequire("../runtime/compileTypeScript").default;
compileTypeScript = serverRequire("../../../../typescriptCompiler/compileTypeScript").default;

SupCore.system.requireForAllPlugins("typescriptAPI/index.js");
const plugins = SupCore.system.getPlugins<SupCore.TypeScriptAPIPlugin>("typescriptAPI");
const actorComponentAccessors: string[] = [];
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 "));
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions plugins/default/typescript/editors/apiBrowser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/default/typescript/editors/script/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 "));
Expand Down
1 change: 0 additions & 1 deletion plugins/default/typescript/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/// <reference path="./node_modules/typescript/lib/typescript.d.ts" />
/// <reference path="../../common/textEditorWidget/widget.d.ts" />
/// <reference path="../../../../../SupClient/SupClient.d.ts" />
/// <reference path="../../../../../SupCore/SupCore.d.ts" />
Expand Down
8 changes: 1 addition & 7 deletions plugins/default/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +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"
},
"devDependencies": {
"@types/convert-source-map": "0.0.30"
"operational-transform": "^0.2.3"
}
}
2 changes: 2 additions & 0 deletions plugins/default/typescript/runtime/Behavior.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const componentClassName = "Sup.Behavior";

export function setupComponent(player: SupRuntime.Player, component: any, config: any) {
if (config.propertyValues == null) return;

Expand Down
Loading