//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
//**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************//
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using bs;
namespace bs.Editor
{
/** @addtogroup Build
* @{
*/
///
/// Contains a list of valid platforms that can be built for.
///
public enum PlatformType // Note: Must match C++ enum PlatformType
{
Windows,
Count // Keep at end
}
///
/// Contains build data for a specific platform.
///
public abstract class PlatformInfo : ScriptObject
{
///
/// Creates a new platform info. For internal runtime use only.
///
protected PlatformInfo()
{ }
///
/// Returns the platform that this object contains data for.
///
public PlatformType Type
{
get { return Internal_GetType(mCachedPtr); }
}
///
/// Initial scene that is loaded when application is first started.
///
public RRef MainScene
{
get { return Internal_GetMainScene(mCachedPtr); }
set
{
IntPtr scenePtr = IntPtr.Zero;
if (value != null)
scenePtr = value.GetCachedPtr();
Internal_SetMainScene(mCachedPtr, scenePtr);
}
}
///
/// Determines should the application be started in fullscreen using the user's desktop resolution.
///
public bool Fullscreen
{
get { return Internal_GetFullscreen(mCachedPtr); }
set { Internal_SetFullscreen(mCachedPtr, value); }
}
///
/// Width of a window if the game is started in windowed mode. This is only relevant if
/// is off.
///
public int WindowedWidth
{
get
{
int width, height;
Internal_GetResolution(mCachedPtr, out width, out height);
return width;
}
set { Internal_SetResolution(mCachedPtr, value, WindowedHeight); }
}
///
/// Height of a window if the game is started in windowed mode. This is only relevant if
/// is off.
///
public int WindowedHeight
{
get
{
int width, height;
Internal_GetResolution(mCachedPtr, out width, out height);
return height;
}
set { Internal_SetResolution(mCachedPtr, WindowedWidth, value); }
}
///
/// Determines should the scripts be output in debug mode (worse performance but better error reporting).
///
public bool Debug
{
get { return Internal_GetDebug(mCachedPtr); }
set { Internal_SetDebug(mCachedPtr, value); }
}
///
/// A set of semicolon separated defines to use when compiling scripts for this platform.
///
public string Defines
{
get { return Internal_GetDefines(mCachedPtr); }
set { Internal_SetDefines(mCachedPtr, value); }
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern PlatformType Internal_GetType(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetDefines(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetDefines(IntPtr thisPtr, string value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern RRef Internal_GetMainScene(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
static extern void Internal_SetMainScene(IntPtr thisPtr, IntPtr prefabPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
static extern bool Internal_GetFullscreen(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
static extern void Internal_SetFullscreen(IntPtr thisPtr, bool fullscreen);
[MethodImpl(MethodImplOptions.InternalCall)]
static extern void Internal_GetResolution(IntPtr thisPtr, out int width, out int height);
[MethodImpl(MethodImplOptions.InternalCall)]
static extern void Internal_SetResolution(IntPtr thisPtr, int width, int height);
[MethodImpl(MethodImplOptions.InternalCall)]
static extern bool Internal_GetDebug(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
static extern void Internal_SetDebug(IntPtr thisPtr, bool fullscreen);
}
///
/// Supported icon sizes for Windows platform.
///
public enum WinIconSizes
{
Icon16 = 16,
Icon32 = 32,
Icon48 = 48,
Icon64 = 64,
Icon96 = 96,
Icon128 = 128,
Icon196 = 196,
Icon256 = 256
}
///
/// Platform data specific to Windows.
///
public class WinPlatformInfo : PlatformInfo
{
///
/// Texture that will be displayed on the application's executable.
///
public RRef Icon
{
get { return Internal_GetIcon(mCachedPtr); }
set
{
IntPtr texturePtr = IntPtr.Zero;
if (value != null)
texturePtr = value.GetCachedPtr();
Internal_SetIcon(mCachedPtr, texturePtr);
}
}
///
/// Text that will be displayed in the application's title bar.
///
public string TitleText
{
get { return Internal_GetTitleText(mCachedPtr); }
set { Internal_SetTitleText(mCachedPtr, value); }
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern RRef Internal_GetIcon(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetIcon(IntPtr thisPtr, IntPtr texturePtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetTitleText(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetTitleText(IntPtr thisPtr, string value);
}
///
/// Handles building of the game executable and packaging of all necessary resources, making the game be ready to ran
/// as a standalone product.
///
public static class BuildManager
{
///
/// Returns a list of all available platforms that can be built for.
///
public static PlatformType[] AvailablePlatforms
{
get { return Internal_GetAvailablePlatforms(); }
}
///
/// Returns the currently active platform.
///
public static PlatformType ActivePlatform
{
get { return Internal_GetActivePlatform(); }
set { Internal_SetActivePlatform(value); }
}
///
/// Returns the data about the currently active platform.
///
public static PlatformInfo ActivePlatformInfo
{
get { return Internal_GetActivePlatformInfo(); }
}
///
/// Returns absolute path to the folder where builds for the currently active platform are output.
///
public static string OutputFolder
{
get { return GetBuildFolder(BuildFolder.DestinationRoot, ActivePlatform); }
}
///
/// Returns a path to a specific folder used in the build process. See entries of BuildFolder enum for explanations
/// of individual folder types.
///
/// Type of folder to retrieve the path for.
/// Platform to retrieve the path for.
/// Path for the requested folder. This can be absolute or relative, see enum
/// for details.
private static string GetBuildFolder(BuildFolder folder, PlatformType platform)
{
return Internal_GetBuildFolder(folder, platform);
}
///
/// Returns a list of names of all native binaries required for a specific platform.
///
/// Platform type for which to get the binaries for.
/// Array of names of native binary files.
private static string[] GetNativeBinaries(PlatformType platform)
{
return Internal_GetNativeBinaries(platform);
}
///
/// Builds the executable and packages the game.
///
public static void Build()
{
PlatformType activePlatform = ActivePlatform;
PlatformInfo platformInfo = ActivePlatformInfo;
string srcRoot = GetBuildFolder(BuildFolder.SourceRoot, activePlatform);
string destRoot = GetBuildFolder(BuildFolder.DestinationRoot, activePlatform);
// Prepare clean destination folder
if(Directory.Exists(destRoot))
Directory.Delete(destRoot, true);
Directory.CreateDirectory(destRoot);
// Compile game assembly
string bansheeAssemblyFolder;
if(platformInfo.Debug)
bansheeAssemblyFolder = GetBuildFolder(BuildFolder.BansheeDebugAssemblies, activePlatform);
else
bansheeAssemblyFolder = GetBuildFolder(BuildFolder.BansheeReleaseAssemblies, activePlatform);
string srcBansheeAssemblyFolder = Path.Combine(srcRoot, bansheeAssemblyFolder);
string destBansheeAssemblyFolder = Path.Combine(destRoot, bansheeAssemblyFolder);
Directory.CreateDirectory(destBansheeAssemblyFolder);
CompilerInstance ci = ScriptCompiler.CompileAsync(ScriptAssemblyType.Game, ActivePlatform, platformInfo.Debug, destBansheeAssemblyFolder);
// Copy engine assembly
{
string srcFile = Path.Combine(srcBansheeAssemblyFolder, EditorApplication.EngineAssemblyName);
string destFile = Path.Combine(destBansheeAssemblyFolder, EditorApplication.EngineAssemblyName);
File.Copy(srcFile, destFile);
}
// Copy builtin data
string dataFolder = GetBuildFolder(BuildFolder.Data, activePlatform);
string srcData = Path.Combine(srcRoot, dataFolder);
string destData = Path.Combine(destRoot, dataFolder);
DirectoryEx.Copy(srcData, destData);
// Copy native binaries
string binaryFolder = GetBuildFolder(BuildFolder.NativeBinaries, activePlatform);
string srcBin = Path.Combine(srcRoot, binaryFolder);
string destBin = destRoot;
string[] nativeBinaries = GetNativeBinaries(activePlatform);
foreach (var entry in nativeBinaries)
{
string srcFile = Path.Combine(srcBin, entry);
string destFile = Path.Combine(destBin, entry);
File.Copy(srcFile, destFile);
}
// Copy .NET framework assemblies
string frameworkAssemblyFolder = GetBuildFolder(BuildFolder.FrameworkAssemblies, activePlatform);
string srcFrameworkAssemblyFolder = Path.Combine(srcRoot, frameworkAssemblyFolder);
string destFrameworkAssemblyFolder = Path.Combine(destRoot, frameworkAssemblyFolder);
Directory.CreateDirectory(destFrameworkAssemblyFolder);
string[] frameworkAssemblies = GetFrameworkAssemblies(activePlatform);
foreach (var entry in frameworkAssemblies)
{
string srcFile = Path.Combine(srcFrameworkAssemblyFolder, entry + ".dll");
string destFile = Path.Combine(destFrameworkAssemblyFolder, entry + ".dll");
File.Copy(srcFile, destFile);
}
// Copy Mono
string monoFolder = GetBuildFolder(BuildFolder.Mono, activePlatform);
string srcMonoFolder = Path.Combine(srcRoot, monoFolder);
string destMonoFolder = Path.Combine(destRoot, monoFolder);
DirectoryEx.Copy(srcMonoFolder, destMonoFolder);
string srcExecFile = GetMainExecutable(activePlatform);
string destExecFile = Path.Combine(destBin, Path.GetFileName(srcExecFile));
File.Copy(srcExecFile, destExecFile);
InjectIcons(destExecFile, platformInfo);
PackageResources(destRoot, platformInfo);
CreateStartupSettings(destRoot, platformInfo);
// Wait until compile finishes
while (!ci.IsDone)
Thread.Sleep(200);
ci.Dispose();
}
///
/// Injects icons specified in into an executable at the specified path.
///
/// Absolute path to the executable to inject icons in.
/// Object containing references to icons to inject.
private static void InjectIcons(string filePath, PlatformInfo info)
{
IntPtr infoPtr = IntPtr.Zero;
if (info != null)
infoPtr = info.GetCachedPtr();
Internal_InjectIcons(filePath, infoPtr);
}
///
/// Finds all used resources by the build and packages them into an output folder.
///
/// Absolute path to the root folder of the build. This is where the packaged resource
/// folder be placed.
/// Platform information about the current build.
private static void PackageResources(string buildFolder, PlatformInfo info)
{
IntPtr infoPtr = IntPtr.Zero;
if (info != null)
infoPtr = info.GetCachedPtr();
Internal_PackageResources(buildFolder, infoPtr);
}
///
/// Creates a game settings asset that contains necessary data for starting up the game (for example initial scene).
///
/// Absolute path to the root folder of the build. This is where the settings assets
/// will be output.
/// Platform information about the current build.
private static void CreateStartupSettings(string buildFolder, PlatformInfo info)
{
IntPtr infoPtr = IntPtr.Zero;
if (info != null)
infoPtr = info.GetCachedPtr();
Internal_CreateStartupSettings(buildFolder, infoPtr);
}
///
/// Returns a list of .NET framework managed assemblies (without extension) to be included for the specified platform.
///
/// Platform type to retrieve the list of assemblies for.
/// A list of .NET framework managed assemblies (without extension) that will be included with the build.
internal static string[] GetFrameworkAssemblies(PlatformType type)
{
return Internal_GetFrameworkAssemblies(type);
}
///
/// Returns the absolute path to the executable for the provided platform.
///
/// Platform type to retrieve the executable location for.
/// Absolute path to the executable.
internal static string GetMainExecutable(PlatformType type)
{
return Internal_GetMainExecutable(type);
}
///
/// Returns a list of semicolon separated defines that will be used when compiling scripts for the specified
/// platform.
///
/// Platfrom type to retrieve the defines for.
/// Semicolor separated defines that will be passed along to the script compiler.
internal static string GetDefines(PlatformType type)
{
return Internal_GetDefines(type);
}
///
/// Returns an object containing all platform specific build data.
///
/// Platform type to retrieve the data for.
/// An object containing all platform specific build data
internal static PlatformInfo GetPlatformInfo(PlatformType type)
{
return Internal_GetPlatformInfo(type);
}
///
/// Types of various folders used by the build manager.
///
private enum BuildFolder // Note: Must match C++ enum ScriptBuildFolder
{
/// Absolute path to the root folder where all the prebuilt binaries and data exist.
SourceRoot,
/// Absolute path to the root folder for a build for a specific platform.
DestinationRoot,
/// Folder where native binaries are stored. Relative to root.
NativeBinaries,
/// Folder where Banshee specific debug assemblies are stored. Relative to root.
BansheeDebugAssemblies,
/// Folder where Banshee specific release assemblies are stored. Relative to root.
BansheeReleaseAssemblies,
/// Folder where .NET framework assemblies are stored. Relative to root.
FrameworkAssemblies,
/// Folder where miscelaneous Mono files are stored. Relative to root.
Mono,
/// Folder where builtin data is stored. Relative to root.
Data
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern PlatformType[] Internal_GetAvailablePlatforms();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern PlatformType Internal_GetActivePlatform();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetActivePlatform(PlatformType value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern PlatformInfo Internal_GetActivePlatformInfo();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern PlatformInfo Internal_GetPlatformInfo(PlatformType type);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string[] Internal_GetFrameworkAssemblies(PlatformType type);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetMainExecutable(PlatformType type);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetDefines(PlatformType type);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string[] Internal_GetNativeBinaries(PlatformType type);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetBuildFolder(BuildFolder folder, PlatformType platform);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_InjectIcons(string filePath, IntPtr info);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_PackageResources(string buildFolder, IntPtr info);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_CreateStartupSettings(string buildFolder, IntPtr info);
}
/** @} */
}