Skip to content

Commit

Permalink
Merge pull request #90 from nowsprinting/feature/initialize_order
Browse files Browse the repository at this point in the history
Add callback-order parameter into InitializeOnLaunchAutopilotAttribute
  • Loading branch information
asurato authored Oct 30, 2024
2 parents 0338969 + 74cb55f commit bdeb5d7
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 192 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,12 @@ private static async UniTask InitializeOnLaunchAutopilotMethodAsync()
}
```

Note that the autopilot launch process is performed with `RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)` (default for `RuntimeInitializeOnLoadMethod`).
Also, `RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)` implements the initialization process for Configurable Enter Play Mode.
> [!NOTE]
> You can specify callback order with argument. Callbacks with lower values are called before ones with higher values.
> [!NOTE]
> The autopilot launch process is performed with `RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)` (default for `RuntimeInitializeOnLoadMethod`).
> Also, `RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)` implements the initialization process for Configurable Enter Play Mode.


Expand Down
8 changes: 6 additions & 2 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,12 @@ private static async UniTask InitializeOnLaunchAutopilotMethodAsync()
}
```

なお、オートパイロットの起動処理は、`RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)``RuntimeInitializeOnLoadMethod`のデフォルト)で実行しています。
また`RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)`で、Configurable Enter Play Modeのための初期化処理を実装しています。
> [!NOTE]
> 引数に呼び出し順序を指定できます。値の低いメソッドから順に呼び出されます。
> [!NOTE]
> オートパイロットの起動処理は、`RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)``RuntimeInitializeOnLoadMethod`のデフォルト)で実行しています。
> また`RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)`で、Configurable Enter Play Modeのための初期化処理を実装しています。


Expand Down
19 changes: 4 additions & 15 deletions Runtime/Agents/OneTimeAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
using Cysharp.Threading.Tasks;
using DeNA.Anjin.Attributes;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace DeNA.Anjin.Agents
{
Expand All @@ -23,7 +20,7 @@ public class OneTimeAgent : AbstractAgent
/// </summary>
public AbstractAgent agent;

[SerializeField] [HideInInspector] internal bool wasExecuted;
public bool WasExecuted { get; internal set; }

[InitializeOnLaunchAutopilot]
public static void ResetExecutedFlag()
Expand All @@ -32,28 +29,20 @@ public static void ResetExecutedFlag()
var oneTimeAgents = FindObjectsOfType<OneTimeAgent>();
foreach (var current in oneTimeAgents)
{
current.wasExecuted = false;
current.WasExecuted = false;
}
#if UNITY_EDITOR
// Reset asset files (in Editor only)
foreach (var guid in AssetDatabase.FindAssets("t:OneTimeAgent"))
{
var so = AssetDatabase.LoadAssetAtPath<OneTimeAgent>(AssetDatabase.GUIDToAssetPath(guid));
so.wasExecuted = false;
}
#endif
}

/// <inheritdoc />
public override async UniTask Run(CancellationToken token)
{
if (wasExecuted)
if (WasExecuted)
{
Logger.Log($"Skip {this.name} since it has already been executed");
return;
}

wasExecuted = true;
WasExecuted = true;

Logger.Log($"Enter {this.name}.Run()");

Expand Down
22 changes: 20 additions & 2 deletions Runtime/Attributes/InitializeOnLaunchAutopilotAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2023 DeNA Co., Ltd.
// Copyright (c) 2023-2024 DeNA Co., Ltd.
// This software is released under the MIT License.

using System;
Expand All @@ -8,10 +8,28 @@ namespace DeNA.Anjin.Attributes
{
/// <summary>
/// Attach to a static method that performs game title-specific initialization at autopilot startup.
/// Initialization is performed at the timing of `RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)`.
/// Called when `RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)`.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class InitializeOnLaunchAutopilotAttribute : PreserveAttribute
{
internal const int InitializeLoggerOrder = -20000;
internal const int CovertObsoleteOrder = -10000;
internal const int DefaultOrder = 0;

/// <summary>
/// Relative callback order for callbacks. Callbacks with lower values are called before ones with higher values.
/// </summary>
public int CallbackOrder { get; private set; }

/// <summary>
/// Attach to a static method that performs game title-specific initialization at autopilot startup.
/// Called when `RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)`.
/// </summary>
/// <param name="callbackOrder">Relative callback order. Callbacks with lower values are called before ones with higher values.</param>
public InitializeOnLaunchAutopilotAttribute(int callbackOrder = DefaultOrder)
{
this.CallbackOrder = callbackOrder;
}
}
}
40 changes: 3 additions & 37 deletions Runtime/Autopilot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using Assert = UnityEngine.Assertions.Assert;
#if UNITY_INCLUDE_TESTS
using NUnit.Framework;
using AssertionException = NUnit.Framework.AssertionException;
#endif
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace DeNA.Anjin
{
Expand Down Expand Up @@ -163,37 +156,10 @@ public async UniTask TerminateAsync(ExitCode exitCode, string logString = null,
JUnitReporter.Output(_state.settings.junitReportPath, (int)exitCode, logString, stackTrace, time);
}

Destroy(this.gameObject);
DestroyImmediate(this.gameObject);

_logger.Log("Terminate autopilot");
_state.settings = null;
_state.exitCode = exitCode;

if (_state.launchFrom == LaunchType.PlayMode) // Note: Editor play mode, Play mode tests, and Player build
{
#if UNITY_INCLUDE_TESTS
// Play mode tests
if (TestContext.CurrentContext != null && exitCode != ExitCode.Normally)
{
throw new AssertionException($"Autopilot failed with exit code {exitCode}");
}
#endif
return; // Only terminate autopilot run if starting from play mode.
}

#if UNITY_EDITOR
// Terminate when launch from edit mode (including launch from commandline)
_logger.Log("Stop playing by autopilot");
// XXX: Avoid a problem that Editor stay playing despite isPlaying get assigned false.
// SEE: https://github.com/DeNA/Anjin/issues/20
await UniTask.NextFrame(token);
EditorApplication.isPlaying = false;
// Note: If launched from the command line, `DeNA.Anjin.Editor.Commandline.OnChangePlayModeState()` will be called, and the Unity editor will be terminated.
#else
// Player build launch from commandline
_logger.Log($"Exit Unity-player by autopilot, exit code={exitCode}");
Application.Quit((int)exitCode);
#endif
_logger.Log("Terminate Autopilot");
await Launcher.TeardownLaunchAutopilotAsync(_state, _logger, exitCode, "Autopilot", token);
}

/// <summary>
Expand Down
15 changes: 10 additions & 5 deletions Runtime/ExitCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,28 @@
namespace DeNA.Anjin
{
/// <summary>
/// Exit code for autopilot running
/// Autopilot exit code.
/// </summary>
public enum ExitCode
{
/// <summary>
/// Normally exit
/// Normally exit.
/// </summary>
Normally = 0,

/// <summary>
/// Exit by un catch Exceptions
/// Uncaught exceptions.
/// </summary>
UnCatchExceptions = 1,

/// <summary>
/// Exit by fault in log message
/// Autopilot running failed.
/// </summary>
AutopilotFailed = 2
AutopilotFailed = 2,

/// <summary>
/// Autopilot launching failed.
/// </summary>
AutopilotLaunchingFailed
}
}
Loading

0 comments on commit bdeb5d7

Please sign in to comment.