diff --git a/Build/CMake/IOS/AtomicNET.framework.plist b/Build/CMake/IOS/AtomicNET.framework.plist
new file mode 100644
index 0000000000..edcdb35478
--- /dev/null
+++ b/Build/CMake/IOS/AtomicNET.framework.plist
@@ -0,0 +1,58 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleIdentifier
+ com.atomicgameengine.atomicnetframework
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ Mono
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 3.12
+ NSPrincipalClass
+
+ CFBundleExecutable
+ AtomicNETNative
+
+ BuildMachineOSBuild
+ 13F34
+ CFBundleDevelopmentRegion
+ en
+ CFBundleSupportedPlatforms
+
+ iPhoneOS
+
+ DTCompiler
+ com.apple.compilers.llvm.clang.1_0
+ DTPlatformBuild
+ 12D508
+ DTPlatformName
+ iphoneos
+ DTPlatformVersion
+ 8.2
+ DTSDKBuild
+ 12D508
+ DTSDKName
+ iphoneos8.2
+ DTXcode
+ 0620
+ DTXcodeBuild
+ 6C131e
+ MinimumOSVersion
+ 8.0
+ UIDeviceFamily
+
+ 1
+ 2
+
+
+
diff --git a/Build/Scripts/Bootstrap.js b/Build/Scripts/Bootstrap.js
index 21831f55fd..eb469e643b 100644
--- a/Build/Scripts/Bootstrap.js
+++ b/Build/Scripts/Bootstrap.js
@@ -1 +1,61 @@
+
+var os = require('os');
+
+// Parse args
+var options = require('./Minimist')(process.argv.slice(2));
+var cmd = options._[0];
+
+// Load `jake` global
+require('../node_modules/jake/lib/jake');
+
+// Load jake tasks, etc
var host = require('./Host');
+
+// Make options availabe to host
+host.options = options;
+
+function printHelp() {
+
+ console.log("\nAtomic Editor Build Script")
+ console.log("--------------------------")
+ console.log("--help : This help text")
+ console.log("--with-android : Build with Android platform support");
+ console.log("--with-ios : Build with iOS platform support");
+ console.log("--debug : Build debug version of the editor and associated platform runtimes")
+ console.log("--noclean : Do not clean before building, useful during development")
+ console.log("--nonet : Build without AtomicNET C# scripting support")
+ console.log("--------------------------")
+
+ process.exit(0);
+}
+
+if (options["help"]) {
+ printHelp();
+}
+
+// Atomic Editor Build
+if (cmd == "buildeditor") {
+
+ console.log("\n\nBuilding Atomic Editor, this process will take a few minutes\n");
+
+ var buildTask = jake.Task['build:atomiceditor'];
+
+ if (options["with-android"]) {
+
+ if (!process.env.ANDROID_NDK) {
+ console.log("\nANDROID_NDK environment variable not set, exiting\n");
+ process.exit(1);
+ }
+ }
+
+ if (options["with-ios"]) {
+
+ if (os.platform() != "darwin") {
+ console.log("\niOS platform requires macOS, exiting\n");
+ process.exit(1);
+ }
+ }
+
+ buildTask.invoke();
+
+}
diff --git a/Build/Scripts/BuildAndroid.js b/Build/Scripts/BuildAndroid.js
index 3390b17b15..89d61f4c1a 100644
--- a/Build/Scripts/BuildAndroid.js
+++ b/Build/Scripts/BuildAndroid.js
@@ -2,8 +2,8 @@ var fs = require('fs-extra');
var path = require("path");
var host = require("./Host");
var os = require('os');
-var atomicRoot = host.atomicRoot;
+var atomicRoot = host.atomicRoot;
var buildDir = host.artifactsRoot + "Build/Android/";
namespace('build', function() {
@@ -12,34 +12,39 @@ namespace('build', function() {
async: true
}, function() {
- // Clean build
- common.cleanCreateDir(buildDir);
+ var options = host.options;
+ var cleanBuild = options["noclean"] ? false : true;
+ var debug = options["debug"] ? true : false;
+ var config = debug ? "Debug" : "Release";
+
+
+ host.setupDirs(cleanBuild, [buildDir]);
process.chdir(buildDir);
var cmds = [];
if (os.platform() == "win32") {
- cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAndroid.bat");
+ cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAndroid.bat " + config);
}
else {
- cmds.push("cmake -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=../../../Build/CMake/Toolchains/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ../../../");
+ cmds.push("cmake -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=../../../Build/CMake/Toolchains/android.toolchain.cmake -DCMAKE_BUILD_TYPE=" + config + " ../../../");
cmds.push("make -j4");
}
jake.exec(cmds, function() {
- var editorAppFolder = host.artifactsRoot + (os.platform() == "win32" ? "AtomicEditor/" : "AtomicEditor/AtomicEditor.app/");
+ var editorResourceFolder = host.artifactsRoot + (os.platform() == "win32" ? "AtomicEditor/Resources/" : "AtomicEditor/AtomicEditor.app/Contents/Resources/");
// Install Deployment
fs.copySync(buildDir + "Source/AtomicPlayer/Application/libAtomicPlayer.so",
- editorAppFolder + "Contents/Resources/ToolData/Deployment/Android/libs/armeabi-v7a/libAtomicPlayer.so");
+ editorResourceFolder + "ToolData/Deployment/Android/libs/armeabi-v7a/libAtomicPlayer.so");
complete();
}, {
printStdout: true,
- breakOnError : false
+ printStderr: true
});
});
diff --git a/Build/Scripts/BuildAtomicNET.js b/Build/Scripts/BuildAtomicNET.js
new file mode 100644
index 0000000000..f0c12b0d38
--- /dev/null
+++ b/Build/Scripts/BuildAtomicNET.js
@@ -0,0 +1,44 @@
+var fs = require('fs-extra');
+var path = require("path");
+var host = require("./Host");
+var os = require('os');
+var atomicRoot = host.atomicRoot;
+
+namespace('build', function() {
+
+ task('atomicnet', {
+ async: true
+ }, function() {
+
+ var options = host.options;
+
+ var android = options["with-android"] ? true : false;
+ var ios = options["with-ios"] ? true : false;
+ var debug = options["debug"] ? true : false;
+
+ var cmds = [];
+
+ platforms = "-platform desktop";
+ if (android)
+ platforms += " -platform android";
+ if (ios)
+ platforms += " -platform ios";
+
+ var netCmd = host.atomicTool + " net compile " + atomicRoot + "Script/AtomicNET/AtomicNETProject.json " + platforms + " -config " + (debug ? "Debug" : "Release");
+
+ console.log(netCmd);
+
+ cmds.push(netCmd);
+
+ jake.exec(cmds, function() {
+
+ complete();
+
+ }, {
+ printStdout: true,
+ printStderr: true
+ });
+
+ });
+
+}); // end of build namespace
diff --git a/Build/Scripts/BuildIOS.js b/Build/Scripts/BuildIOS.js
new file mode 100644
index 0000000000..81e7a07d59
--- /dev/null
+++ b/Build/Scripts/BuildIOS.js
@@ -0,0 +1,48 @@
+var fs = require('fs-extra');
+var path = require("path");
+var host = require("./Host");
+var os = require('os');
+
+var atomicRoot = host.atomicRoot;
+var buildDir = host.artifactsRoot + "Build/IOS/";
+
+namespace('build', function() {
+
+ task('ios_native', {
+ async: true
+ }, function() {
+
+ var options = host.options;
+ var cleanBuild = options["noclean"] ? false : true;
+ var debug = options["debug"] ? true : false;
+
+ var NETNativeSrcDir = buildDir + "Source/AtomicNET/NETNative/" + (debug ? "Debug" : "Release") + "-iphoneos/";
+ var NETNativeDestDir = host.artifactsRoot + "AtomicNET/" + (debug ? "Debug" : "Release") + "/Native/iOS/";
+
+ host.setupDirs(cleanBuild, [buildDir, NETNativeDestDir]);
+
+ process.chdir(buildDir);
+
+ var cmds = [];
+
+ cmds.push("cmake -DIOS=1 -DATOMIC_DEV_BUILD=0 -G Xcode ../../../");
+ cmds.push("xcodebuild -configuration " + (debug ? "Debug" : "Release") + " -parallelizeTargets -jobs 4");
+ //cmds.push("cd \"" + NETNativeSrcDir + "\" && install_name_tool -id @rpath/AtomicNETNative.framework/AtomicNETNative AtomicNETNative.framework/AtomicNETNative");
+ //cmds.push("cd \"" + NETNativeSrcDir + "\" && codesign --deep --force --verify --sign \"iPhone Developer\" ./AtomicNETNative.framework/");
+ cmds.push("cd \"" + NETNativeSrcDir + "\" && zip -r AtomicNETNative.framework.zip AtomicNETNative.framework");
+
+ jake.exec(cmds, function() {
+
+ fs.copySync(NETNativeSrcDir + "AtomicNETNative.framework", NETNativeDestDir + "AtomicNETNative.framework");
+ fs.copySync(NETNativeSrcDir + "AtomicNETNative.framework.zip", NETNativeDestDir + "AtomicNETNative.framework.zip");
+
+ complete();
+
+ }, {
+ printStdout: true,
+ printStderr: true
+ });
+
+ });
+
+}); // end of build namespace
diff --git a/Build/Scripts/BuildLinux.js b/Build/Scripts/BuildLinux.js
index 39bc470c0b..16f378589c 100755
--- a/Build/Scripts/BuildLinux.js
+++ b/Build/Scripts/BuildLinux.js
@@ -1,106 +1,169 @@
var fs = require('fs-extra');
var path = require("path");
-var spawnSync = require('child_process').spawnSync
var host = require("./Host");
-var atomicRoot = host.atomicRoot;
+var spawnSync = require('child_process').spawnSync
+var atomicRoot = host.atomicRoot;
var buildDir = host.artifactsRoot + "Build/Linux/";
var editorAppFolder = host.artifactsRoot + "AtomicEditor/";
-namespace('build', function() {
+var buildAtomicNET = false;
+var debug = false;
+var config = "Release";
- // Builds a standalone Atomic Editor, which can be distributed out of build tree
- task('atomiceditor', {
- async: true
- }, function() {
+function copyAtomicNET() {
- // Clean build
- var cleanBuild = true;
- if (cleanBuild) {
- common.cleanCreateDir(buildDir);
- common.cleanCreateDir(editorAppFolder);
- common.cleanCreateDir(host.getGenScriptRootDir("LINUX"));
- }
+ if (!buildAtomicNET)
+ return;
- var buildAtomicNET = false;
+ fs.copySync(atomicRoot + "Artifacts/AtomicNET/" + config,
+ editorAppFolder + "Resources/ToolData/AtomicNET/" + config);
- // TODO: build box has old node
- if (spawnSync)
- buildAtomicNET = spawnSync("which", ["xbuild"]).status == 1 ? false : true;
+ fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
+ editorAppFolder + "Resources/ToolData/AtomicNET/Build/Projects/AtomicProject.json");
+
+}
+
+function copyAtomicEditor() {
+
+ // Copy the Editor binaries
+ fs.copySync(buildDir + "Source/AtomicEditor/AtomicEditor",
+ host.artifactsRoot + "AtomicEditor/AtomicEditor");
+
+ // We need some resources to run
+ fs.copySync(atomicRoot + "Resources/CoreData",
+ editorAppFolder + "Resources/CoreData");
+
+ fs.copySync(atomicRoot + "Resources/PlayerData",
+ editorAppFolder + "Resources/PlayerData");
+
+ fs.copySync(atomicRoot + "Data/AtomicEditor",
+ editorAppFolder + "Resources/ToolData");
+
+ fs.copySync(atomicRoot + "Resources/EditorData",
+ editorAppFolder + "Resources/EditorData");
+
+ fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
+ editorAppFolder + "Resources/EditorData/AtomicEditor/EditorScripts");
+
+ fs.copySync(buildDir + "Source/AtomicPlayer/Application/AtomicPlayer",
+ editorAppFolder + "Resources/ToolData/Deployment/Linux/AtomicPlayer");
+
+ var binaryFiles = ["chrome-sandbox", "libcef.so", "natives_blob.bin", "snapshot_blob.bin"];
+
+ var resourceFiles = ["cef.pak",
+ "cef_100_percent.pak",
+ "cef_200_percent.pak",
+ "cef_extensions.pak",
+ "devtools_resources.pak",
+ "icudtl.dat",
+ "locales"];
+
+ for (var i = 0; i < binaryFiles.length; i++) {
+ fs.copySync(atomicRoot + "Submodules/CEF/Linux/Release/" + binaryFiles[i], editorAppFolder+"/" + binaryFiles[i]);
+ }
+
+ for (var i = 0; i < resourceFiles.length; i++) {
+ fs.copySync(atomicRoot + "Submodules/CEF/Linux/Resources/" + resourceFiles[i], editorAppFolder+"/" + resourceFiles[i]);
+ }
+
+
+ if (buildAtomicNET) {
+ copyAtomicNET();
+ }
+
+}
+
+namespace('build', function() {
+
+ task('atomiceditor_phase2', {
+ async: true
+ }, function() {
process.chdir(buildDir);
var cmds = [];
+ cmds.push("make AtomicEditor AtomicPlayer -j2")
- cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -DCMAKE_BUILD_TYPE=Release");
- cmds.push("make -j2")
+ jake.exec(cmds, function() {
- if (buildAtomicNET)
- cmds.push(host.atomicTool + " net compile " + atomicRoot + "Script/AtomicNET/AtomicNETProject.json LINUX Release");
+ copyAtomicEditor();
- jake.exec(cmds, function() {
+ complete();
- // Copy the Editor binaries
- fs.copySync(buildDir + "Source/AtomicEditor/AtomicEditor",
- host.artifactsRoot + "AtomicEditor/AtomicEditor");
+ }, {
+ printStdout: true
+ });
- // We need some resources to run
- fs.copySync(atomicRoot + "Resources/CoreData",
- editorAppFolder + "Resources/CoreData");
+ });
+ // Builds a standalone Atomic Editor, which can be distributed out of build tree
+ task('atomiceditor', {
+ async: true
+ }, function() {
- fs.copySync(atomicRoot + "Resources/PlayerData",
- editorAppFolder + "Resources/PlayerData");
+ var options = host.options;
- fs.copySync(atomicRoot + "Data/AtomicEditor",
- editorAppFolder + "Resources/ToolData");
+ var android = options["with-android"] ? true : false;
+ var cleanBuild = options["noclean"] ? false : true;
+ debug = options["debug"] ? true : false;
+ config = debug ? "Debug" : "Release";
- fs.copySync(atomicRoot + "Resources/EditorData",
- editorAppFolder + "Resources/EditorData");
+ var createDirs = [];
+ var removeDirs = [];
- fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
- editorAppFolder + "Resources/EditorData/AtomicEditor/EditorScripts");
+ // We clean atomicNET here as otherwise platform binaries would be deleted
+ createDirs.push(host.artifactsRoot + "AtomicNET/");
+ createDirs.push(buildDir);
+ createDirs.push(editorAppFolder);
+ createDirs.push(host.getGenScriptRootDir());
- fs.copySync(buildDir + "Source/AtomicPlayer/Application/AtomicPlayer",
- editorAppFolder + "Resources/ToolData/Deployment/Linux/AtomicPlayer");
+ removeDirs.push(host.artifactsRoot + "Build/Android/");
- // AtomicNET
+ host.setupDirs(cleanBuild, createDirs, removeDirs);
- if (buildAtomicNET) {
+ // TODO: build box has old node
+ if (spawnSync)
+ buildAtomicNET = spawnSync("which", ["xbuild"]).status == 1 ? false : true;
- fs.copySync(atomicRoot + "Artifacts/AtomicNET/Release",
- editorAppFolder + "Resources/ToolData/AtomicNET/Release");
+ process.chdir(buildDir);
- fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
- editorAppFolder + "Resources/ToolData/AtomicNET/Build/Projects/AtomicProject.json");
- }
+ var cmds = [];
- var binaryFiles = ["chrome-sandbox", "libcef.so", "natives_blob.bin", "snapshot_blob.bin"];
+ // Generate Atomic solution, AtomicTool binary, and script bindings
+ cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -DCMAKE_BUILD_TYPE=" + config);
+ cmds.push("make AtomicNETNative -j2")
- var resourceFiles = ["cef.pak",
- "cef_100_percent.pak",
- "cef_200_percent.pak",
- "cef_extensions.pak",
- "devtools_resources.pak",
- "icudtl.dat",
- "locales"];
+ jake.exec(cmds, function() {
+
+ var rootTask = jake.Task['build:atomiceditor_phase2'];
+ var task = rootTask;
- for (var i = 0; i < binaryFiles.length; i++) {
- fs.copySync(atomicRoot + "Submodules/CEF/Linux/Release/" + binaryFiles[i], editorAppFolder+"/" + binaryFiles[i]);
+ // add optional build components in reverse order
+ if (buildAtomicNET) {
+ var netTask = jake.Task['build:atomicnet'];
+ task.prereqs.push("build:atomicnet")
+ task = netTask;
}
- for (var i = 0; i < resourceFiles.length; i++) {
- fs.copySync(atomicRoot + "Submodules/CEF/Linux/Resources/" + resourceFiles[i], editorAppFolder+"/" + resourceFiles[i]);
+ if (android) {
+ var androidTask = jake.Task['build:android_native'];
+ task.prereqs.push("build:android_native")
+ task = androidTask;
}
+ rootTask.addListener('complete', function () {
+ console.log("\n\nAtomic Editor built to " + editorAppFolder + "\n\n");
+ complete();
+ });
- console.log("\n\nAtomic Editor build to " + editorAppFolder + "\n\n");
-
- complete();
+ rootTask.invoke();
}, {
- printStdout: true
+ printStdout: true,
+ printStderr: true
});
});
-});
+
+});// end of build namespace
diff --git a/Build/Scripts/BuildMac.js b/Build/Scripts/BuildMac.js
index 0ccfd88518..f8009f477b 100644
--- a/Build/Scripts/BuildMac.js
+++ b/Build/Scripts/BuildMac.js
@@ -2,102 +2,156 @@ var fs = require('fs-extra');
var path = require("path");
var spawnSync = require('child_process').spawnSync
var host = require("./Host");
-var atomicRoot = host.atomicRoot;
+var atomicRoot = host.atomicRoot;
var buildDir = host.artifactsRoot + "Build/Mac/";
var editorAppFolder = host.artifactsRoot + "/AtomicEditor/AtomicEditor.app/";
var resourceDest = editorAppFolder + "/Contents/Resources/"
-namespace('build', function() {
+var buildAtomicNET = false;
+var debug = false;
+var config = "Release";
- // Builds a standalone Atomic Editor, which can be distributed out of build tree
- task('atomiceditor', {
- async: true
- }, function(android) {
+function copyAtomicNET() {
- android = android == "android" ? true : false;
+ if (!buildAtomicNET)
+ return;
- // Clean build
- var cleanBuild = true;
- if (cleanBuild) {
- common.cleanCreateDir(host.artifactsRoot + "AtomicNET/");
- common.cleanCreateDir(buildDir);
- common.cleanCreateDir(editorAppFolder);
- common.cleanCreateDir(host.getGenScriptRootDir());
- }
+ fs.copySync(atomicRoot + "Artifacts/AtomicNET/" + config,
+ resourceDest + "ToolData/AtomicNET/" + config);
- var buildAtomicNET = spawnSync("which", ["xbuild"]).status == 1 ? false : true;
+ fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
+ resourceDest + "ToolData/AtomicNET/Build/Projects/AtomicProject.json");
- process.chdir(buildDir);
+}
- var cmds = [];
+function copyAtomicEditor() {
- cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -G Xcode");
- cmds.push("xcodebuild -target AtomicEditor -target AtomicPlayer -target AtomicNETNative -configuration Release -parallelizeTargets -jobs 4")
+ fs.copySync(buildDir + "Source/AtomicEditor/" + config + "/AtomicEditor.app", editorAppFolder);
- if (buildAtomicNET)
- cmds.push(host.atomicTool + " net compile " + atomicRoot + "Script/AtomicNET/AtomicNETProject.json " + (android ? "ANDROID" : "WINDOWS") + " Release");
+ // We need some resources to run
+ fs.copySync(atomicRoot + "Resources/CoreData",
+ resourceDest + "CoreData");
- function copyAtomicNET() {
+ fs.copySync(atomicRoot + "Resources/PlayerData",
+ resourceDest + "PlayerData");
- if (!buildAtomicNET)
- return;
+ fs.copySync(atomicRoot + "Data/AtomicEditor",
+ resourceDest + "ToolData");
- fs.copySync(atomicRoot + "Artifacts/AtomicNET/Release",
- resourceDest + "ToolData/AtomicNET/Release");
+ fs.copySync(atomicRoot + "Resources/EditorData",
+ resourceDest + "EditorData");
- fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
- resourceDest + "ToolData/AtomicNET/Build/Projects/AtomicProject.json");
+ fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
+ resourceDest + "EditorData/AtomicEditor/EditorScripts");
- }
+ // copy the mac player binary to deployment
+ var playerBinary = buildDir + "Source/AtomicPlayer/Application/" + config + "/AtomicPlayer.app/Contents/MacOS/AtomicPlayer";
+
+ fs.copySync(playerBinary, resourceDest + "ToolData/Deployment/MacOS/AtomicPlayer.app/Contents/MacOS/AtomicPlayer");
+
+ if (buildAtomicNET) {
+ copyAtomicNET();
+ }
+}
+
+namespace('build', function() {
+
+ task('atomiceditor_phase2', {
+ async: true
+ }, function() {
+
+ process.chdir(buildDir);
+
+ var cmds = [];
+ cmds.push("xcodebuild -target AtomicEditor -target AtomicPlayer -configuration " + config + " -parallelizeTargets -jobs 4")
jake.exec(cmds, function() {
- fs.copySync(buildDir + "Source/AtomicEditor/Release/AtomicEditor.app", editorAppFolder);
+ copyAtomicEditor();
+
+ complete();
+
+ }, {
+ printStdout: true
+ });
+
+ });
- // We need some resources to run
- fs.copySync(atomicRoot + "Resources/CoreData",
- resourceDest + "CoreData");
+ // Builds a standalone Atomic Editor, which can be distributed out of build tree
+ task('atomiceditor', {
+ async: true
+ }, function() {
- fs.copySync(atomicRoot + "Resources/PlayerData",
- resourceDest + "PlayerData");
+ var options = host.options;
- fs.copySync(atomicRoot + "Data/AtomicEditor",
- resourceDest + "ToolData");
+ var android = options["with-android"] ? true : false;
+ var ios = options["with-ios"] ? true : false;
+ var cleanBuild = options["noclean"] ? false : true;
+ debug = options["debug"] ? true : false;
+ config = debug ? "Debug" : "Release";
- fs.copySync(atomicRoot + "Resources/EditorData",
- resourceDest + "EditorData");
+ var createDirs = [];
+ var removeDirs = [];
- fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
- resourceDest + "EditorData/AtomicEditor/EditorScripts");
+ // We clean atomicNET here as otherwise platform binaries would be deleted
+ createDirs.push(host.artifactsRoot + "AtomicNET/");
+ createDirs.push(buildDir);
+ createDirs.push(editorAppFolder);
+ createDirs.push(host.getGenScriptRootDir());
- // copy the mac player binary to deployment
- var playerBinary = buildDir + "Source/AtomicPlayer/Application/Release/AtomicPlayer.app/Contents/MacOS/AtomicPlayer";
+ removeDirs.push(host.artifactsRoot + "Build/Android/");
+ removeDirs.push(host.artifactsRoot + "Build/IOS/");
- fs.copySync(playerBinary, resourceDest + "ToolData/Deployment/MacOS/AtomicPlayer.app/Contents/MacOS/AtomicPlayer");
+ host.setupDirs(cleanBuild, createDirs, removeDirs);
- if (android) {
+ if (!options["nonet"]) {
+ buildAtomicNET = spawnSync("which", ["xbuild"]).status == 1 ? false : true;
+ }
+
+ process.chdir(buildDir);
+
+ var cmds = [];
- var androidNativeTask = jake.Task['build:android_native'];
+ // Generate XCode project, AtomicTool binary, and script bindings
+ cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -G Xcode");
+ cmds.push("xcodebuild -target GenerateScriptBindings -target AtomicNETNative -configuration " + config + " -parallelizeTargets -jobs 4")
- androidNativeTask.addListener('complete', function () {
- copyAtomicNET();
- console.log("\n\nAtomic Editor build to " + editorAppFolder + "\n\n");
- complete();
- });
+ jake.exec(cmds, function() {
- androidNativeTask.invoke();
+ var rootTask = jake.Task['build:atomiceditor_phase2'];
+ var task = rootTask;
+ // add optional build components in reverse order
+ if (buildAtomicNET) {
+ var netTask = jake.Task['build:atomicnet'];
+ task.prereqs.push("build:atomicnet")
+ task = netTask;
}
- else {
- copyAtomicNET();
- console.log("\n\nAtomic Editor build to " + editorAppFolder + "\n\n");
- complete();
+
+ if (ios) {
+ var iosTask = jake.Task['build:ios_native'];
+ task.prereqs.push("build:ios_native")
+ task = iosTask;
}
+ if (android) {
+ var androidTask = jake.Task['build:android_native'];
+ task.prereqs.push("build:android_native")
+ task = androidTask;
+ }
+
+ rootTask.addListener('complete', function () {
+ console.log("\n\nAtomic Editor built to " + editorAppFolder + "\n\n");
+ complete();
+ });
+
+ rootTask.invoke();
+
}, {
- printStdout: true
+ printStdout: true,
+ printStderr: true
});
});
@@ -124,7 +178,8 @@ namespace('build', function() {
complete();
}, {
- printStdout: true
+ printStdout: true,
+ printStderr: true
});
});
diff --git a/Build/Scripts/BuildWindows.js b/Build/Scripts/BuildWindows.js
index 07daec2f27..724eaa2166 100644
--- a/Build/Scripts/BuildWindows.js
+++ b/Build/Scripts/BuildWindows.js
@@ -1,96 +1,144 @@
var fs = require('fs-extra');
var path = require("path");
var host = require("./Host");
-var atomicRoot = host.atomicRoot;
+var atomicRoot = host.atomicRoot;
var buildDir = host.artifactsRoot + "Build/Windows/";
var editorAppFolder = host.artifactsRoot + "AtomicEditor/";
-namespace('build', function() {
+var buildAtomicNET = true;
+var debug = false;
+var config = "Release";
- // Builds a standalone Atomic Editor, which can be distributed out of build tree
- task('atomiceditor', {
- async: true
- }, function(android) {
+function copyAtomicNET() {
- android = android == "android" ? true : false;
+ if (!buildAtomicNET)
+ return;
- // Clean build
- var cleanBuild = true;
- if (cleanBuild) {
- common.cleanCreateDir(host.artifactsRoot + "AtomicNET/");
- common.cleanCreateDir(buildDir);
- common.cleanCreateDir(editorAppFolder);
- common.cleanCreateDir(host.getGenScriptRootDir());
- }
+ fs.copySync(atomicRoot + "Artifacts/AtomicNET/" + config,
+ editorAppFolder + "Resources/ToolData/AtomicNET/" + config);
- process.chdir(buildDir);
+ fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
+ editorAppFolder + "Resources/ToolData/AtomicNET/Build/Projects/AtomicProject.json");
- var cmds = [];
+}
- // Build the AtomicEditor
- cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAtomicEditor.bat");
- cmds.push(host.atomicTool + " net compile " + atomicRoot + "Script/AtomicNET/AtomicNETProject.json " + (android ? "ANDROID" : "WINDOWS") + " Release");
+function copyAtomicEditor() {
- function copyAtomicNET() {
+ // Copy the Editor binaries
+ fs.copySync(buildDir + "Source/AtomicEditor/" + config,
+ host.artifactsRoot + "AtomicEditor");
- fs.copySync(atomicRoot + "Artifacts/AtomicNET/Release",
- editorAppFolder + "Resources/ToolData/AtomicNET/Release");
+ // We need some resources to run
+ fs.copySync(atomicRoot + "Resources/CoreData",
+ editorAppFolder + "Resources/CoreData");
- fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
- editorAppFolder + "Resources/ToolData/AtomicNET/Build/Projects/AtomicProject.json");
+ fs.copySync(atomicRoot + "Resources/PlayerData",
+ editorAppFolder + "Resources/PlayerData");
- }
+ fs.copySync(atomicRoot + "Data/AtomicEditor",
+ editorAppFolder + "Resources/ToolData");
+
+ fs.copySync(atomicRoot + "Resources/EditorData",
+ editorAppFolder + "Resources/EditorData");
+
+ fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
+ editorAppFolder + "Resources/EditorData/AtomicEditor/EditorScripts");
+
+ fs.copySync(buildDir + "Source/AtomicPlayer/Application/" + config +"/AtomicPlayer.exe",
+ editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/AtomicPlayer.exe");
+
+ fs.copySync(buildDir + "Source/AtomicPlayer/Application/" + config + "/D3DCompiler_47.dll",
+ editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/D3DCompiler_47.dll");
+
+ if (buildAtomicNET) {
+ copyAtomicNET();
+ }
+
+}
+
+namespace('build', function() {
+
+ task('atomiceditor_phase2', {
+ async: true
+ }, function() {
+
+ process.chdir(buildDir);
+
+ var cmds = [];
+ cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAtomicEditorPhase2.bat " + config);
jake.exec(cmds, function() {
- // Copy the Editor binaries
- fs.copySync(buildDir + "Source/AtomicEditor/Release",
- host.artifactsRoot + "AtomicEditor");
+ copyAtomicEditor();
- // We need some resources to run
- fs.copySync(atomicRoot + "Resources/CoreData",
- editorAppFolder + "Resources/CoreData");
+ complete();
+
+ }, {
+ printStdout: true
+ });
- fs.copySync(atomicRoot + "Resources/PlayerData",
- editorAppFolder + "Resources/PlayerData");
+ });
+ // Builds a standalone Atomic Editor, which can be distributed out of build tree
+ task('atomiceditor', {
+ async: true
+ }, function() {
- fs.copySync(atomicRoot + "Data/AtomicEditor",
- editorAppFolder + "Resources/ToolData");
+ var options = host.options;
- fs.copySync(atomicRoot + "Resources/EditorData",
- editorAppFolder + "Resources/EditorData");
+ var android = options["with-android"] ? true : false;
+ var cleanBuild = options["noclean"] ? false : true;
+ debug = options["debug"] ? true : false;
+ config = debug ? "Debug" : "Release";
- fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
- editorAppFolder + "Resources/EditorData/AtomicEditor/EditorScripts");
+ var createDirs = [];
+ var removeDirs = [];
- fs.copySync(buildDir + "Source/AtomicPlayer/Application/Release/AtomicPlayer.exe",
- editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/AtomicPlayer.exe");
+ // We clean atomicNET here as otherwise platform binaries would be deleted
+ createDirs.push(host.artifactsRoot + "AtomicNET/");
+ createDirs.push(buildDir);
+ createDirs.push(editorAppFolder);
+ createDirs.push(host.getGenScriptRootDir());
- fs.copySync(buildDir + "Source/AtomicPlayer/Application/Release/D3DCompiler_47.dll",
- editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/D3DCompiler_47.dll");
+ removeDirs.push(host.artifactsRoot + "Build/Android/");
- if (android) {
+ host.setupDirs(cleanBuild, createDirs, removeDirs);
- var androidNativeTask = jake.Task['build:android_native'];
+ process.chdir(buildDir);
- androidNativeTask.addListener('complete', function () {
- copyAtomicNET();
- console.log("\nAtomic Editor build to ", editorAppFolder);
- complete();
- });
+ var cmds = [];
- androidNativeTask.invoke();
+ // Generate Atomic solution, AtomicTool binary, and script bindings
+ cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAtomicEditorPhase1.bat " + config);
+ jake.exec(cmds, function() {
+
+ var rootTask = jake.Task['build:atomiceditor_phase2'];
+ var task = rootTask;
+
+ // add optional build components in reverse order
+ if (buildAtomicNET) {
+ var netTask = jake.Task['build:atomicnet'];
+ task.prereqs.push("build:atomicnet")
+ task = netTask;
}
- else {
- copyAtomicNET();
- console.log("\nAtomic Editor build to ", editorAppFolder);
- complete();
+
+ if (android) {
+ var androidTask = jake.Task['build:android_native'];
+ task.prereqs.push("build:android_native")
+ task = androidTask;
}
+ rootTask.addListener('complete', function () {
+ console.log("\n\nAtomic Editor built to " + editorAppFolder + "\n\n");
+ complete();
+ });
+
+ rootTask.invoke();
+
}, {
- printStdout: true
+ printStdout: true,
+ printStderr: true
});
});
@@ -124,4 +172,5 @@ namespace('build', function() {
});
-}); // end of build namespace
+
+});// end of build namespace
diff --git a/Build/Scripts/Host.js b/Build/Scripts/Host.js
index 6c2a0e521d..7d23ae00ec 100644
--- a/Build/Scripts/Host.js
+++ b/Build/Scripts/Host.js
@@ -13,4 +13,6 @@ if (os.platform() == "win32") {
require("./BuildCommon");
require("./BuildAndroid");
+require("./BuildIOS");
require("./BuildWeb");
+require("./BuildAtomicNET");
diff --git a/Build/Scripts/HostCommon.js b/Build/Scripts/HostCommon.js
index ed18543694..313ba5e4bf 100644
--- a/Build/Scripts/HostCommon.js
+++ b/Build/Scripts/HostCommon.js
@@ -138,6 +138,29 @@ function testCreateDir(directory) {
}
}
+function setupDirs(clean, createDirs, removeDirs) {
+
+ if (createDirs) {
+ for (var i = 0; i < createDirs.length; i++) {
+
+ var path = createDirs[i];
+ if (!fs.existsSync(path) || clean) {
+ cleanCreateDir(path);
+ }
+ }
+ }
+
+ if (removeDirs) {
+ for (var i = 0; i < removeDirs.length; i++) {
+
+ var path = removeDirs[i];
+ if (fs.existsSync(path) && clean) {
+ testRemoveDir(path);
+ }
+ }
+ }
+
+}
function testRemoveDir(path) {
@@ -160,3 +183,4 @@ exports.getScriptModules = getScriptModules;
exports.getGenScriptFilenames = getGenScriptFilenames;
exports.createGenScriptFiles = createGenScriptFiles;
exports.getGenScriptRootDir = getGenScriptRootDir;
+exports.setupDirs = setupDirs;
diff --git a/Build/Scripts/Minimist.js b/Build/Scripts/Minimist.js
new file mode 100644
index 0000000000..e06783fb1c
--- /dev/null
+++ b/Build/Scripts/Minimist.js
@@ -0,0 +1,235 @@
+module.exports = function (args, opts) {
+ if (!opts) opts = {};
+
+ var flags = { bools : {}, strings : {}, unknownFn: null };
+
+ if (typeof opts['unknown'] === 'function') {
+ flags.unknownFn = opts['unknown'];
+ }
+
+ if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
+ flags.allBools = true;
+ } else {
+ [].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
+ flags.bools[key] = true;
+ });
+ }
+
+ var aliases = {};
+ Object.keys(opts.alias || {}).forEach(function (key) {
+ aliases[key] = [].concat(opts.alias[key]);
+ aliases[key].forEach(function (x) {
+ aliases[x] = [key].concat(aliases[key].filter(function (y) {
+ return x !== y;
+ }));
+ });
+ });
+
+ [].concat(opts.string).filter(Boolean).forEach(function (key) {
+ flags.strings[key] = true;
+ if (aliases[key]) {
+ flags.strings[aliases[key]] = true;
+ }
+ });
+
+ var defaults = opts['default'] || {};
+
+ var argv = { _ : [] };
+ Object.keys(flags.bools).forEach(function (key) {
+ setArg(key, defaults[key] === undefined ? false : defaults[key]);
+ });
+
+ var notFlags = [];
+
+ if (args.indexOf('--') !== -1) {
+ notFlags = args.slice(args.indexOf('--')+1);
+ args = args.slice(0, args.indexOf('--'));
+ }
+
+ function argDefined(key, arg) {
+ return (flags.allBools && /^--[^=]+$/.test(arg)) ||
+ flags.strings[key] || flags.bools[key] || aliases[key];
+ }
+
+ function setArg (key, val, arg) {
+ if (arg && flags.unknownFn && !argDefined(key, arg)) {
+ if (flags.unknownFn(arg) === false) return;
+ }
+
+ var value = !flags.strings[key] && isNumber(val)
+ ? Number(val) : val
+ ;
+ setKey(argv, key.split('.'), value);
+
+ (aliases[key] || []).forEach(function (x) {
+ setKey(argv, x.split('.'), value);
+ });
+ }
+
+ function setKey (obj, keys, value) {
+ var o = obj;
+ keys.slice(0,-1).forEach(function (key) {
+ if (o[key] === undefined) o[key] = {};
+ o = o[key];
+ });
+
+ var key = keys[keys.length - 1];
+ if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
+ o[key] = value;
+ }
+ else if (Array.isArray(o[key])) {
+ o[key].push(value);
+ }
+ else {
+ o[key] = [ o[key], value ];
+ }
+ }
+
+ function aliasIsBoolean(key) {
+ return aliases[key].some(function (x) {
+ return flags.bools[x];
+ });
+ }
+
+ for (var i = 0; i < args.length; i++) {
+ var arg = args[i];
+
+ if (/^--.+=/.test(arg)) {
+ // Using [\s\S] instead of . because js doesn't support the
+ // 'dotall' regex modifier. See:
+ // http://stackoverflow.com/a/1068308/13216
+ var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
+ var key = m[1];
+ var value = m[2];
+ if (flags.bools[key]) {
+ value = value !== 'false';
+ }
+ setArg(key, value, arg);
+ }
+ else if (/^--no-.+/.test(arg)) {
+ var key = arg.match(/^--no-(.+)/)[1];
+ setArg(key, false, arg);
+ }
+ else if (/^--.+/.test(arg)) {
+ var key = arg.match(/^--(.+)/)[1];
+ var next = args[i + 1];
+ if (next !== undefined && !/^-/.test(next)
+ && !flags.bools[key]
+ && !flags.allBools
+ && (aliases[key] ? !aliasIsBoolean(key) : true)) {
+ setArg(key, next, arg);
+ i++;
+ }
+ else if (/^(true|false)$/.test(next)) {
+ setArg(key, next === 'true', arg);
+ i++;
+ }
+ else {
+ setArg(key, flags.strings[key] ? '' : true, arg);
+ }
+ }
+ else if (/^-[^-]+/.test(arg)) {
+ var letters = arg.slice(1,-1).split('');
+
+ var broken = false;
+ for (var j = 0; j < letters.length; j++) {
+ var next = arg.slice(j+2);
+
+ if (next === '-') {
+ setArg(letters[j], next, arg)
+ continue;
+ }
+
+ if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
+ setArg(letters[j], next.split('=')[1], arg);
+ broken = true;
+ break;
+ }
+
+ if (/[A-Za-z]/.test(letters[j])
+ && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
+ setArg(letters[j], next, arg);
+ broken = true;
+ break;
+ }
+
+ if (letters[j+1] && letters[j+1].match(/\W/)) {
+ setArg(letters[j], arg.slice(j+2), arg);
+ broken = true;
+ break;
+ }
+ else {
+ setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
+ }
+ }
+
+ var key = arg.slice(-1)[0];
+ if (!broken && key !== '-') {
+ if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
+ && !flags.bools[key]
+ && (aliases[key] ? !aliasIsBoolean(key) : true)) {
+ setArg(key, args[i+1], arg);
+ i++;
+ }
+ else if (args[i+1] && /true|false/.test(args[i+1])) {
+ setArg(key, args[i+1] === 'true', arg);
+ i++;
+ }
+ else {
+ setArg(key, flags.strings[key] ? '' : true, arg);
+ }
+ }
+ }
+ else {
+ if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
+ argv._.push(
+ flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
+ );
+ }
+ if (opts.stopEarly) {
+ argv._.push.apply(argv._, args.slice(i + 1));
+ break;
+ }
+ }
+ }
+
+ Object.keys(defaults).forEach(function (key) {
+ if (!hasKey(argv, key.split('.'))) {
+ setKey(argv, key.split('.'), defaults[key]);
+
+ (aliases[key] || []).forEach(function (x) {
+ setKey(argv, x.split('.'), defaults[key]);
+ });
+ }
+ });
+
+ if (opts['--']) {
+ argv['--'] = new Array();
+ notFlags.forEach(function(key) {
+ argv['--'].push(key);
+ });
+ }
+ else {
+ notFlags.forEach(function(key) {
+ argv._.push(key);
+ });
+ }
+
+ return argv;
+};
+
+function hasKey (obj, keys) {
+ var o = obj;
+ keys.slice(0,-1).forEach(function (key) {
+ o = (o[key] || {});
+ });
+
+ var key = keys[keys.length - 1];
+ return key in o;
+}
+
+function isNumber (x) {
+ if (typeof x === 'number') return true;
+ if (/^0x[0-9a-f]+$/i.test(x)) return true;
+ return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
+}
diff --git a/Build/Scripts/Windows/CompileAndroid.bat b/Build/Scripts/Windows/CompileAndroid.bat
index c88d8f2dd2..8fd0a6c414 100644
--- a/Build/Scripts/Windows/CompileAndroid.bat
+++ b/Build/Scripts/Windows/CompileAndroid.bat
@@ -1,3 +1,3 @@
SET PATH=%ANDROID_NDK%\prebuilt\windows\bin\;%PATH%
-cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../../../Build/CMake/Toolchains/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ../../../
+cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../../../Build/CMake/Toolchains/android.toolchain.cmake -DCMAKE_BUILD_TYPE=%1 ../../../
%ANDROID_NDK%\prebuilt\windows\bin\make.exe -j4
diff --git a/Build/Scripts/Windows/CompileAtomicEditorPhase1.bat b/Build/Scripts/Windows/CompileAtomicEditorPhase1.bat
new file mode 100644
index 0000000000..bf4aa8907f
--- /dev/null
+++ b/Build/Scripts/Windows/CompileAtomicEditorPhase1.bat
@@ -0,0 +1,3 @@
+call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
+cmake ..\\..\\..\\ -DATOMIC_DEV_BUILD=0 -G "Visual Studio 14 2015 Win64"
+msbuild /m Atomic.sln /t:AtomicNETNative /p:Configuration=%1 /p:Platform=x64
diff --git a/Build/Scripts/Windows/CompileAtomicEditorPhase2.bat b/Build/Scripts/Windows/CompileAtomicEditorPhase2.bat
new file mode 100644
index 0000000000..e647f96512
--- /dev/null
+++ b/Build/Scripts/Windows/CompileAtomicEditorPhase2.bat
@@ -0,0 +1,2 @@
+call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
+msbuild /m Atomic.sln /t:AtomicEditor /t:AtomicPlayer /p:Configuration=%1 /p:Platform=x64
diff --git a/Build_AtomicEditor.bat b/Build_AtomicEditor.bat
index ef81fac815..e0ecd687bb 100644
--- a/Build_AtomicEditor.bat
+++ b/Build_AtomicEditor.bat
@@ -1,37 +1,2 @@
@echo OFF
-setlocal enabledelayedexpansion
-
-set ATOMICEDITOR_BUILD_CMD=Build\Windows\node\node.exe Build\node_modules\jake\bin\cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
-
-for %%a in (%*) do (
- if /I "%%a"=="--with-android" (set ATOMICEDITOR_ANDROID=YES)
-)
-
-:: If we're building in android support, make sure ANDROID_NDK is defined
-if "%ATOMICEDITOR_ANDROID%" == "YES" (
-
- if "%ANDROID_NDK%" == "" (
- @echo:
- echo ANDROID_NDK not set, exiting
- @echo:
- exit /B
- )
-
- @echo:
- echo Building Atomic Editor with Android support
- @echo:
- set ATOMICEDITOR_BUILD_CMD=!ATOMICEDITOR_BUILD_CMD![android]
-)
-
-@echo:
-@echo:
-ECHO Building Atomic Editor, this process will take a few minutes
-@echo:
-@echo:
-PAUSE
-%ATOMICEDITOR_BUILD_CMD%
-@echo:
-@echo:
-PAUSE
-
-endlocal
+Build\Windows\node\node.exe ./Build/Scripts/Bootstrap.js buildeditor %*
diff --git a/Build_AtomicEditor.sh b/Build_AtomicEditor.sh
index 7a92db3e46..edca5ae51e 100755
--- a/Build_AtomicEditor.sh
+++ b/Build_AtomicEditor.sh
@@ -1,23 +1,9 @@
#!/usr/bin/env sh
-buildcmd="build:atomiceditor"
-
-for var in "$@"
-do
- if [ $var == "--with-android" ]; then
- if [ "$ANDROID_NDK" == "" ]; then
- echo "\n\nANDROID_NDK environment variable not set, exiting\n\n"
- exit 1
- fi
- echo "\n\nBuilding Atomic Editor with Android support\n\n"
- buildcmd+="[android]"
- fi
-done
-
if [ "$(uname)" = "Darwin" ]; then
- ./Build/Mac/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js $buildcmd
+ ./Build/Mac/node/node ./Build/Scripts/Bootstrap.js buildeditor "$@"
elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then
- ./Build/Linux/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js $buildcmd
+ ./Build/Linux/node/node ./Build/Scripts/Bootstrap.js buildeditor "$@"
elif [ "$(expr substr $(uname -s) 1 7)" = "MSYS_NT" ]; then
- ./Build/Windows/node/node.exe ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js $buildcmd
+ ./Build/Windows/node/node.exe ./Build/Scripts/Bootstrap.js buildeditor "$@"
fi
diff --git a/Script/AtomicNET/AtomicNET/Application/Application.cs b/Script/AtomicNET/AtomicNET/Application/Application.cs
index 9a59d7b3e4..5dc45b4be5 100644
--- a/Script/AtomicNET/AtomicNET/Application/Application.cs
+++ b/Script/AtomicNET/AtomicNET/Application/Application.cs
@@ -28,7 +28,14 @@ public static int Run(Type appDelegateType, string[] args)
app = NETIPCPlayerApp.Create(args);
#endif
-#if ATOMIC_ANDROID
+#if ATOMIC_IOS
+ // On iOS, we need to set main ready as main() isn't being called
+ SDLEvents.SetMainReady();
+#endif
+
+
+#if ATOMIC_ANDROID || ATOMIC_IOS
+
app = NETAtomicPlayer.Create(args);
var renderer = AtomicNET.GetSubsystem();
diff --git a/Script/AtomicNET/AtomicNET/Core/AtomicNET.cs b/Script/AtomicNET/AtomicNET/Core/AtomicNET.cs
index f5ee5612cb..15b8fe3471 100644
--- a/Script/AtomicNET/AtomicNET/Core/AtomicNET.cs
+++ b/Script/AtomicNET/AtomicNET/Core/AtomicNET.cs
@@ -77,11 +77,7 @@ public static void Initialize()
PlayerModule.Initialize();
- coreDelegates = new CoreDelegates();
- coreDelegates.eventDispatch = NativeCore.EventDispatch;
- coreDelegates.updateDispatch = NativeCore.UpdateDispatch;
-
- IntPtr coreptr = csi_Atomic_NETCore_Initialize(ref coreDelegates);
+ IntPtr coreptr = csi_Atomic_NETCore_Initialize(NativeCore.EventDispatch, NativeCore.UpdateDispatch);
NETCore core = (coreptr == IntPtr.Zero ? null : NativeCore.WrapNative(coreptr));
@@ -102,10 +98,9 @@ public static void Initialize()
}
[DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
- private static extern IntPtr csi_Atomic_NETCore_Initialize(ref CoreDelegates delegates);
+ private static extern IntPtr csi_Atomic_NETCore_Initialize(EventDispatchDelegate eventDispatch, UpdateDispatchDelegate updateDispatch);
private static Context context;
- private static CoreDelegates coreDelegates;
private static Dictionary subSystems = new Dictionary();
}
diff --git a/Script/AtomicNET/AtomicNET/Core/Constants.cs b/Script/AtomicNET/AtomicNET/Core/Constants.cs
index dd017905bd..f86c1cbbbd 100644
--- a/Script/AtomicNET/AtomicNET/Core/Constants.cs
+++ b/Script/AtomicNET/AtomicNET/Core/Constants.cs
@@ -4,7 +4,9 @@ namespace AtomicEngine
public static partial class Constants
{
-#if __MonoCS__
+#if ATOMIC_IOS
+ public const string LIBNAME = "@rpath/AtomicNETNative.framework/AtomicNETNative";
+#elif __MonoCS__
public const string LIBNAME = "AtomicNETNative";
#else
public const string LIBNAME = "AtomicNETNative.dll";
diff --git a/Script/AtomicNET/AtomicNET/Core/NativeCore.cs b/Script/AtomicNET/AtomicNET/Core/NativeCore.cs
index e346603352..4501730e71 100644
--- a/Script/AtomicNET/AtomicNET/Core/NativeCore.cs
+++ b/Script/AtomicNET/AtomicNET/Core/NativeCore.cs
@@ -5,9 +5,19 @@
using System.Linq;
using static System.Reflection.IntrospectionExtensions;
+#if ATOMIC_IOS
+using ObjCRuntime;
+#endif
+
namespace AtomicEngine
{
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void EventDispatchDelegate(IntPtr sender, uint eventType, IntPtr eventData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void UpdateDispatchDelegate(float timeStep);
+
public class NativeType
{
@@ -124,6 +134,26 @@ internal static void Initialize()
svm[i] = new ScriptVariantMap();
}
+
+ static float expireDelta = 0.0f;
+
+ // called ahead of E_UPDATE event
+#if ATOMIC_IOS
+ [MonoPInvokeCallback(typeof(UpdateDispatchDelegate))]
+#endif
+ public static void UpdateDispatch(float timeStep)
+ {
+ expireDelta += timeStep;
+ if (expireDelta > 2.0f)
+ {
+ expireDelta = 0.0f;
+ ExpireNatives();
+ }
+ }
+
+ #if ATOMIC_IOS
+ [MonoPInvokeCallback(typeof(EventDispatchDelegate))]
+ #endif
public static void EventDispatch(IntPtr sender, uint eventType, IntPtr eventData)
{
List eventReceivers;
@@ -240,19 +270,6 @@ static void ExpireNatives()
}
- static float expireDelta = 0.0f;
-
- // called ahead of E_UPDATE event
- public static void UpdateDispatch(float timeStep)
- {
- expireDelta += timeStep;
- if (expireDelta > 2.0f)
- {
- expireDelta = 0.0f;
- ExpireNatives();
- }
- }
-
// register a newly created native
public static IntPtr RegisterNative(IntPtr native, RefCounted r)
{
diff --git a/Script/AtomicNET/AtomicNET/Core/NativeEvents.cs b/Script/AtomicNET/AtomicNET/Core/NativeEvents.cs
index b241d68cde..a89f2f1d75 100644
--- a/Script/AtomicNET/AtomicNET/Core/NativeEvents.cs
+++ b/Script/AtomicNET/AtomicNET/Core/NativeEvents.cs
@@ -3,28 +3,10 @@
namespace AtomicEngine
{
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void EventDispatchDelegate(IntPtr sender, uint eventType, IntPtr eventData);
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void UpdateDispatchDelegate(float timeStep);
-
public delegate void EventDelegate(uint eventType, ScriptVariantMap eventData);
public delegate void SenderEventDelegate(AObject sender, uint eventType, ScriptVariantMap eventData);
- public delegate void HandleUpdateDelegate(float timeStep);
-
- [StructLayout(LayoutKind.Sequential)]
- public struct CoreDelegates
- {
- [MarshalAs(UnmanagedType.FunctionPtr)]
- public EventDispatchDelegate eventDispatch;
-
- [MarshalAs(UnmanagedType.FunctionPtr)]
- public UpdateDispatchDelegate updateDispatch;
- }
-
public partial class ScriptVariantMap
{
public void CopyVariantMap(IntPtr vm)
diff --git a/Script/AtomicNET/AtomicNET/Core/SDLEvents.cs b/Script/AtomicNET/AtomicNET/Core/SDLEvents.cs
new file mode 100644
index 0000000000..91f4d7ee82
--- /dev/null
+++ b/Script/AtomicNET/AtomicNET/Core/SDLEvents.cs
@@ -0,0 +1,144 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+ public static class SDLEvents
+ {
+ [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
+ static extern int SDL_SendWindowEvent(IntPtr window, byte windowevent, int data1, int data2);
+
+ [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
+ static extern int SDL_SendAppEvent(byte eventType);
+
+ [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
+ static extern void SDL_SetMainReady();
+
+ public static void SetMainReady() => SDL_SetMainReady();
+
+ public static void SendWindowEvent(SdlWindowEvent wndEvent, int data1 = 0, int data2 = 0)
+ {
+ var graphics = AtomicNET.GetSubsystem();
+ SDL_SendWindowEvent(graphics.SDLWindow, (byte) wndEvent, data1, data2);
+ }
+
+ public static void SendAppEvent(SdlEventType eventType) => SDL_SendAppEvent((byte)eventType);
+ }
+
+ //see SDL_Video.h
+ public enum SdlWindowEvent
+ {
+ SDL_WINDOWEVENT_NONE, /* Never used */
+ SDL_WINDOWEVENT_SHOWN, /* Window has been shown */
+ SDL_WINDOWEVENT_HIDDEN, /* Window has been hidden */
+ SDL_WINDOWEVENT_EXPOSED, /* Window has been exposed and should be redrawn */
+ SDL_WINDOWEVENT_MOVED, /* Window has been moved to data1, data2 */
+ SDL_WINDOWEVENT_RESIZED, /* Window has been resized to data1xdata2 */
+ SDL_WINDOWEVENT_SIZE_CHANGED, /* The window size has changed, either as a result of an API call or through the system or user changing the window size. */
+ SDL_WINDOWEVENT_MINIMIZED, /* Window has been minimized */
+ SDL_WINDOWEVENT_MAXIMIZED, /* Window has been maximized */
+ SDL_WINDOWEVENT_RESTORED, /* Window has been restored to normal size and position */
+ SDL_WINDOWEVENT_ENTER, /* Window has gained mouse focus */
+ SDL_WINDOWEVENT_LEAVE, /* Window has lost mouse focus */
+ SDL_WINDOWEVENT_FOCUS_GAINED, /* Window has gained keyboard focus */
+ SDL_WINDOWEVENT_FOCUS_LOST, /* Window has lost keyboard focus */
+ SDL_WINDOWEVENT_CLOSE /* The window manager requests that the window be closed */
+ }
+
+ //see SDL_Events.h
+ public enum SdlEventType
+ {
+ SDL_FIRSTEVENT = 0, /**< Unused (do not remove) */
+
+ /* Application events */
+ SDL_QUIT = 0x100, /**< User-requested quit */
+
+ /* These application events have special meaning on iOS, see README-ios.txt for details */
+ SDL_APP_TERMINATING, /**< The application is being terminated by the OS
+ Called on iOS in applicationWillTerminate()
+ Called on Android in onDestroy()
+ */
+ SDL_APP_LOWMEMORY, /**< The application is low on memory, free memory if possible.
+ Called on iOS in applicationDidReceiveMemoryWarning()
+ Called on Android in onLowMemory()
+ */
+ SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background
+ Called on iOS in applicationWillResignActive()
+ Called on Android in onPause()
+ */
+ SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time
+ Called on iOS in applicationDidEnterBackground()
+ Called on Android in onPause()
+ */
+ SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground
+ Called on iOS in applicationWillEnterForeground()
+ Called on Android in onResume()
+ */
+ SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive
+ Called on iOS in applicationDidBecomeActive()
+ Called on Android in onResume()
+ */
+
+ /* Window events */
+ SDL_WINDOWEVENT = 0x200, /**< Window state change */
+ SDL_SYSWMEVENT, /**< System specific event */
+
+ /* Keyboard events */
+ SDL_KEYDOWN = 0x300, /**< Key pressed */
+ SDL_KEYUP, /**< Key released */
+ SDL_TEXTEDITING, /**< Keyboard text editing (composition) */
+ SDL_TEXTINPUT, /**< Keyboard text input */
+
+ /* Mouse events */
+ SDL_MOUSEMOTION = 0x400, /**< Mouse moved */
+ SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */
+ SDL_MOUSEBUTTONUP, /**< Mouse button released */
+ SDL_MOUSEWHEEL, /**< Mouse wheel motion */
+
+ /* Joystick events */
+ SDL_JOYAXISMOTION = 0x600, /**< Joystick axis motion */
+ SDL_JOYBALLMOTION, /**< Joystick trackball motion */
+ SDL_JOYHATMOTION, /**< Joystick hat position change */
+ SDL_JOYBUTTONDOWN, /**< Joystick button pressed */
+ SDL_JOYBUTTONUP, /**< Joystick button released */
+ SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */
+ SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */
+
+ /* Game controller events */
+ SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */
+ SDL_CONTROLLERBUTTONDOWN, /**< Game controller button pressed */
+ SDL_CONTROLLERBUTTONUP, /**< Game controller button released */
+ SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */
+ SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */
+ SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */
+
+ /* Touch events */
+ SDL_FINGERDOWN = 0x700,
+ SDL_FINGERUP,
+ SDL_FINGERMOTION,
+
+ /* Gesture events */
+ SDL_DOLLARGESTURE = 0x800,
+ SDL_DOLLARRECORD,
+ SDL_MULTIGESTURE,
+
+ /* Clipboard events */
+ SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */
+
+ /* Drag and drop events */
+ SDL_DROPFILE = 0x1000, /**< The system requests a file open */
+
+ /* Render events */
+ SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset */
+
+ /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
+ * and should be allocated with SDL_RegisterEvents()
+ */
+ SDL_USEREVENT = 0x8000,
+
+ /**
+ * This last event is only for bounding internal arrays
+ */
+ SDL_LASTEVENT = 0xFFFF
+ }
+}
diff --git a/Script/AtomicNET/AtomicNET/Graphics/Graphics.cs b/Script/AtomicNET/AtomicNET/Graphics/Graphics.cs
index 96bec0e9c9..c914812d67 100644
--- a/Script/AtomicNET/AtomicNET/Graphics/Graphics.cs
+++ b/Script/AtomicNET/AtomicNET/Graphics/Graphics.cs
@@ -8,6 +8,14 @@ namespace AtomicEngine
public partial class Graphics : AObject
{
+ [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr csi_Atomic_Graphics_GetSDLWindow();
+
+ ///
+ /// Pointer to SDL window
+ ///
+ public IntPtr SDLWindow => csi_Atomic_Graphics_GetSDLWindow();
+
// Shader Parameters
public void SetShaderParameter(string param, Matrix3x4 matrix)
diff --git a/Script/AtomicNET/AtomicNETProject.json b/Script/AtomicNET/AtomicNETProject.json
index b01354877d..c6766492cf 100644
--- a/Script/AtomicNET/AtomicNETProject.json
+++ b/Script/AtomicNET/AtomicNETProject.json
@@ -101,6 +101,32 @@
"$ATOMIC_ROOT$/Script/AtomicNET/Platform/Android/"
]
},
+ {
+ "name": "AtomicNET.iOS",
+ "platforms" : ["ios"],
+ "outputType" : "Library",
+ "projectTypeGuids" :[ "8FFB629D-F513-41CE-95D2-7ECE97B6EEEC", "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC" ],
+ "defineConstants" : ["ATOMIC_IOS"],
+ "rootNamespace" : "AtomicGameEngine",
+ "assemblyName" : "AtomicNET",
+ "assemblyOutputPath" : "..\\..\\$ATOMIC_CONFIG$\\iOS\\",
+ "projectGuid" : "C74AB5E8-7517-11E6-AE3F-005056C00008",
+ "objcBindingApiDefinition" : "$ATOMIC_ROOT$/Script/AtomicNET/Platform/iOS/ApiDefinition/ApiDefinition.cs",
+ "references" : [
+ "Xamarin.iOS",
+ "System",
+ "System.Core",
+ "System.Xml.Linq",
+ "System.Xml"
+ ],
+ "sharedReferences" : [
+ "AtomicNET.Shared"
+ ],
+ "sources" : [
+ "$ATOMIC_ROOT$/Script/AtomicNET/Platform/iOS/AtomicNET"
+ ],
+ "importProjects" : ["$(MSBuildExtensionsPath)\\Xamarin\\iOS\\Xamarin.iOS.ObjCBinding.CSharp.targets"]
+ },
{
"name": "AtomicNETService",
"platforms" : ["desktop"],
diff --git a/Script/AtomicNET/AtomicNETService/Program.cs b/Script/AtomicNET/AtomicNETService/Program.cs
index 7f97045a22..76202dbe78 100644
--- a/Script/AtomicNET/AtomicNETService/Program.cs
+++ b/Script/AtomicNET/AtomicNETService/Program.cs
@@ -1,11 +1,6 @@
using System;
using AtomicEngine;
-// net genproject C:\Dev\atomic\AtomicGameEngine\Script\AtomicNET\AtomicNETProject.json WINDOWS
-// net parse C:\Dev\atomic\AtomicGameEngine\Artifacts\AtomicNET\Build\AtomicNETService\bin\Debug\AtomicNETService.exe
-// net compile C:\Dev\atomic\AtomicGameEngine\Artifacts\AtomicNET\Build\AtomicNET.sln
-
-
namespace AtomicTools
{
@@ -68,5 +63,3 @@ public static void Main(string[] args)
}
}
}
-
-
diff --git a/Script/AtomicNET/AtomicProject.json b/Script/AtomicNET/AtomicProject.json
index 89f74a1a77..34e67592e1 100644
--- a/Script/AtomicNET/AtomicProject.json
+++ b/Script/AtomicNET/AtomicProject.json
@@ -84,6 +84,37 @@
"$ATOMIC_ROOT$/Script/AtomicNET/AtomicPlayer/AtomicPlayer.Common",
"$ATOMIC_PROJECT_ROOT$/Project/AtomicNET/Platforms/Android"
]
+ },
+ {
+ "name": "$ATOMIC_PROJECT_NAME$.iOS",
+ "platforms" : ["ios"],
+ "outputType" : "Exe",
+ "defineConstants" : ["ATOMIC_IOS"],
+ "rootNamespace" : "",
+ "assemblyName" : "$ATOMIC_PROJECT_NAME$",
+ "projectGuid" : "071BD84E-7518-11E6-C78E-005056C00008",
+ "projectTypeGuids" : ["FEACFBD2-3405-455C-9665-78FE426C6842", "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"],
+ "assemblyOutputPath" : "$ATOMIC_PROJECT_ROOT$\\AtomicNET\\$ATOMIC_CONFIG$\\Bin\\iOS",
+ "playerApplication" : true,
+ "codesignEntitlements" : "$ATOMIC_PROJECT_ROOT$/Project/AtomicNET/Platforms/iOS/Entitlements.plist",
+ "infoPList" : "$ATOMIC_PROJECT_ROOT$/Project/AtomicNET/Platforms/iOS/Info.plist",
+ "references" : [
+ "Xamarin.iOS",
+ "System",
+ "System.Core",
+ "System.Xml.Linq",
+ "System.Xml",
+ "AtomicNET.iOS"
+ ],
+ "sharedReferences" : [
+ "$ATOMIC_PROJECT_NAME$.Shared"
+ ],
+ "sources" : [
+ "$ATOMIC_ROOT$/Script/AtomicNET/AtomicPlayer/AtomicPlayer.Common",
+ "$ATOMIC_PROJECT_ROOT$/Project/AtomicNET/Platforms/iOS"
+ ],
+ "importProjects" : ["$(MSBuildExtensionsPath)\\Xamarin\\iOS\\Xamarin.iOS.CSharp.targets"]
}
+
]
}
diff --git a/Script/AtomicNET/Platform/iOS/ApiDefinition/ApiDefinition.cs b/Script/AtomicNET/Platform/iOS/ApiDefinition/ApiDefinition.cs
new file mode 100644
index 0000000000..4135e81f41
--- /dev/null
+++ b/Script/AtomicNET/Platform/iOS/ApiDefinition/ApiDefinition.cs
@@ -0,0 +1,10 @@
+using System;
+
+using UIKit;
+using Foundation;
+using ObjCRuntime;
+using CoreGraphics;
+
+namespace AtomicGameEngine
+{
+}
diff --git a/Script/AtomicNET/Platform/iOS/AtomicNET/AtomicNETNative.framework.linkwith.cs b/Script/AtomicNET/Platform/iOS/AtomicNET/AtomicNETNative.framework.linkwith.cs
new file mode 100644
index 0000000000..21a1889fe9
--- /dev/null
+++ b/Script/AtomicNET/Platform/iOS/AtomicNET/AtomicNETNative.framework.linkwith.cs
@@ -0,0 +1,3 @@
+using ObjCRuntime;
+
+[assembly: LinkWith ("AtomicNETNative.framework")]
diff --git a/Source/AtomicNET/NETNative/CMakeLists.txt b/Source/AtomicNET/NETNative/CMakeLists.txt
index 0455024fe7..44fbcc2c08 100644
--- a/Source/AtomicNET/NETNative/CMakeLists.txt
+++ b/Source/AtomicNET/NETNative/CMakeLists.txt
@@ -5,6 +5,12 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/Source/ThirdParty/FreeType/include
${CMAKE_SOURCE_DIR}/Source/ThirdParty/Box2D)
+# TODO: Look into the application-extension flag for iOS
+#if (IOS)
+# set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fapplication-extension")
+# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fapplication-extension")
+#endif()
+
set (CSATOMICDIR "${CMAKE_SOURCE_DIR}/Artifacts/Build/Source/Generated/CSharp/Packages/")
file (GLOB CSHARP_BINDINGS_SOURCE ${CSATOMICDIR}/Atomic/Native/*.cpp ${CSATOMICDIR}/Atomic/Native/*.h
@@ -44,6 +50,18 @@ if (APPLE)
target_link_libraries( AtomicNETNative "-stdlib=libc++ -framework AudioUnit -framework Carbon -framework Cocoa -framework CoreAudio -framework CoreVideo -framework ForceFeedback -framework IOKit -framework OpenGL -framework CoreServices -framework Security")
+ else()
+
+ set_target_properties(AtomicNETNative PROPERTIES
+ FRAMEWORK TRUE
+ MACOSX_FRAMEWORK_IDENTIFIER com.atomicgameengine.atomicnetframework
+ MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_SOURCE_DIR}/Build/CMake/IOS/AtomicNET.framework.plist
+ # PUBLIC_HEADER dynamicFramework.h
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
+ )
+
+ target_link_libraries( AtomicNETNative "-framework AudioToolbox -framework CoreAudio -framework CoreGraphics -framework Foundation -framework OpenGLES -framework QuartzCore -framework UIKit -framework CoreMotion -framework GameController")
+
endif()
endif()
@@ -64,10 +82,21 @@ endif()
set (ATOMICNET_NATIVE_DIR "${CMAKE_SOURCE_DIR}/Artifacts/AtomicNET/$<$:Debug>$<$:Release>/Native/${ATOMICNET_NATIVE_PLATFORM}")
+if (NOT IOS)
+
add_custom_command( TARGET AtomicNETNative POST_BUILD
COMMAND "${CMAKE_COMMAND}" ARGS -E make_directory "\"${ATOMICNET_NATIVE_DIR}\""
COMMAND "${CMAKE_COMMAND}" ARGS -E copy_if_different \"$\" "\"${ATOMICNET_NATIVE_DIR}\"" )
+else()
+
+ # iOS: We need to copy/zip the framework on iOS, the framework must also be code signed and POST_BUILD is triggered before this occurs,
+ # so handled in BuildIOS.js
+ add_custom_command( TARGET AtomicNETNative POST_BUILD
+ COMMAND install_name_tool -id @rpath/AtomicNETNative.framework/AtomicNETNative \"$\")
+
+endif()
+
if (MSVC)
# Copy the D3D shader compiler (for pre-Windows 8)
diff --git a/Source/AtomicNET/NETNative/NETAtomicPlayer.cpp b/Source/AtomicNET/NETNative/NETAtomicPlayer.cpp
index c911c85ca1..4b051acdaf 100644
--- a/Source/AtomicNET/NETNative/NETAtomicPlayer.cpp
+++ b/Source/AtomicNET/NETNative/NETAtomicPlayer.cpp
@@ -38,7 +38,7 @@
#include
#endif
-// Android or iOS: use SDL_main
+// Android: uses SDL_main, defined for IOS only to satifsy linker
#if defined(__ANDROID__) || defined(IOS)
typedef int(*sdl_entry_callback)();
@@ -50,14 +50,16 @@ extern "C" void RegisterSDLEntryCallback(sdl_entry_callback callback)
sdlEntryCallback = callback;
}
-extern "C" int SDL_main(int argc, char** argv);
-int SDL_main(int argc, char** argv)
-{
- Atomic::ParseArguments(argc, argv);
+extern "C" int SDL_main(int argc, char** argv);
+int SDL_main(int argc, char** argv)
+{
+#if defined(__ANDROID__)
+ Atomic::ParseArguments(argc, argv);
if (sdlEntryCallback != 0)
{
return sdlEntryCallback();
}
+#endif
return 0;
}
#endif
@@ -75,7 +77,7 @@ namespace Atomic
{
PlayerApp::Setup();
- engineParameters_["ResourcePaths"] = "AtomicResources";
+ engineParameters_["ResourcePaths"] = "AtomicResources";
}
int NETAtomicPlayer::Initialize()
diff --git a/Source/AtomicNET/NETNative/NETCInterop.cpp b/Source/AtomicNET/NETNative/NETCInterop.cpp
index d3bb25fc92..4b256645c1 100644
--- a/Source/AtomicNET/NETNative/NETCInterop.cpp
+++ b/Source/AtomicNET/NETNative/NETCInterop.cpp
@@ -22,6 +22,11 @@
namespace Atomic
{
+#ifdef ATOMIC_PLATFORM_IOS
+ static const char *sdlResourceDir = 0;
+ static const char *sdlDocumentsDir = 0;
+#endif
+
extern "C"
{
@@ -60,10 +65,16 @@ namespace Atomic
obj->SendEvent(eventType, vmap ? vmap->GetVariantMap() : obj->GetEventDataMap());
}
- ATOMIC_EXPORT_API ClassID csi_Atomic_NETCore_Initialize(NETCoreDelegates* delegates)
+ ATOMIC_EXPORT_API ClassID csi_Atomic_NETCore_Initialize(NETCoreEventDispatchFunction eventDispatch, NETCoreUpdateDispatchFunction updateDispatch)
{
Context* context = new Context();
- NETCore* netCore = new NETCore(context, delegates);
+
+ // NOTE: We don't simply marshal the NETCoreDelegates structure due to iOS "reverse callback" limitation
+ NETCoreDelegates delegates;
+ delegates.eventDispatch = eventDispatch;
+ delegates.updateDispatch = updateDispatch;
+
+ NETCore* netCore = new NETCore(context, &delegates);
context->RegisterSubsystem(netCore);
return netCore;
}
@@ -123,6 +134,20 @@ namespace Atomic
}
+ // Graphics
+
+ ATOMIC_EXPORT_API void* csi_Atomic_Graphics_GetSDLWindow()
+ {
+ if (!NETCore::GetContext())
+ return 0;
+
+ if (!NETCore::GetContext()->GetSubsystem())
+ return 0;
+
+ return NETCore::GetContext()->GetSubsystem()->GetSDLWindow();
+
+ }
+
ATOMIC_EXPORT_API void* csi_Atomic_VertexBuffer_Lock(VertexBuffer* vb , unsigned start, unsigned count, bool discard)
{
if (!vb)
@@ -140,9 +165,35 @@ namespace Atomic
graphics->SetShaderParameter(param, *matrix);
}
+#ifdef ATOMIC_PLATFORM_IOS
+ ATOMIC_EXPORT_API void SDL_IOS_Init(const char *resourceDir, const char *documentsDir)
+ {
+ sdlResourceDir = resourceDir;
+ sdlDocumentsDir = documentsDir;
+ }
+#endif
+
}
}
+#ifdef ATOMIC_PLATFORM_IOS
+
+//FileSystem.cpp uses these functions as external.
+const char* SDL_IOS_GetResourceDir()
+{
+ return Atomic::sdlResourceDir;
+}
+
+const char* SDL_IOS_GetDocumentsDir()
+{
+ return Atomic::sdlDocumentsDir;
+}
+
+#endif
+
+
+
+
diff --git a/Source/AtomicPlayer/Application/CMakeLists.txt b/Source/AtomicPlayer/Application/CMakeLists.txt
index 23a4695831..66f2bbad29 100644
--- a/Source/AtomicPlayer/Application/CMakeLists.txt
+++ b/Source/AtomicPlayer/Application/CMakeLists.txt
@@ -55,7 +55,7 @@ if (APPLE)
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
XCODE_ATTRIBUTE_INFOPLIST_PREPROCESS YES
- XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET 9.2
+ XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET 9.3
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2" # iPhone/iPad
XCODE_ATTRIBUTE_COMBINE_HIDPI_IMAGES NO
)
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index fb6f821339..2d0b246a37 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -12,7 +12,7 @@ endif()
add_subdirectory(AtomicPlayer)
add_subdirectory(AtomicPlayerJS)
-if (NOT IOS AND NOT EMSCRIPTEN)
+if (NOT EMSCRIPTEN)
add_subdirectory(AtomicApp)
add_subdirectory(AtomicNET)
endif()
diff --git a/Source/ToolCore/Command/NETCmd.cpp b/Source/ToolCore/Command/NETCmd.cpp
index c8d3686ab0..b16d23c906 100644
--- a/Source/ToolCore/Command/NETCmd.cpp
+++ b/Source/ToolCore/Command/NETCmd.cpp
@@ -67,11 +67,34 @@ bool NETCmd::Parse(const Vector& arguments, unsigned startIndex, String&
return false;
}
+ if (command_ == "compile" || command_ == "genresources")
+ {
+ for (unsigned i = startIndex + 3; i < arguments.Size(); i++)
+ {
+ if (arguments[i].Length() > 1 && arguments[i][0] == '-')
+ {
+ String argument = arguments[i].Substring(1).ToLower();
+ String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;
+
+ if (argument == "platform" && !value.Empty())
+ {
+ platforms_.Push(value);
+ i++;
+ }
+ else if (argument == "config" && !value.Empty())
+ {
+ configurations_.Push(value);
+ i++;
+ }
+ }
+ }
+ }
+
if (command_ == "compile")
{
+ // solution
solutionPath_ = startIndex + 2 < arguments.Size() ? arguments[startIndex + 2] : String::EMPTY;
- platform_ = startIndex + 3 < arguments.Size() ? arguments[startIndex + 3] : String::EMPTY;
- configuration_ = startIndex + 4 < arguments.Size() ? arguments[startIndex + 4] : "Release";
+
bool exists = false;
@@ -87,19 +110,32 @@ bool NETCmd::Parse(const Vector& arguments, unsigned startIndex, String&
return false;
}
- if (!platform_.Length())
+ if (!platforms_.Size())
{
errorMsg = "Platform not specified";
return false;
}
+ if (!configurations_.Size())
+ {
+ errorMsg = "configuration not specified";
+ return false;
+ }
+
+
return true;
}
else if (command_ == "genresources")
{
projectPath_ = startIndex + 2 < arguments.Size() ? arguments[startIndex + 2] : String::EMPTY;
- platform_ = startIndex + 3 < arguments.Size() ? arguments[startIndex + 3] : String::EMPTY;
requiresProjectLoad_ = true;
+
+ if (!platforms_.Size())
+ {
+ errorMsg = "Platform not specified";
+ return false;
+ }
+
}
else
{
@@ -136,8 +172,6 @@ void NETCmd::Run()
if (command_ == "compile")
{
- FileSystem* fileSystem = GetSubsystem();
-
NETBuildSystem* buildSystem = new NETBuildSystem(context_);
context_->RegisterSubsystem(buildSystem);
@@ -173,7 +207,7 @@ void NETCmd::Run()
}
// json project file
- build = buildSystem->Build(solutionPath_, platform_, configuration_);
+ build = buildSystem->Build(solutionPath_, platforms_, configurations_);
if (!build)
{
@@ -200,11 +234,11 @@ void NETCmd::Run()
buildSystem->SetBuildPath(project->GetProjectPath() + "AtomicNET/Resources/");
- Platform* platform = toolSystem->GetPlatformByName(platform_);
+ Platform* platform = toolSystem->GetPlatformByName(platforms_[0]);
if (!platform)
{
- Error(ToString("Unknown platform %s", platform_.CString()));
+ Error(ToString("Unknown platform %s", platforms_[0].CString()));
Finished();
return;
}
diff --git a/Source/ToolCore/Command/NETCmd.h b/Source/ToolCore/Command/NETCmd.h
index 0bf8e6abc6..0821a756db 100644
--- a/Source/ToolCore/Command/NETCmd.h
+++ b/Source/ToolCore/Command/NETCmd.h
@@ -64,8 +64,8 @@ class NETCmd: public Command
// compile
String solutionPath_;
- String platform_;
- String configuration_;
+ StringVector platforms_;
+ StringVector configurations_;
bool requiresProjectLoad_;
diff --git a/Source/ToolCore/NETTools/NETBuildSystem.cpp b/Source/ToolCore/NETTools/NETBuildSystem.cpp
index 207efa2451..4d207a285c 100644
--- a/Source/ToolCore/NETTools/NETBuildSystem.cpp
+++ b/Source/ToolCore/NETTools/NETBuildSystem.cpp
@@ -41,14 +41,23 @@
namespace ToolCore
{
- NETBuild::NETBuild(Context* context, const String& solutionPath, const String& platform, const String& configuration) :
+ NETBuild::NETBuild(Context* context, const String& solutionPath, const StringVector& platforms, const StringVector& configurations) :
Object(context),
solutionPath_(solutionPath),
- platform_(platform),
- configuration_(configuration),
status_(NETBUILD_PENDING)
{
+ for (unsigned i = 0; i < platforms.Size() ; i++)
+ {
+ platforms_.Push(platforms[i].ToLower());
+ }
+ for (unsigned i = 0; i < configurations.Size() ; i++)
+ {
+ String config = configurations[i];
+ config.Replace("release", "Release");
+ config.Replace("debug", "Debug");
+ configurations_.Push(config);
+ }
}
NETBuildSystem::NETBuildSystem(Context* context) :
@@ -187,15 +196,8 @@ namespace ToolCore
{
SharedPtr gen(new NETProjectGen(context_));
- StringVector platforms;
- platforms.Push("desktop");
-
- if (curBuild_->platform_.ToLower() == "android")
- {
- platforms.Push("android");
- }
-
- gen->SetSupportedPlatforms(platforms);
+ gen->SetSupportedPlatforms(curBuild_->platforms_);
+ gen->SetRewriteSolution(true);
if (!gen->LoadJSONProject(solutionPath))
{
@@ -229,7 +231,53 @@ namespace ToolCore
return;
}
- const String configuration = curBuild_->configuration_;
+ StringVector stringVector;
+ String platforms;
+ String configs;
+
+ for (unsigned i = 0; i < curBuild_->configurations_.Size(); i++)
+ {
+ stringVector.Push(ToString("/p:Configuration=%s", curBuild_->configurations_[i].CString()));
+ }
+
+ configs = String::Joined(stringVector, " ");
+ stringVector.Clear();
+
+ for (unsigned i = 0; i < curBuild_->platforms_.Size(); i++)
+ {
+ // map platform
+ String platform = curBuild_->platforms_[i];
+
+ if (platform == "desktop" || platform == "android")
+ {
+ platform = "\"Any CPU\"";
+ }
+ else if (platform == "ios")
+ {
+
+ platform = "\"Any CPU\"";
+ // TODO
+ // platform = "iPhone";
+ }
+ else
+ {
+ ATOMIC_LOGERRORF("Unknown platform: %s, skipping", platform.CString());
+ continue;
+ }
+
+ platform = ToString("/p:Platform=%s", platform.CString());
+
+ if (stringVector.Contains(platform))
+ {
+ // This can happen when specifying Desktop + Android for example
+ continue;
+ }
+
+ stringVector.Push(platform);
+ }
+
+ platforms = String::Joined(stringVector, " ");
+ stringVector.Clear();
Vector args;
@@ -258,7 +306,7 @@ namespace ToolCore
compile += ToString("&& \"%s\" restore \"%s\" ", nugetBinary.CString(), solutionPath.CString());
}
- compile += ToString("&& msbuild \"%s\" /p:Configuration=%s /p:Platform=\"Any CPU\"\"", solutionPath.CString(), configuration.CString());
+ compile += ToString("&& msbuild \"%s\" %s %s\"", solutionPath.CString(), platforms.CString(), configs.CString());
args.Push(compile);
@@ -280,7 +328,7 @@ namespace ToolCore
#endif
}
- compile += ToString("\"%s\" \"%s\" /p:Configuration=%s /p:Platform=\"Any CPU\"", xbuildBinary.CString(), solutionPath.CString(), configuration.CString());
+ compile += ToString("\"%s\" \"%s\" %s %s", xbuildBinary.CString(), solutionPath.CString(), platforms.CString(), configs.CString());
args.Push(compile);
@@ -291,6 +339,8 @@ namespace ToolCore
SubprocessSystem* subs = GetSubsystem();
Subprocess* subprocess = nullptr;
+ ATOMIC_LOGINFOF("%s : %s", cmd.CString(), curBuild_->allArgs_.CString());
+
try
{
subprocess = subs->Launch(cmd, args, "");
@@ -316,7 +366,7 @@ namespace ToolCore
}
- NETBuild* NETBuildSystem::GetBuild(const String& solutionPath, const String& platform, const String& configuration)
+ NETBuild* NETBuildSystem::GetBuild(const String& solutionPath, const StringVector& platforms, const StringVector& configurations)
{
List>::ConstIterator itr = builds_.Begin();
@@ -324,7 +374,7 @@ namespace ToolCore
{
NETBuild* build = *itr;
- if (build->solutionPath_ == solutionPath && build->platform_ == platform && build->configuration_ == configuration)
+ if (build->solutionPath_ == solutionPath && build->platforms_ == platforms && build->configurations_ == configurations)
return build;
itr++;
@@ -336,26 +386,20 @@ namespace ToolCore
NETBuild* NETBuildSystem::BuildAtomicProject(Project* project)
{
- String platform;
- String configuration;
+ StringVector platforms;
+ StringVector configurations;
-#ifdef ATOMIC_PLATFORM_WINDOWS
- platform = "WINDOWS";
-#elif ATOMIC_PLATFORM_OSX
- platform = "MACOSX";
-#else
- platform = "LINUX";
-#endif
+ platforms.Push("desktop");
#ifdef ATOMIC_DEBUG
- configuration = "Debug";
+ configurations.Push("Debug");
#else
- configuration = "Release";
+ configurations.Push("Release");
#endif
String solutionPath = project->GetProjectPath() + "AtomicNET/Solution/" + project->GetProjectSettings()->GetName() + ".sln";
- NETBuild* build = Build(solutionPath, platform, configuration);
+ NETBuild* build = Build(solutionPath, platforms, configurations);
if (build)
{
@@ -385,7 +429,7 @@ namespace ToolCore
}
- NETBuild* NETBuildSystem::Build(const String& solutionPath, const String& platform, const String& configuration)
+ NETBuild* NETBuildSystem::Build(const String& solutionPath, const StringVector& platforms, const StringVector& configurations)
{
FileSystem* fileSystem = GetSubsystem();
@@ -397,13 +441,13 @@ namespace ToolCore
}
// Get existing build
- SharedPtr build(GetBuild(solutionPath, platform, configuration));
+ SharedPtr build(GetBuild(solutionPath, platforms, configurations));
if (build.NotNull())
return build;
// Create a new build
- build = new NETBuild(context_, solutionPath, platform, configuration);
+ build = new NETBuild(context_, solutionPath, platforms, configurations);
builds_.Push(build);
diff --git a/Source/ToolCore/NETTools/NETBuildSystem.h b/Source/ToolCore/NETTools/NETBuildSystem.h
index ddbb942dfb..b58cd0f997 100644
--- a/Source/ToolCore/NETTools/NETBuildSystem.h
+++ b/Source/ToolCore/NETTools/NETBuildSystem.h
@@ -58,14 +58,15 @@ namespace ToolCore
public:
- NETBuild(Context* context, const String& solutionPath, const String& platform, const String& configuration);
+ NETBuild(Context* context, const String& solutionPath, const StringVector& platforms, const StringVector& configurations);
virtual ~NETBuild() {}
private:
/// .sln or .json configuration file
String solutionPath_;
- String configuration_;
- String platform_;
+ StringVector configurations_;
+ StringVector platforms_;
+
NETBuildStatus status_;
String allArgs_;
String output_;
@@ -85,7 +86,7 @@ namespace ToolCore
virtual ~NETBuildSystem();
/// Build either a .sln or .json configuration file
- NETBuild* Build(const String& solutionPath, const String& platform, const String& configuration = "Release");
+ NETBuild* Build(const String& solutionPath, const StringVector &platforms, const StringVector &configurations);
NETBuild* BuildAtomicProject(Project* project);
@@ -93,7 +94,7 @@ namespace ToolCore
void CurrentBuildError(String errorText);
- NETBuild* GetBuild(const String& solutionPath, const String& platform, const String& configuration);
+ NETBuild* GetBuild(const String& solutionPath, const StringVector& platforms, const StringVector& configurations);
void HandleBuildAtomicProject(StringHash eventType, VariantMap& eventData);
void HandleToolUpdate(StringHash eventType, VariantMap& eventData);
diff --git a/Source/ToolCore/NETTools/NETProjectGen.cpp b/Source/ToolCore/NETTools/NETProjectGen.cpp
index e2cd26f292..4ea34d6edc 100644
--- a/Source/ToolCore/NETTools/NETProjectGen.cpp
+++ b/Source/ToolCore/NETTools/NETProjectGen.cpp
@@ -237,6 +237,12 @@ namespace ToolCore
platform = "Android";
}
+ else if (SupportsPlatform("ios"))
+ {
+ ref = "AtomicNET";
+ platform = "iOS";
+ }
+
if (platform.Length())
{
@@ -374,10 +380,23 @@ namespace ToolCore
paths.Join(searchPaths, ";");
}
+ void NETCSProject::ProcessDefineConstants(StringVector& constants)
+ {
+ const Vector& globalConstants = projectGen_->GetGlobalDefineConstants();
+ constants += globalConstants;
+
+ if (constants.Contains("ATOMIC_IOS") || constants.Contains("ATOMIC_ANDROID"))
+ constants.Push("ATOMIC_MOBILE");
+ }
+
void NETCSProject::CreateReleasePropertyGroup(XMLElement &projectRoot)
{
XMLElement pgroup = projectRoot.CreateChild("PropertyGroup");
- pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ");
+
+ if (playerApplication_ && SupportsPlatform("ios"))
+ pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Release|iPhone' ");
+ else
+ pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ");
pgroup.CreateChild("Optimize").SetValue("true");
@@ -391,8 +410,7 @@ namespace ToolCore
constants += defineConstants_;
- const Vector& globalConstants = projectGen_->GetGlobalDefineConstants();
- constants += globalConstants;
+ ProcessDefineConstants(constants);
pgroup.CreateChild("DefineConstants").SetValue(String::Joined(constants, ";").CString());
pgroup.CreateChild("ErrorReport").SetValue("prompt");
@@ -429,16 +447,27 @@ namespace ToolCore
}
else
{
- pgroup.CreateChild("DebugType").SetValue("pdbonly");
-
if (SupportsPlatform("android"))
{
+ pgroup.CreateChild("DebugType").SetValue("pdbonly");
+
if (outputType_.ToLower() != "library")
{
pgroup.CreateChild("AndroidUseSharedRuntime").SetValue("False");
pgroup.CreateChild("AndroidLinkMode").SetValue("SdkOnly");
}
}
+ else if (playerApplication_ && SupportsPlatform("ios"))
+ {
+ pgroup.CreateChild("DebugType").SetValue("none");
+
+ pgroup.CreateChild("MtouchArch").SetValue("ARMv7, ARM64");
+ pgroup.CreateChild("CodesignEntitlements").SetValue(GetSanitizedPath(codesignEntitlements_));
+ pgroup.CreateChild("CodesignKey").SetValue("iPhone Developer");
+ pgroup.CreateChild("MtouchDebug").SetValue("true");
+ pgroup.CreateChild("MtouchOptimizePNGs").SetValue("False");
+ }
+
}
}
@@ -446,7 +475,12 @@ namespace ToolCore
void NETCSProject::CreateDebugPropertyGroup(XMLElement &projectRoot)
{
XMLElement pgroup = projectRoot.CreateChild("PropertyGroup");
- pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ");
+
+ if (playerApplication_ && SupportsPlatform("ios"))
+ pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Debug|iPhone' ");
+ else
+ pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ");
+
pgroup.CreateChild("Optimize").SetValue("false");
@@ -460,9 +494,7 @@ namespace ToolCore
constants.Push("TRACE");
constants += defineConstants_;
-
- const Vector& globalConstants = projectGen_->GetGlobalDefineConstants();
- constants += globalConstants;
+ ProcessDefineConstants(constants);
pgroup.CreateChild("DefineConstants").SetValue(String::Joined(constants, ";").CString());
@@ -516,6 +548,17 @@ namespace ToolCore
pgroup.CreateChild("AndroidEnableMultiDex").SetValue("False");
pgroup.CreateChild("AndroidSupportedAbis").SetValue("armeabi-v7a");
}
+ else if (playerApplication_ && SupportsPlatform("ios"))
+ {
+ pgroup.CreateChild("MtouchArch").SetValue("ARMv7, ARM64");
+ pgroup.CreateChild("CodesignEntitlements").SetValue(GetSanitizedPath(codesignEntitlements_));
+ pgroup.CreateChild("CodesignKey").SetValue("iPhone Developer");
+ pgroup.CreateChild("MtouchDebug").SetValue("true");
+ pgroup.CreateChild("MtouchFastDev").SetValue("true");
+ pgroup.CreateChild("IpaPackageName").SetValue("");
+ pgroup.CreateChild("OptimizePNGs").SetValue("false");
+ pgroup.CreateChild("MtouchOptimizePNGs").SetValue("False");
+ }
}
@@ -570,17 +613,69 @@ namespace ToolCore
}
else
{
- const String& projectPath = projectGen_->GetAtomicProjectPath();
+ const String& projectPath = projectGen_->GetAtomicProjectPath();
if (!playerApplication_ || !projectPath.Length())
return;
- XMLElement androidAsset = itemGroup.CreateChild("AndroidAsset");
- androidAsset.SetAttribute("Include", projectPath + "AtomicNET/Resources/AtomicResources.pak");
- androidAsset.CreateChild("Link").SetValue("Assets\\AtomicResources.pak");
+ if (androidApplication_)
+ {
+ XMLElement androidAsset = itemGroup.CreateChild("AndroidAsset");
+ androidAsset.SetAttribute("Include", projectPath + "AtomicNET/Resources/AtomicResources.pak");
+ androidAsset.CreateChild("Link").SetValue("Assets\\AtomicResources.pak");
+ }
+ else
+ {
+ XMLElement bundleResource = itemGroup.CreateChild("BundleResource");
+ bundleResource.SetAttribute("Include", projectPath + "AtomicNET/Resources/AtomicResources.pak");
+ bundleResource.CreateChild("Link").SetValue("Resources\\AtomicResources.pak");
+ bundleResource.CreateChild("CopyToOutputDirectory").SetValue("PreserveNewest");
+ }
}
}
+ void NETCSProject::CreateIOSItems(XMLElement &projectRoot)
+ {
+ XMLElement iosGroup = projectRoot.CreateChild("ItemGroup");
+
+ if (objcBindingApiDefinition_.Length())
+ {
+ iosGroup.CreateChild("ObjcBindingApiDefinition").SetAttribute("Include", GetSanitizedPath(objcBindingApiDefinition_));
+ }
+
+ if (name_ == "AtomicNET.iOS")
+ {
+ ToolEnvironment* tenv = GetSubsystem();
+
+#ifdef ATOMIC_DEBUG
+ String config = "Debug";
+#else
+ String config = "Release";
+#endif
+
+ String nativePath = AddTrailingSlash(tenv->GetAtomicNETRootDir()) + config + "/Native/iOS/AtomicNETNative.framework";
+ iosGroup.CreateChild("ObjcBindingNativeFramework").SetAttribute("Include", GetSanitizedPath(nativePath));
+
+ // framework copy
+ XMLElement none = iosGroup.CreateChild("None");
+ none.SetAttribute("Include", nativePath + ".zip");
+ none.CreateChild("Link").SetValue("AtomicNETNative.framework.zip");
+ none.CreateChild("CopyToOutputDirectory").SetValue("Always");
+
+ }
+ else if (playerApplication_)
+ {
+ XMLElement plist = iosGroup.CreateChild("None");
+ plist.SetAttribute("Include", GetSanitizedPath(infoPList_));
+ plist.CreateChild("Link").SetValue("Info.plist");
+
+ XMLElement entitlements = iosGroup.CreateChild("Content");
+ entitlements.SetAttribute("Include", GetSanitizedPath(codesignEntitlements_));
+ entitlements.CreateChild("Link").SetValue("Entitlements.plist");
+ }
+
+ }
+
void NETCSProject::CreateAndroidItems(XMLElement &projectRoot)
{
@@ -729,8 +824,11 @@ namespace ToolCore
// Platform
XMLElement platform = pgroup.CreateChild("Platform");
- platform.SetAttribute("Condition", " '$(Platform)' == '' ");
- platform.SetValue("AnyCPU");
+ platform.SetAttribute("Condition", " '$(Platform)' == '' ");
+ if (playerApplication_ && SupportsPlatform("ios"))
+ platform.SetValue("iPhone");
+ else
+ platform.SetValue("AnyCPU");
// ProjectGuid
XMLElement guid = pgroup.CreateChild("ProjectGuid");
@@ -766,7 +864,14 @@ namespace ToolCore
pgroup.CreateChild("ProductVersion").SetValue("8.0.30703");
pgroup.CreateChild("SchemaVersion").SetValue("2.0");
- pgroup.CreateChild("TargetFrameworkVersion").SetValue("v6.0");
+ if (SupportsPlatform("ios"))
+ {
+ pgroup.CreateChild("IPhoneResourcePrefix").SetValue("Resources");
+ }
+ else
+ {
+ pgroup.CreateChild("TargetFrameworkVersion").SetValue("v6.0");
+ }
if (SupportsPlatform("android"))
{
@@ -945,6 +1050,12 @@ namespace ToolCore
CreateAndroidItems(project);
}
+ if (SupportsPlatform("ios"))
+ {
+ CreateIOSItems(project);
+ }
+
+
if (SupportsDesktop() && !GetIsPCL())
project.CreateChild("Import").SetAttribute("Project", "$(MSBuildToolsPath)\\Microsoft.CSharp.targets");
@@ -1213,6 +1324,16 @@ namespace ToolCore
targetFrameworkProfile_ = root["targetFrameworkProfile"].GetString();
+ // iOS
+ objcBindingApiDefinition_ = root["objcBindingApiDefinition"].GetString();
+ ReplacePathStrings(objcBindingApiDefinition_);
+
+ codesignEntitlements_ = root["codesignEntitlements"].GetString();
+ ReplacePathStrings(codesignEntitlements_);
+
+ infoPList_ = root["infoPList"].GetString();
+ ReplacePathStrings(infoPList_);
+
return true;
}
@@ -1327,7 +1448,9 @@ namespace ToolCore
source += " GlobalSection(SolutionConfigurationPlatforms) = preSolution\n";
source += " Debug|Any CPU = Debug|Any CPU\n";
- source += " Release|Any CPU = Release|Any CPU\n";
+ source += " Release|Any CPU = Release|Any CPU\n";
+ source += " Debug|iPhone = Debug|iPhone\n";
+ source += " Release|iPhone = Release|iPhone\n";
source += " EndGlobalSection\n";
source += " GlobalSection(ProjectConfigurationPlatforms) = postSolution\n";
@@ -1338,10 +1461,22 @@ namespace ToolCore
if (p->outputType_ == "Shared")
continue;
- source += ToString(" {%s}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n", p->GetProjectGUID().CString());
- source += ToString(" {%s}.Debug|Any CPU.Build.0 = Debug|Any CPU\n", p->GetProjectGUID().CString());
- source += ToString(" {%s}.Release|Any CPU.ActiveCfg = Release|Any CPU\n", p->GetProjectGUID().CString());
- source += ToString(" {%s}.Release|Any CPU.Build.0 = Release|Any CPU\n", p->GetProjectGUID().CString());
+ String cpu = "Any CPU";
+ if (p->GetIsPlayerApp() && p->SupportsPlatform("ios"))
+ cpu = "iPhone";
+
+ source += ToString(" {%s}.Debug|%s.ActiveCfg = Debug|%s\n", p->GetProjectGUID().CString(), cpu.CString(), cpu.CString());
+ source += ToString(" {%s}.Debug|%s.Build.0 = Debug|%s\n", p->GetProjectGUID().CString(), cpu.CString(), cpu.CString());
+ source += ToString(" {%s}.Release|%s.ActiveCfg = Release|%s\n", p->GetProjectGUID().CString(), cpu.CString(), cpu.CString());
+ source += ToString(" {%s}.Release|%s.Build.0 = Release|%s\n", p->GetProjectGUID().CString(), cpu.CString(), cpu.CString());
+
+ if (cpu != "iPhone" && (p->SupportsPlatform("ios", false)))
+ {
+ source += ToString(" {%s}.Debug|iPhone.ActiveCfg = Debug|Any CPU\n", p->GetProjectGUID().CString());
+ source += ToString(" {%s}.Debug|iPhone.Build.0 = Debug|Any CPU\n", p->GetProjectGUID().CString());
+ source += ToString(" {%s}.Release|iPhone.ActiveCfg = Release|Any CPU\n", p->GetProjectGUID().CString());
+ source += ToString(" {%s}.Release|iPhone.Build.0 = Release|Any CPU\n", p->GetProjectGUID().CString());
+ }
}
source += " EndGlobalSection\n";
@@ -1563,7 +1698,6 @@ namespace ToolCore
bool NETProjectGen::LoadAtomicProject(const String& atomicProjectPath)
{
- FileSystem* fileSystem = GetSubsystem();
ToolEnvironment* tenv = GetSubsystem();
ToolSystem* tsystem = GetSubsystem();
@@ -1589,7 +1723,7 @@ namespace ToolCore
{
// Nope, load them up
projectSettings_ = SharedPtr(new ProjectSettings(context_));
- projectSettings_->Load(atomicProjectPath_ + "Settings/Platforms.json");
+ projectSettings_->Load(atomicProjectPath_ + "Settings/Project.json");
}
#ifdef ATOMIC_DEV_BUILD
diff --git a/Source/ToolCore/NETTools/NETProjectGen.h b/Source/ToolCore/NETTools/NETProjectGen.h
index 7c8d5a81da..13c468afd5 100644
--- a/Source/ToolCore/NETTools/NETProjectGen.h
+++ b/Source/ToolCore/NETTools/NETProjectGen.h
@@ -76,6 +76,10 @@ namespace ToolCore
bool GetIsPCL() const { return projectTypeGuids_.Contains("{786C830F-07A1-408B-BD7F-6EE04809D6DB}"); }
+ bool GetIsPlayerApp() const { return playerApplication_; }
+ bool SupportsDesktop() const;
+ bool SupportsPlatform(const String& platform, bool explicitCheck = true) const;
+
bool Generate();
private:
@@ -99,12 +103,13 @@ namespace ToolCore
void CreateApplicationItems(XMLElement &projectRoot);
void CreateAndroidItems(XMLElement &projectRoot);
+ void CreateIOSItems(XMLElement &projectRoot);
void CreateAssemblyInfo();
void GetAssemblySearchPaths(String& paths);
- bool SupportsDesktop() const;
- bool SupportsPlatform(const String& platform, bool explicitCheck = true) const;
+ void ProcessDefineConstants(StringVector& constants);
+
String name_;
String projectGuid_;
@@ -138,6 +143,12 @@ namespace ToolCore
// Android
bool androidApplication_;
+
+ // iOS
+ String objcBindingApiDefinition_;
+ String codesignEntitlements_;
+ String infoPList_;
+
};
diff --git a/Source/ToolCore/Project/ProjectSettings.cpp b/Source/ToolCore/Project/ProjectSettings.cpp
index 4df083028e..41a71c707b 100644
--- a/Source/ToolCore/Project/ProjectSettings.cpp
+++ b/Source/ToolCore/Project/ProjectSettings.cpp
@@ -89,6 +89,7 @@ namespace ToolCore
if (!fileSystem->FileExists(path))
{
+ ATOMIC_LOGERRORF("No platform settings specified, using default: %s", path.CString());
SetDefault();
return true;
}
@@ -144,7 +145,7 @@ namespace ToolCore
if (!platforms_.Size())
{
- ATOMIC_LOGERRORF("No valif platforms defined in platform settings: %s, using default", path.CString());
+ ATOMIC_LOGERRORF("No valid platforms defined in platform settings: %s, using default", path.CString());
SetDefault();
}