Skip to content

Commit 834cb50

Browse files
fix(core): address PR review feedback for Prompt abstraction
- Make ShowDialogAsync thread-safe with volatile backing field and Interlocked.Exchange - Improve XML documentation for Prompt class with usage examples - Change default behavior to log error and return false (safer default) - Add namespace to PromptInitializer (JEngine) - Add TextMeshPro dependency to jengine.ui package.json - Remove JEngine.UI dependency from HotUpdate.Code (use Prompt abstraction instead) - Update EntryPoint.cs to use Prompt.ShowDialogAsync instead of MessageBox.Show Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
1 parent d9508df commit 834cb50

5 files changed

Lines changed: 53 additions & 24 deletions

File tree

UnityProject/Assets/HotUpdate/Code/EntryPoint.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
using JEngine.Core;
2828
using JEngine.Core.Encrypt;
2929
using JEngine.Core.Update;
30-
using JEngine.UI;
3130
using Obfuz;
3231
using UnityEngine;
3332
using UnityEngine.Scripting;
@@ -64,7 +63,7 @@ async UniTask LoadAddOnPackage()
6463
{
6564
OnStatusUpdate = static status => Debug.Log($"[AddOn1] Status: {GetStatusText(status)}"),
6665
OnVersionUpdate = static version => Debug.Log($"[AddOn1] Version: {version}"),
67-
OnDownloadPrompt = static (count, size) => MessageBox.Show("Notice",
66+
OnDownloadPrompt = static (count, size) => Prompt.ShowDialogAsync("Notice",
6867
$"[AddOn1] Need to download {count} files, total size {size / 1024f / 1024f:F2}MB. Continue?",
6968
"Yes", "No"),
7069
OnDownloadProgress = static data =>

UnityProject/Assets/HotUpdate/Code/HotUpdate.Code.asmdef

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
"GUID:3fe1a3e70da50184f9897101cad7e4f2",
1313
"GUID:6055be8ebefd69e48b49212b09b47b2f",
1414
"GUID:ba02d1bbd77cf4a0c8606d3e5cbbbe79",
15-
"GUID:5c8e1f4d7a3b9e2c6f0d8a4b7e3c1f9d",
16-
"GUID:5655bcbaa4dec434b86ecd07e2c6f24d"
15+
"GUID:5c8e1f4d7a3b9e2c6f0d8a4b7e3c1f9d"
1716
],
1817
"includePlatforms": [],
1918
"excludePlatforms": [],

UnityProject/Assets/Scripts/PromptInitializer.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,28 @@
3434
// "com.jasonxudeveloper.jengine.ui": "1.0.0"
3535
//
3636
// If you don't need MessageBox dialogs, you can:
37-
// - Delete this script entirely (Bootstrap will log warnings and continue)
37+
// - Delete this script entirely (Bootstrap will log errors and continue)
3838
// - Implement your own custom dialog provider by assigning to Prompt.ShowDialogAsync
3939
// ============================================================================
4040

4141
using JEngine.Core;
4242
using JEngine.UI;
4343
using UnityEngine;
4444

45-
/// <summary>
46-
/// Initializes the Prompt system to use MessageBox for dialogs.
47-
/// This runs automatically before any scene loads.
48-
/// </summary>
49-
public static class PromptInitializer
45+
namespace JEngine
5046
{
51-
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
52-
private static void Initialize()
47+
/// <summary>
48+
/// Initializes the Prompt system to use MessageBox for dialogs.
49+
/// This runs automatically before any scene loads.
50+
/// </summary>
51+
public static class PromptInitializer
5352
{
54-
// Register MessageBox as the dialog provider for JEngine.Core
55-
Prompt.ShowDialogAsync = MessageBox.Show;
56-
Debug.Log("[JEngine] Prompt system initialized with MessageBox provider.");
53+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
54+
private static void Initialize()
55+
{
56+
// Register MessageBox as the dialog provider for JEngine.Core
57+
Prompt.ShowDialogAsync = MessageBox.Show;
58+
Debug.Log("[JEngine] Prompt system initialized with MessageBox provider.");
59+
}
5760
}
5861
}

UnityProject/Packages/com.jasonxudeveloper.jengine.core/Runtime/Prompt.cs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,55 @@
2424
// THE SOFTWARE.
2525

2626
using System;
27+
using System.Threading;
2728
using Cysharp.Threading.Tasks;
2829
using UnityEngine;
2930

3031
namespace JEngine.Core
3132
{
3233
/// <summary>
33-
/// User prompt/dialog abstraction. Configure ShowDialogAsync to customize behavior.
34+
/// Provides an abstraction layer for displaying user prompts and dialogs.
35+
/// This allows the core framework to request user input without depending on specific UI implementations.
3436
/// </summary>
37+
/// <remarks>
38+
/// <para>
39+
/// By default, dialogs log an error and return false. To enable actual dialogs,
40+
/// assign a handler to <see cref="ShowDialogAsync"/> before Bootstrap runs.
41+
/// </para>
42+
/// <para>
43+
/// Example using JEngine.UI.MessageBox:
44+
/// <code>
45+
/// [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
46+
/// static void Init() => Prompt.ShowDialogAsync = MessageBox.Show;
47+
/// </code>
48+
/// </para>
49+
/// </remarks>
3550
public static class Prompt
3651
{
52+
private static volatile Func<string, string, string, string, UniTask<bool>> _showDialogAsync = DefaultShowDialog;
53+
3754
/// <summary>
38-
/// Shows a dialog to the user and returns the result.
39-
/// Parameters: title, content, okText (null to hide), noText (null to hide)
40-
/// Returns: true if OK clicked, false if No/Cancel clicked
41-
/// Default: logs warning and returns true (continues execution).
55+
/// Gets or sets the dialog handler function.
4256
/// </summary>
43-
public static Func<string, string, string, string, UniTask<bool>> ShowDialogAsync = DefaultShowDialog;
57+
/// <value>
58+
/// A function that displays a dialog to the user.
59+
/// Parameters: title, content, okText (null to hide OK button), noText (null to hide No button).
60+
/// Returns: true if OK clicked, false if No/Cancel clicked.
61+
/// </value>
62+
/// <remarks>
63+
/// This property is thread-safe. Assign before Bootstrap runs using
64+
/// <c>[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]</c>.
65+
/// </remarks>
66+
public static Func<string, string, string, string, UniTask<bool>> ShowDialogAsync
67+
{
68+
get => _showDialogAsync;
69+
set => Interlocked.Exchange(ref _showDialogAsync, value ?? DefaultShowDialog);
70+
}
4471

4572
private static UniTask<bool> DefaultShowDialog(string title, string content, string ok, string no)
4673
{
47-
Debug.LogWarning($"[JEngine] Dialog provider not configured. {title}: {content}");
48-
return UniTask.FromResult(true);
74+
Debug.LogError($"[JEngine] Dialog provider not configured. Cannot display: {title}: {content}");
75+
return UniTask.FromResult(false);
4976
}
5077
}
5178
}

UnityProject/Packages/com.jasonxudeveloper.jengine.ui/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"url": "https://github.com/JasonXuDeveloper"
1919
},
2020
"dependencies": {
21-
"com.cysharp.unitask": "2.5.10"
21+
"com.cysharp.unitask": "2.5.10",
22+
"com.unity.textmeshpro": "3.0.6"
2223
}
2324
}

0 commit comments

Comments
 (0)