diff --git a/Runtime/AgentDispatcher.cs b/Runtime/AgentDispatcher.cs
index 3046046..fb00ab6 100644
--- a/Runtime/AgentDispatcher.cs
+++ b/Runtime/AgentDispatcher.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2023 DeNA Co., Ltd.
// This software is released under the MIT License.
+using System;
using DeNA.Anjin.Agents;
using DeNA.Anjin.Settings;
using DeNA.Anjin.Utilities;
@@ -88,17 +89,17 @@ public void DispatchByScene(Scene scene)
agent = _settings.fallbackAgent;
}
- DispatchAgent(agent);
+ DispatchAgent(agent).Forget();
if (_settings.observerAgent != null)
{
- DispatchAgent(_settings.observerAgent);
+ DispatchAgent(_settings.observerAgent).Forget();
// Note: The ObserverAgent is not made to DontDestroyOnLoad, to start every time.
// Because it is a source of bugs to force the implementation of DontDestroyOnLoad to the descendants of the Composite.
}
}
- private void DispatchAgent(AbstractAgent agent)
+ private async UniTask DispatchAgent(AbstractAgent agent)
{
var agentName = agent.name;
var gameObject = new GameObject(agentName);
@@ -106,9 +107,19 @@ private void DispatchAgent(AbstractAgent agent)
agent.Logger = _logger;
agent.Random = _randomFactory.CreateRandom();
- agent.Run(token).Forget();
-
- _logger.Log($"Agent {agentName} dispatched!");
+
+ try
+ {
+ agent.Run(token).Forget();
+ _logger.Log($"Agent {agentName} dispatched!");
+ }
+ catch (Exception e)
+ {
+ // XXX: Wait 1 frame to fix https://github.com/DeNA/Anjin/issues/20
+ await UniTask.DelayFrame(1, cancellationToken: token);
+ Debug.LogException(e);
+ _logger.Log($"Agent {agentName} dispatched but immediately threw an error!");
+ }
}
}
}
diff --git a/Runtime/Autopilot.cs b/Runtime/Autopilot.cs
index 7bf1ac7..6cbb190 100644
--- a/Runtime/Autopilot.cs
+++ b/Runtime/Autopilot.cs
@@ -62,15 +62,18 @@ private void Start()
_randomFactory = new RandomFactory(seed);
_logger.Log($"Random seed is {seed}");
+
+ // NOTE: Registering logMessageReceived must be placed before DispatchByScene.
+ // Because some agent can throw an error immediately, so reporter can miss the error if
+ // registering logMessageReceived is placed after DispatchByScene.
+ _reporter = new SlackReporter(_settings, new SlackAPI());
+ _logMessageHandler = new LogMessageHandler(_settings, _reporter);
+ Application.logMessageReceived += _logMessageHandler.HandleLog;
_dispatcher = new AgentDispatcher(_settings, _logger, _randomFactory);
_dispatcher.DispatchByScene(SceneManager.GetActiveScene());
SceneManager.activeSceneChanged += _dispatcher.DispatchByScene;
- _reporter = new SlackReporter(_settings, new SlackAPI());
- _logMessageHandler = new LogMessageHandler(_settings, _reporter);
- Application.logMessageReceived += _logMessageHandler.HandleLog;
-
if (_settings.lifespanSec > 0)
{
StartCoroutine(Lifespan(_settings.lifespanSec));
diff --git a/Tests/Runtime/TestDoubles/StubClickAgent.cs b/Tests/Runtime/TestDoubles/StubClickAgent.cs
index d384def..e03b57e 100644
--- a/Tests/Runtime/TestDoubles/StubClickAgent.cs
+++ b/Tests/Runtime/TestDoubles/StubClickAgent.cs
@@ -9,10 +9,18 @@
namespace DeNA.Anjin.TestDoubles
{
+ ///
+ /// A test double for agent. This agent immediately click game objects that have the name specified
+ ///
public class StubClickAgent : AbstractAgent
{
+ ///
+ /// A name of game objects to click
+ ///
[SerializeField] public string targetName;
+
+ ///
public override UniTask Run(CancellationToken token)
{
foreach (var obj in FindObjectsByType(FindObjectsSortMode.None))
@@ -33,6 +41,7 @@ public override UniTask Run(CancellationToken token)
handler.OnPointerClick(new PointerEventData(EventSystem.current));
}
+
return UniTask.CompletedTask;
}
}