Cleanup Electron support

This commit is contained in:
Joshua Granick
2018-05-31 14:56:06 -07:00
parent e45f0dd51d
commit 026018886e
12 changed files with 108 additions and 563 deletions

View File

@@ -9,7 +9,6 @@ package lime.project;
var CONSOLE_PC = "console-pc";
var FIREFOX = "firefox";
var FLASH = "flash";
var ELECTRON = "electron";
var HTML5 = "html5";
var IOS = "ios";
var LINUX = "linux";

View File

@@ -1,19 +1,31 @@
package lime.tools.helpers;
import lime.tools.helpers.PlatformHelper;
import lime.tools.helpers.PathHelper;
import lime.tools.helpers.ProcessHelper;
import lime.project.HXProject;
import utils.PlatformSetup;
class ElectronHelper {
public static function launch (project:HXProject, path:String):Void {
var electronPath = project.defines.get ("ELECTRON");
if (electronPath == null || electronPath == "") electronPath = "electron";
else electronPath = electronPath + "\\electron";
var exitCode = ProcessHelper.runCommand ("", electronPath, [path]);
var electronPath = project.defines.get ("ELECTRON_PATH");
if (electronPath == null || electronPath == "") {
electronPath = "electron";
} else {
electronPath = PathHelper.combine (electronPath, "electron");
}
ProcessHelper.runCommand ("", electronPath, [ path ]);
}
}

View File

@@ -1,425 +0,0 @@
package lime.tools.platforms;
import haxe.io.Path;
import haxe.Template;
import lime.tools.helpers.DeploymentHelper;
import lime.tools.helpers.ElectronHelper;
import lime.tools.helpers.FileHelper;
import lime.tools.helpers.HTML5Helper;
import lime.tools.helpers.IconHelper;
import lime.tools.helpers.LogHelper;
import lime.tools.helpers.ModuleHelper;
import lime.tools.helpers.PathHelper;
import lime.tools.helpers.ProcessHelper;
import lime.tools.helpers.WatchHelper;
import lime.project.AssetType;
import lime.project.HXProject;
import lime.project.Icon;
import lime.project.PlatformTarget;
import lime.project.Haxelib;
import sys.io.File;
import sys.FileSystem;
class ElectronPlatform extends PlatformTarget {
private var outputFile:String;
public function new (command:String, _project:HXProject, targetFlags:Map<String, String> ) {
super (command, _project, targetFlags);
this.project.haxelibs.push(new Haxelib("electron"));
initialize (command, _project);
}
public override function build ():Void {
ModuleHelper.buildModules (project, targetDirectory + "/obj", targetDirectory + "/bin");
if (project.app.main != null) {
var type = "release";
if (project.debug) {
type = "debug";
} else if (project.targetFlags.exists ("final")) {
type = "final";
}
var hxml = targetDirectory + "/haxe/" + type + ".hxml";
ProcessHelper.runCommand ("", "haxe", [ hxml ] );
if (noOutput) return;
if (project.targetFlags.exists ("webgl")) {
FileHelper.copyFile (targetDirectory + "/obj/ApplicationMain.js", outputFile);
}
if (project.modules.iterator ().hasNext ()) {
ModuleHelper.patchFile (outputFile);
}
if (project.targetFlags.exists ("minify") || type == "final") {
HTML5Helper.minify (project, targetDirectory + "/bin/" + project.app.file + ".js");
}
}
}
public override function clean ():Void {
if (FileSystem.exists (targetDirectory)) {
PathHelper.removeDirectory (targetDirectory);
}
}
public override function deploy ():Void {
DeploymentHelper.deploy (project, targetFlags, targetDirectory, "electron");
}
public override function display ():Void {
Sys.println (getDisplayHXML ());
}
private function getDisplayHXML ():String {
var hxml = PathHelper.findTemplate (project.templatePaths, "electron/hxml/" + buildType + ".hxml");
var context = project.templateContext;
context.OUTPUT_DIR = targetDirectory;
context.OUTPUT_FILE = outputFile;
var template = new Template (File.getContent (hxml));
return template.execute (context) + "\n-D display";
}
private function initialize (command:String, project:HXProject):Void {
targetDirectory = PathHelper.combine (project.app.path, project.config.getString ("electron.output-directory", "electron"));
trace("targetDirectory = " + targetDirectory);
outputFile = targetDirectory + "/bin/" + project.app.file + ".js";
}
public override function run ():Void {
trace("ElectronHelper.launch");
ElectronHelper.launch (project, targetDirectory + "/bin");
}
public override function update ():Void {
project = project.clone ();
var destination = targetDirectory + "/bin/";
PathHelper.mkdir (destination);
var webfontDirectory = targetDirectory + "/obj/webfont";
var useWebfonts = true;
for (haxelib in project.haxelibs) {
if (haxelib.name == "openfl-html5-dom" || haxelib.name == "openfl-bitfive") {
useWebfonts = false;
}
}
var fontPath;
for (asset in project.assets) {
if (asset.type == AssetType.FONT && asset.targetPath != null) {
if (useWebfonts) {
fontPath = PathHelper.combine (webfontDirectory, Path.withoutDirectory (asset.targetPath));
if (!FileSystem.exists (fontPath)) {
PathHelper.mkdir (webfontDirectory);
FileHelper.copyFile (asset.sourcePath, fontPath);
var originalPath = asset.sourcePath;
asset.sourcePath = fontPath;
HTML5Helper.generateWebfonts (project, asset);
var ext = "." + Path.extension (asset.sourcePath);
var source = Path.withoutExtension (asset.sourcePath);
var extensions = [ ext, ".eot", ".woff", ".svg" ];
for (extension in extensions) {
if (!FileSystem.exists (source + extension)) {
LogHelper.warn ("Could not generate *" + extension + " web font for \"" + originalPath + "\"");
}
}
}
asset.sourcePath = fontPath;
asset.targetPath = Path.withoutExtension (asset.targetPath);
} else {
project.haxeflags.push (HTML5Helper.generateFontData (project, asset));
}
}
}
if (project.targetFlags.exists ("xml")) {
project.haxeflags.push ("-xml " + targetDirectory + "/types.xml");
}
if (LogHelper.verbose) {
project.haxedefs.set ("verbose", 1);
}
ModuleHelper.updateProject (project);
var libraryNames = new Map<String, Bool> ();
for (asset in project.assets) {
if (asset.library != null && !libraryNames.exists (asset.library)) {
libraryNames[asset.library] = true;
}
}
//for (library in libraryNames.keys ()) {
//
//project.haxeflags.push ("-resource " + targetDirectory + "/obj/manifest/" + library + ".json@__ASSET_MANIFEST__" + library);
//
//}
//project.haxeflags.push ("-resource " + targetDirectory + "/obj/manifest/default.json@__ASSET_MANIFEST__default");
var context = project.templateContext;
context.WIN_FLASHBACKGROUND = project.window.background != null ? StringTools.hex (project.window.background, 6) : "";
context.OUTPUT_DIR = targetDirectory;
context.OUTPUT_FILE = outputFile;
if (project.targetFlags.exists ("webgl")) {
context.CPP_DIR = targetDirectory + "/obj";
}
context.favicons = [];
var icons = project.icons;
if (icons.length == 0) {
icons = [ new Icon (PathHelper.findTemplate (project.templatePaths, "default/icon.svg")) ];
}
//if (IconHelper.createWindowsIcon (icons, PathHelper.combine (destination, "favicon.ico"))) {
//
//context.favicons.push ({ rel: "icon", type: "image/x-icon", href: "./favicon.ico" });
//
//}
if (IconHelper.createIcon (icons, 192, 192, PathHelper.combine (destination, "favicon.png"))) {
context.favicons.push ({ rel: "shortcut icon", type: "image/png", href: "./favicon.png" });
}
context.linkedLibraries = [];
for (dependency in project.dependencies) {
if (StringTools.endsWith (dependency.name, ".js")) {
context.linkedLibraries.push (dependency.name);
} else if (StringTools.endsWith (dependency.path, ".js") && FileSystem.exists (dependency.path)) {
var name = Path.withoutDirectory (dependency.path);
context.linkedLibraries.push ("./lib/" + name);
FileHelper.copyIfNewer (dependency.path, PathHelper.combine (destination, PathHelper.combine ("lib", name)));
}
}
for (asset in project.assets) {
var path = PathHelper.combine (destination, asset.targetPath);
if (asset.type != AssetType.TEMPLATE) {
if (asset.type != AssetType.FONT) {
PathHelper.mkdir (Path.directory (path));
FileHelper.copyAssetIfNewer (asset, path);
} else if (useWebfonts) {
PathHelper.mkdir (Path.directory (path));
var ext = "." + Path.extension (asset.sourcePath);
var source = Path.withoutExtension (asset.sourcePath);
var hasFormat = [ false, false, false, false ];
var extensions = [ ext, ".eot", ".svg", ".woff" ];
var extension;
for (i in 0...extensions.length) {
extension = extensions[i];
if (FileSystem.exists (source + extension)) {
FileHelper.copyIfNewer (source + extension, path + extension);
hasFormat[i] = true;
}
}
var shouldEmbedFont = false;
for (embedded in hasFormat) {
if (embedded) shouldEmbedFont = true;
}
var embeddedAssets:Array<Dynamic> = cast context.assets;
for (embeddedAsset in embeddedAssets) {
if (embeddedAsset.type == "font" && embeddedAsset.sourcePath == asset.sourcePath) {
if (shouldEmbedFont) {
var urls = [];
if (hasFormat[1]) urls.push ("url('" + embeddedAsset.targetPath + ".eot?#iefix') format('embedded-opentype')");
if (hasFormat[2]) urls.push ("url('" + embeddedAsset.targetPath + ".svg#my-font-family') format('svg')");
if (hasFormat[3]) urls.push ("url('" + embeddedAsset.targetPath + ".woff') format('woff')");
urls.push ("url('" + embeddedAsset.targetPath + ext + "') format('truetype')");
var fontFace = "\t\t@font-face {\n";
fontFace += "\t\t\tfont-family: '" + embeddedAsset.fontName + "';\n";
if (hasFormat[1]) fontFace += "\t\t\tsrc: url('" + embeddedAsset.targetPath + ".eot');\n";
fontFace += "\t\t\tsrc: " + urls.join (",\n\t\t\t") + ";\n";
fontFace += "\t\t\tfont-weight: normal;\n";
fontFace += "\t\t\tfont-style: normal;\n";
fontFace += "\t\t}\n";
embeddedAsset.cssFontFace = fontFace;
}
break;
}
}
}
}
}
FileHelper.recursiveSmartCopyTemplate (project, "electron/template", destination, context);
if (project.app.main != null) {
FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context);
FileHelper.recursiveSmartCopyTemplate (project, "electron/haxe", targetDirectory + "/haxe", context, true, false);
FileHelper.recursiveSmartCopyTemplate (project, "electron/hxml", targetDirectory + "/haxe", context);
if (project.targetFlags.exists ("webgl")) {
FileHelper.recursiveSmartCopyTemplate (project, "webgl/hxml", targetDirectory + "/haxe", context, true, false);
}
}
for (asset in project.assets) {
var path = PathHelper.combine (destination, asset.targetPath);
if (asset.type == AssetType.TEMPLATE) {
PathHelper.mkdir (Path.directory (path));
FileHelper.copyAsset (asset, path, context);
}
}
}
public override function watch ():Void {
// TODO: Use a custom live reload HTTP server for test/run instead
var dirs = WatchHelper.processHXML (project, getDisplayHXML ());
var command = WatchHelper.getCurrentCommand ();
WatchHelper.watch (project, command, dirs);
}
@ignore public override function install ():Void {}
@ignore public override function rebuild ():Void {}
@ignore public override function trace ():Void {}
@ignore public override function uninstall ():Void {}
}

View File

@@ -5,6 +5,7 @@ import haxe.io.Path;
import haxe.Template;
import lime.text.Font;
import lime.tools.helpers.DeploymentHelper;
import lime.tools.helpers.ElectronHelper;
import lime.tools.helpers.FileHelper;
import lime.tools.helpers.HTML5Helper;
import lime.tools.helpers.IconHelper;
@@ -98,7 +99,15 @@ class HTML5Platform extends PlatformTarget {
public override function deploy ():Void {
DeploymentHelper.deploy (project, targetFlags, targetDirectory, "HTML5");
var name = "HTML5";
if (targetFlags.exists ("electron")) {
name = "Electron";
}
DeploymentHelper.deploy (project, targetFlags, targetDirectory, name);
}
@@ -112,7 +121,15 @@ class HTML5Platform extends PlatformTarget {
private function getDisplayHXML ():String {
var hxml = PathHelper.findTemplate (project.templatePaths, "html5/hxml/" + buildType + ".hxml");
var type = "html5";
if (targetFlags.exists ("electron")) {
type = "electron";
}
var hxml = PathHelper.findTemplate (project.templatePaths, type + "/hxml/" + buildType + ".hxml");
var context = project.templateContext;
context.OUTPUT_DIR = targetDirectory;
@@ -127,8 +144,24 @@ class HTML5Platform extends PlatformTarget {
private function initialize (command:String, project:HXProject):Void {
targetDirectory = PathHelper.combine (project.app.path, project.config.getString ("html5.output-directory", "html5"));
if (targetFlags.exists ("electron")) {
targetDirectory = PathHelper.combine (project.app.path, project.config.getString ("electron.output-directory", "electron"));
} else {
targetDirectory = PathHelper.combine (project.app.path, project.config.getString ("html5.output-directory", "html5"));
}
dependencyPath = project.config.getString ("html5.dependency-path", "lib");
if (targetFlags.exists ("electron")) {
dependencyPath = project.config.getString ("html5.dependency-path", dependencyPath);
}
outputFile = targetDirectory + "/bin/" + project.app.file + ".js";
}
@@ -136,7 +169,15 @@ class HTML5Platform extends PlatformTarget {
public override function run ():Void {
HTML5Helper.launch (project, targetDirectory + "/bin");
if (targetFlags.exists ("electron")) {
ElectronHelper.launch (project, targetDirectory + "/bin");
} else {
HTML5Helper.launch (project, targetDirectory + "/bin");
}
}
@@ -395,9 +436,16 @@ class HTML5Platform extends PlatformTarget {
FileHelper.recursiveSmartCopyTemplate (project, "html5/haxe", targetDirectory + "/haxe", context, true, false);
FileHelper.recursiveSmartCopyTemplate (project, "html5/hxml", targetDirectory + "/haxe", context);
if (project.targetFlags.exists ("webgl")) {
}
FileHelper.recursiveSmartCopyTemplate (project, "webgl/hxml", targetDirectory + "/haxe", context, true, false);
if (targetFlags.exists ("electron")) {
FileHelper.recursiveSmartCopyTemplate (project, "electron/template", destination, context);
if (project.app.main != null) {
FileHelper.recursiveSmartCopyTemplate (project, "electron/haxe", targetDirectory + "/haxe", context, true, false);
FileHelper.recursiveSmartCopyTemplate (project, "electron/hxml", targetDirectory + "/haxe", context);
}

View File

@@ -1,4 +1,5 @@
-cp ::OUTPUT_DIR::/haxe
-lib electron
--each

View File

@@ -1,4 +1,5 @@
-cp ::OUTPUT_DIR::/haxe
-lib electron
--each

View File

@@ -1,4 +1,5 @@
-cp ::OUTPUT_DIR::/haxe
-lib electron
--each

Binary file not shown.

View File

@@ -1,45 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>::APP_TITLE::</title>
<meta id="viewport" name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes">
::if favicons::::foreach (favicons)::
<link rel="::__current__.rel::" type="::__current__.type::" href="::__current__.href::">::end::::end::
::if linkedLibraries::::foreach (linkedLibraries)::
<script type="text/javascript" src="::__current__::"></script>::end::::end::
<script type="text/javascript" src="./::APP_FILE::.js"></script>
<script>
window.addEventListener ("touchmove", function (event) { event.preventDefault (); }, false);
if (typeof window.devicePixelRatio != 'undefined' && window.devicePixelRatio > 2) {
var meta = document.getElementById ("viewport");
meta.setAttribute ('content', 'width=device-width, initial-scale=' + (2 / window.devicePixelRatio) + ', user-scalable=no');
}
</script>
<style>
html,body { margin: 0; padding: 0; height: 100%; overflow: hidden; }
#content { background: #FF0000; width: ::if (WIN_RESIZABLE)::100%::elseif (WIN_WIDTH > 0)::::WIN_WIDTH::px::else::100%::end::; height: ::if (WIN_RESIZABLE)::100%::elseif (WIN_WIDTH > 0)::::WIN_HEIGHT::px::else::100%::end::; }
::foreach assets::::if (type == "font")::::if (cssFontFace)::::cssFontFace::::end::::end::::end::
</style>
</head>
<body>
::foreach assets::::if (type == "font")::
<span style="font-family: ::id::"> </span>::end::::end::
<div id="content"></div>
<script type="text/javascript">
lime.embed ("::APP_FILE::", "content");
</script>
</body>
</html>

View File

@@ -283,10 +283,6 @@ class CommandLineTools {
target = PlatformHelper.hostPlatform;
targetFlags.set ("nodejs", "");
case "electron":
target = Platform.HTML5;
targetFlags.set ("electron", "");
case "cs":
target = PlatformHelper.hostPlatform;
@@ -301,6 +297,11 @@ class CommandLineTools {
target = Platform.IOS;
targetFlags.set ("simulator", "");
case "electron":
target = Platform.HTML5;
targetFlags.set ("electron", "");
case "firefox", "firefoxos":
target = Platform.FIREFOX;
@@ -720,12 +721,7 @@ class CommandLineTools {
case HTML5:
if (targetFlags.exists("electron")) {
platform = new ElectronPlatform (command, project, targetFlags);
}
else {
platform = new HTML5Platform (command, project, targetFlags);
}
platform = new HTML5Platform (command, project, targetFlags);
case FIREFOX:
@@ -1048,13 +1044,13 @@ class CommandLineTools {
LogHelper.println (" \x1b[1mnodejs\x1b[0m -- Alias for host platform (using \x1b[1m-nodejs\x1b[0m)");
LogHelper.println (" \x1b[1mjava\x1b[0m -- Alias for host platform (using \x1b[1m-java\x1b[0m)");
LogHelper.println (" \x1b[1mcs\x1b[0m -- Alias for host platform (using \x1b[1m-cs\x1b[0m)");
LogHelper.println (" \x1b[1melectron\x1b[0m -- Alias for \x1b[1mhtml5 -electron\x1b[0m");
LogHelper.println (" \x1b[1muwp\x1b[0;3m/\x1b[0m\x1b[1mwinjs\x1b[0m -- Alias for \x1b[1mwindows -uwp\x1b[0m");
// LogHelper.println (" \x1b[1miphone\x1b[0;3m/\x1b[0m\x1b[1miphoneos\x1b[0m -- \x1b[1mios\x1b[0m");
// LogHelper.println (" \x1b[1miphonesim\x1b[0m -- Alias for \x1b[1mios -simulator\x1b[0m");
// LogHelper.println (" \x1b[1mappletv\x1b[0;3m/\x1b[0m\x1b[1mappletvos\x1b[0m -- Alias for \x1b[1mtvos\x1b[0m");
// LogHelper.println (" \x1b[1mappletvsim\x1b[0m -- Alias for \x1b[1mtvos -simulator\x1b[0m");
LogHelper.println (" \x1b[1mrpi\x1b[0;3m/\x1b[0m\x1b[1mraspberrypi\x1b[0m -- Alias for \x1b[1mlinux -rpi\x1b[0m");
LogHelper.println (" \x1b[1melectron\x1b[0m -- Alias for \x1b[1mhtml5 -electron\x1b[0m");
LogHelper.println (" \x1b[1mwebassembly\x1b[0;3m/\x1b[0m\x1b[1mwasm\x1b[0m -- Alias for \x1b[1memscripten -webassembly\x1b[0m");
}
@@ -1155,7 +1151,6 @@ class CommandLineTools {
if (command != "run" && command != "trace") {
LogHelper.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-electron\x1b[0m -- Target Electron instead of the browser");
LogHelper.println (" \x1b[3m(emscripten)\x1b[0m \x1b[1m-webassembly\x1b[0m -- Compile for WebAssembly instead of asm.js");
}
@@ -1170,6 +1165,7 @@ class CommandLineTools {
LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-cs\x1b[0m -- Build for C# instead of C++");
LogHelper.println (" \x1b[3m(windows)\x1b[0m \x1b[1m-winjs\x1b[0m -- Build for WinJS instead of C++ (implies UWP)");
LogHelper.println (" \x1b[3m(windows)\x1b[0m \x1b[1m-uwp\x1b[0m -- Build for Universal Windows Platform");
LogHelper.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-electron\x1b[0m -- Target Electron instead of the browser");
if (command != "run" && command != "trace") {
@@ -1690,11 +1686,6 @@ class CommandLineTools {
target = PlatformHelper.hostPlatform;
targetFlags.set ("nodejs", "");
case "electron":
target = Platform.HTML5;
targetFlags.set ("electron", "");
case "cs":
target = PlatformHelper.hostPlatform;
@@ -1709,6 +1700,11 @@ class CommandLineTools {
target = Platform.IOS;
targetFlags.set ("simulator", "");
case "electron":
target = Platform.HTML5;
targetFlags.set ("electron", "");
case "firefox", "firefoxos":
target = Platform.FIREFOX;

View File

@@ -238,7 +238,7 @@ class PlatformSetup {
}
var inputValue = unescapePath (CLIHelper.param (LogHelper.accentColor + description + "\x1b[0m \x1b[37;3m[" + value + "]\x1b[0m"));
var inputValue = unescapePath (CLIHelper.param (LogHelper.accentColor + description + "\x1b[0m \x1b[37;3m[" + (value != null ? value : "") + "]\x1b[0m"));
if (inputValue != "" && inputValue != value) {
@@ -517,8 +517,7 @@ class PlatformSetup {
case "electron":
setupElectron();
setupElectron ();
case "windows":
@@ -763,6 +762,23 @@ class PlatformSetup {
}
public static function setupElectron ():Void {
LogHelper.println ("\x1b[1mIn order to run Electron applications, you must download");
LogHelper.println ("and extract the Electron runtime on your system.");
LogHelper.println ("");
getDefineValue ("ELECTRON_PATH", "Path to Electron runtime");
LogHelper.println ("");
HaxelibHelper.runCommand ("", [ "install", "electron" ], true, true);
LogHelper.println ("");
LogHelper.println ("Setup complete.");
}
public static function setupEmscripten ():Void {
LogHelper.println ("\x1b[1mIn order to build for WebAssembly or asm.js, you must download");
@@ -1282,65 +1298,6 @@ class PlatformSetup {
}
public static function setupElectron ():Void {
if (PlatformHelper.hostPlatform != Platform.WINDOWS) return;
var setElectronToPath = false;
var defines = getDefines ();
var answer = CLIHelper.ask ("Download and install Electron?");
var electronPath:String = "";
if (answer == YES || answer == ALWAYS) {
var downloadPath:String = electronWin;
var defaultInstallPath:String = "C:\\_sdks\\electron";
var localPath:String = "";
downloadFile (downloadPath);
localPath = unescapePath (CLIHelper.param ("Output directory [" + defaultInstallPath + "]"));
localPath = createPath (localPath, defaultInstallPath);
extractFile (Path.withoutDirectory (downloadPath), localPath, "");
defines.set ("ELECTRON", localPath);
writeConfig (defines.get ("LIME_CONFIG"), defines);
LogHelper.println ("");
setElectronToPath = true;
}
var requiredVariables = new Array<String> ();
var requiredVariableDescriptions = new Array<String> ();
if (!setElectronToPath) {
requiredVariables.push ("Electron");
requiredVariableDescriptions.push ("Path to Electron");
}
if (!setElectronToPath) {
LogHelper.println ("");
}
var defines = getDefines (requiredVariables, requiredVariableDescriptions, null);
if (defines != null) {
writeConfig (defines.get ("LIME_CONFIG"), defines);
}
HaxelibHelper.runCommand ("", [ "install", "electron" ], true, true);
}
public static function setupWindows ():Void {
LogHelper.println ("\x1b[1mIn order to build native executables for Windows, you must have a");