//********************************** 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); } /** @} */ }