|
6 | 6 | #endif
|
7 | 7 | using UnityEngine;
|
8 | 8 |
|
9 |
| -/// <summary> |
10 |
| -/// This is needed as Unity throws "An abnormal situation has occurred: the PlayerLoop internal function has been called recursively. Please contact Customer Support with a sample project so that we can reproduce the problem and troubleshoot it." |
11 |
| -/// when trying to build from Setup() steps in tests. |
12 |
| -/// </summary> |
13 |
| -public static class BuildMultiprocessTestPlayer |
| 9 | +namespace MLAPI.MultiprocessRuntimeTests |
14 | 10 | {
|
15 |
| - public const string MultiprocessBaseMenuName = "MLAPI/Multiprocess Test"; |
16 |
| - public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build Test Player #t"; |
17 |
| - public const string MainSceneName = "MultiprocessTestScene"; |
18 |
| - private static string BuildPathDirectory => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds", "MultiprocessTests"); |
19 |
| - public static string BuildPath => Path.Combine(BuildPathDirectory, "MultiprocessTestPlayer"); |
| 11 | + /// <summary> |
| 12 | + /// This is needed as Unity throws "An abnormal situation has occurred: the PlayerLoop internal function has been called recursively. Please contact Customer Support with a sample project so that we can reproduce the problem and troubleshoot it." |
| 13 | + /// when trying to build from Setup() steps in tests. |
| 14 | + /// </summary> |
| 15 | + public static class BuildMultiprocessTestPlayer |
| 16 | + { |
| 17 | + public const string MultiprocessBaseMenuName = "MLAPI/Multiprocess Test"; |
| 18 | + public const string BuildAndExecuteMenuName = MultiprocessBaseMenuName + "/Build Test Player #t"; |
| 19 | + public const string MainSceneName = "MultiprocessTestScene"; |
| 20 | + |
| 21 | + public const string BuildInfoFileName = "buildInfo.json"; |
| 22 | + |
| 23 | + private static string BuildPathDirectory => Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds", "MultiprocessTests"); |
| 24 | + public static string BuildPath => Path.Combine(BuildPathDirectory, "MultiprocessTestPlayer"); |
20 | 25 |
|
21 | 26 | #if UNITY_EDITOR
|
22 |
| - [MenuItem(BuildAndExecuteMenuName)] |
23 |
| - public static void BuildRelease() |
24 |
| - { |
25 |
| - var report = BuildPlayer(); |
26 |
| - if (report.summary.result != BuildResult.Succeeded) |
| 27 | + [MenuItem(BuildAndExecuteMenuName)] |
| 28 | + public static void BuildRelease() |
27 | 29 | {
|
28 |
| - throw new Exception($"Build failed! {report.summary.totalErrors} errors"); |
| 30 | + var report = BuildPlayer(); |
| 31 | + if (report.summary.result != BuildResult.Succeeded) |
| 32 | + { |
| 33 | + throw new Exception($"Build failed! {report.summary.totalErrors} errors"); |
| 34 | + } |
29 | 35 | }
|
30 |
| - } |
31 | 36 |
|
32 |
| - [MenuItem(MultiprocessBaseMenuName + "/Build Test Player (Debug)")] |
33 |
| - public static void BuildDebug() |
34 |
| - { |
35 |
| - var report = BuildPlayer(true); |
36 |
| - if (report.summary.result != BuildResult.Succeeded) |
| 37 | + [MenuItem(MultiprocessBaseMenuName + "/Build Test Player (Debug)")] |
| 38 | + public static void BuildDebug() |
37 | 39 | {
|
38 |
| - throw new Exception($"Build failed! {report.summary.totalErrors} errors"); |
| 40 | + var report = BuildPlayer(true); |
| 41 | + if (report.summary.result != BuildResult.Succeeded) |
| 42 | + { |
| 43 | + throw new Exception($"Build failed! {report.summary.totalErrors} errors"); |
| 44 | + } |
39 | 45 | }
|
40 |
| - } |
41 | 46 |
|
42 |
| - [MenuItem(MultiprocessBaseMenuName + "/Delete Test Build")] |
43 |
| - public static void DeleteBuild() |
44 |
| - { |
45 |
| - if (Directory.Exists(BuildPathDirectory)) |
| 47 | + [MenuItem(MultiprocessBaseMenuName + "/Delete Test Build")] |
| 48 | + public static void DeleteBuild() |
46 | 49 | {
|
47 |
| - Directory.Delete(BuildPathDirectory, recursive: true); |
| 50 | + if (Directory.Exists(BuildPathDirectory)) |
| 51 | + { |
| 52 | + Directory.Delete(BuildPathDirectory, recursive: true); |
| 53 | + } |
| 54 | + else |
| 55 | + { |
| 56 | + Debug.Log($"[{nameof(BuildMultiprocessTestPlayer)}] build directory does not exist ({BuildPathDirectory}) not deleting anything"); |
| 57 | + } |
48 | 58 | }
|
49 |
| - else |
| 59 | + |
| 60 | + /// <summary> |
| 61 | + /// Needs a separate build than the standalone test builds since we don't want the player to try to connect to the editor to do test |
| 62 | + /// reporting. We only want to main node to do that, worker nodes should be dumb |
| 63 | + /// </summary> |
| 64 | + /// <returns></returns> |
| 65 | + private static BuildReport BuildPlayer(bool isDebug = false) |
50 | 66 | {
|
51 |
| - Debug.Log($"[{nameof(BuildMultiprocessTestPlayer)}] build directory does not exist ({BuildPathDirectory}) not deleting anything"); |
52 |
| - } |
53 |
| - } |
| 67 | + // Save standalone build path to file so we can read it from standalone tests (that are not running from editor) |
| 68 | + SaveBuildInfo(new BuildInfo() { BuildPath = BuildPath, IsDebug = isDebug }); |
54 | 69 |
|
55 |
| - /// <summary> |
56 |
| - /// Needs a separate build than the standalone test builds since we don't want the player to try to connect to the editor to do test |
57 |
| - /// reporting. We only want to main node to do that, worker nodes should be dumb |
58 |
| - /// </summary> |
59 |
| - /// <returns></returns> |
60 |
| - private static BuildReport BuildPlayer(bool isDebug = false) |
61 |
| - { |
62 |
| - // Save standalone build path to file so we can read it from standalone tests (that are not running from editor) |
63 |
| - File.WriteAllText(Path.Combine(Application.streamingAssetsPath, MultiprocessOrchestration.BuildInfoFileName), BuildPath); |
| 70 | + // deleting so we don't end up testing on outdated builds if there's a build failure |
| 71 | + DeleteBuild(); |
64 | 72 |
|
65 |
| - // deleting so we don't end up testing on outdated builds if there's a build failure |
66 |
| - DeleteBuild(); |
| 73 | + var buildOptions = BuildOptions.None; |
| 74 | + buildOptions |= BuildOptions.IncludeTestAssemblies; |
| 75 | + buildOptions |= BuildOptions.StrictMode; |
| 76 | + if (isDebug) |
| 77 | + { |
| 78 | + buildOptions |= BuildOptions.Development; |
| 79 | + buildOptions |= BuildOptions.AllowDebugging; // enable this if you want to debug your players. Your players |
67 | 80 |
|
68 |
| - var buildOptions = BuildOptions.None; |
69 |
| - buildOptions |= BuildOptions.IncludeTestAssemblies; |
70 |
| - buildOptions |= BuildOptions.StrictMode; |
71 |
| - if (isDebug) |
72 |
| - { |
73 |
| - buildOptions |= BuildOptions.Development; |
74 |
| - buildOptions |= BuildOptions.AllowDebugging; // enable this if you want to debug your players. Your players |
75 |
| - // will have more connection permission popups when launching though |
| 81 | + // will have more connection permission popups when launching though |
| 82 | + } |
| 83 | + |
| 84 | + var buildPathToUse = BuildPath; |
| 85 | + if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor) |
| 86 | + { |
| 87 | + buildPathToUse += ".exe"; |
| 88 | + } |
| 89 | + |
| 90 | + Debug.Log($"Starting multiprocess player build using path {buildPathToUse}"); |
| 91 | + |
| 92 | + buildOptions &= ~BuildOptions.AutoRunPlayer; |
| 93 | + var buildReport = BuildPipeline.BuildPlayer( |
| 94 | + new[] { $"Assets/Scenes/{MainSceneName}.unity" }, |
| 95 | + buildPathToUse, |
| 96 | + EditorUserBuildSettings.activeBuildTarget, |
| 97 | + buildOptions); |
| 98 | + |
| 99 | + Debug.Log("Build finished"); |
| 100 | + return buildReport; |
76 | 101 | }
|
| 102 | +#endif |
77 | 103 |
|
78 |
| - var buildPathToUse = BuildPath; |
79 |
| - if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor) |
| 104 | + [Serializable] |
| 105 | + public struct BuildInfo |
80 | 106 | {
|
81 |
| - buildPathToUse += ".exe"; |
| 107 | + public string BuildPath; |
| 108 | + public bool IsDebug; |
82 | 109 | }
|
83 |
| - Debug.Log($"Starting multiprocess player build using path {buildPathToUse}"); |
84 | 110 |
|
85 |
| - buildOptions &= ~BuildOptions.AutoRunPlayer; |
86 |
| - var buildReport = BuildPipeline.BuildPlayer( |
87 |
| - new[] { $"Assets/Scenes/{MainSceneName}.unity" }, |
88 |
| - buildPathToUse, |
89 |
| - EditorUserBuildSettings.activeBuildTarget, |
90 |
| - buildOptions); |
| 111 | + public static BuildInfo ReadBuildInfo() |
| 112 | + { |
| 113 | + var jsonString = File.ReadAllText(Path.Combine(Application.streamingAssetsPath, BuildInfoFileName)); |
| 114 | + return JsonUtility.FromJson<BuildInfo>(jsonString); |
| 115 | + } |
91 | 116 |
|
92 |
| - Debug.Log("Build finished"); |
93 |
| - return buildReport; |
| 117 | + public static void SaveBuildInfo(BuildInfo toSave) |
| 118 | + { |
| 119 | + var buildInfoJson = JsonUtility.ToJson(toSave); |
| 120 | + File.WriteAllText(Path.Combine(Application.streamingAssetsPath, BuildInfoFileName), buildInfoJson); |
| 121 | + } |
94 | 122 | }
|
95 |
| -#endif |
96 | 123 | }
|
0 commit comments