Skip to content

Commit d293700

Browse files
authored
Merge pull request #82 from ELDment/beta-1
feat: Implement async support for `AddSubmenu`
2 parents 247735f + 5b8266c commit d293700

File tree

5 files changed

+157
-79
lines changed

5 files changed

+157
-79
lines changed

managed/src/SwiftlyS2.Core/Modules/Menus/Menu.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ public void UseSelection( IPlayer player )
321321
asyncButton.SetLoadingText("Processing...");
322322
Rerender(player, true);
323323
var closeAfter = asyncButton.CloseOnSelect;
324-
Task.Run(async () =>
324+
_ = Task.Run(async () =>
325325
{
326326
try
327327
{
@@ -355,12 +355,17 @@ public void UseSelection( IPlayer player )
355355
}
356356

357357
case SubmenuMenuOption submenu:
358-
var subMenu = submenu.GetSubmenu();
359-
if (subMenu != null)
358+
_ = Task.Run(async () =>
360359
{
361-
subMenu.Parent = this;
362-
MenuManager.OpenMenu(player, subMenu);
363-
}
360+
var subMenu = await submenu.GetSubmenuAsync();
361+
if (subMenu != null && player.IsValid && MenuManager.GetMenu(player) == this)
362+
{
363+
subMenu.Parent = this;
364+
MenuManager.OpenMenu(player, subMenu);
365+
}
366+
});
367+
break;
368+
default:
364369
break;
365370
}
366371
}

managed/src/SwiftlyS2.Core/Modules/Menus/MenuBuilder.cs

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,133 +13,145 @@ internal class MenuBuilder : IMenuBuilder
1313

1414
public IMenuDesign Design => _design ??= new MenuDesign(_menu!);
1515

16-
public IMenuBuilder SetMenu(IMenu menu)
16+
public IMenuBuilder SetMenu( IMenu menu )
1717
{
1818
_menu = menu;
1919
return this;
2020
}
2121

22-
public IMenuBuilder AddButton(string text, Action<IPlayer>? onClick = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
22+
public IMenuBuilder AddButton( string text, Action<IPlayer>? onClick = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
2323
{
2424
_menu!.Options.Add(new ButtonMenuOption(text, onClick, size, overflowStyle));
2525
_menu!.Options[^1].Menu = _menu;
2626
return this;
2727
}
2828

29-
public IMenuBuilder AddButton(string text, Action<IPlayer, IOption>? onClick, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
29+
public IMenuBuilder AddButton( string text, Action<IPlayer, IOption>? onClick, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
3030
{
3131
_menu!.Options.Add(new ButtonMenuOption(text, onClick, size, overflowStyle));
3232
_menu!.Options[^1].Menu = _menu;
3333
return this;
3434
}
3535

36-
public IMenuBuilder AddButton(string text, Action<IPlayer>? onClick, MenuHorizontalStyle? overflowStyle = null)
36+
public IMenuBuilder AddButton( string text, Action<IPlayer>? onClick, MenuHorizontalStyle? overflowStyle = null )
3737
{
3838
return AddButton(text, onClick, IMenuTextSize.Medium, overflowStyle);
3939
}
4040

41-
public IMenuBuilder AddToggle(string text, bool defaultValue = false, Action<IPlayer, bool>? onToggle = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
41+
public IMenuBuilder AddToggle( string text, bool defaultValue = false, Action<IPlayer, bool>? onToggle = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
4242
{
4343
_menu!.Options.Add(new ToggleMenuOption(text, defaultValue, onToggle, size, overflowStyle));
4444
_menu!.Options[^1].Menu = _menu;
4545
return this;
4646
}
4747

48-
public IMenuBuilder AddToggle(string text, bool defaultValue, Action<IPlayer, IOption, bool>? onToggle, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
48+
public IMenuBuilder AddToggle( string text, bool defaultValue, Action<IPlayer, IOption, bool>? onToggle, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
4949
{
5050
_menu!.Options.Add(new ToggleMenuOption(text, defaultValue, onToggle, size, overflowStyle));
5151
_menu!.Options[^1].Menu = _menu;
5252
return this;
5353
}
5454

55-
public IMenuBuilder AddToggle(string text, bool defaultValue, Action<IPlayer, bool>? onToggle, MenuHorizontalStyle? overflowStyle = null)
55+
public IMenuBuilder AddToggle( string text, bool defaultValue, Action<IPlayer, bool>? onToggle, MenuHorizontalStyle? overflowStyle = null )
5656
{
5757
return AddToggle(text, defaultValue, onToggle, IMenuTextSize.Medium, overflowStyle);
5858
}
5959

60-
public IMenuBuilder AddSlider(string text, float min, float max, float defaultValue, float step = 1, Action<IPlayer, float>? onChange = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
60+
public IMenuBuilder AddSlider( string text, float min, float max, float defaultValue, float step = 1, Action<IPlayer, float>? onChange = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
6161
{
6262
_menu!.Options.Add(new SliderMenuButton(text, min, max, defaultValue, step, onChange, size, overflowStyle));
6363
_menu!.Options[^1].Menu = _menu;
6464
return this;
6565
}
6666

67-
public IMenuBuilder AddSlider(string text, float min, float max, float defaultValue, float step, Action<IPlayer, IOption, float>? onChange, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
67+
public IMenuBuilder AddSlider( string text, float min, float max, float defaultValue, float step, Action<IPlayer, IOption, float>? onChange, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
6868
{
6969
_menu!.Options.Add(new SliderMenuButton(text, min, max, defaultValue, step, onChange, size, overflowStyle));
7070
_menu!.Options[^1].Menu = _menu;
7171
return this;
7272
}
7373

74-
public IMenuBuilder AddSlider(string text, float min, float max, float defaultValue, float step, Action<IPlayer, float>? onChange, MenuHorizontalStyle? overflowStyle = null)
74+
public IMenuBuilder AddSlider( string text, float min, float max, float defaultValue, float step, Action<IPlayer, float>? onChange, MenuHorizontalStyle? overflowStyle = null )
7575
{
7676
return AddSlider(text, min, max, defaultValue, step, onChange, IMenuTextSize.Medium, overflowStyle);
7777
}
7878

79-
public IMenuBuilder AddAsyncButton(string text, Func<IPlayer, Task> onClickAsync, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
79+
public IMenuBuilder AddAsyncButton( string text, Func<IPlayer, Task> onClickAsync, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
8080
{
8181
_menu!.Options.Add(new AsyncButtonMenuOption(text, onClickAsync, size, overflowStyle));
8282
_menu!.Options[^1].Menu = _menu;
8383
return this;
8484
}
8585

86-
public IMenuBuilder AddAsyncButton(string text, Func<IPlayer, IOption, Task> onClickAsync, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
86+
public IMenuBuilder AddAsyncButton( string text, Func<IPlayer, IOption, Task> onClickAsync, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
8787
{
8888
_menu!.Options.Add(new AsyncButtonMenuOption(text, onClickAsync, size, overflowStyle));
8989
_menu!.Options[^1].Menu = _menu;
9090
return this;
9191
}
9292

93-
public IMenuBuilder AddAsyncButton(string text, Func<IPlayer, Task> onClickAsync, MenuHorizontalStyle? overflowStyle = null)
93+
public IMenuBuilder AddAsyncButton( string text, Func<IPlayer, Task> onClickAsync, MenuHorizontalStyle? overflowStyle = null )
9494
{
9595
return AddAsyncButton(text, onClickAsync, IMenuTextSize.Medium, overflowStyle);
9696
}
9797

98-
public IMenuBuilder AddText(string text, ITextAlign alignment = ITextAlign.Left, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
98+
public IMenuBuilder AddText( string text, ITextAlign alignment = ITextAlign.Left, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
9999
{
100100
_menu!.Options.Add(new TextMenuOption(text, alignment, size, overflowStyle));
101101
_menu!.Options[^1].Menu = _menu;
102102
return this;
103103
}
104104

105-
public IMenuBuilder AddDynamicText(Func<string> textProvider, TimeSpan updateInterval, Action<IPlayer>? onClick = null, IMenuTextSize size = IMenuTextSize.Medium)
105+
public IMenuBuilder AddDynamicText( Func<string> textProvider, TimeSpan updateInterval, Action<IPlayer>? onClick = null, IMenuTextSize size = IMenuTextSize.Medium )
106106
{
107107
_menu!.Options.Add(new DynamicMenuOption(textProvider, updateInterval, onClick, size));
108108
_menu!.Options[^1].Menu = _menu;
109109
return this;
110110
}
111-
public IMenuBuilder AddSubmenu(string text, IMenu submenu, IMenuTextSize size = IMenuTextSize.Medium)
111+
public IMenuBuilder AddSubmenu( string text, IMenu submenu, IMenuTextSize size = IMenuTextSize.Medium )
112112
{
113113
_menu!.Options.Add(new SubmenuMenuOption(text, submenu, size));
114114
_menu!.Options[^1].Menu = _menu;
115115
return this;
116116
}
117117

118-
public IMenuBuilder AddSubmenu(string text, IMenu submenu)
118+
public IMenuBuilder AddSubmenu( string text, IMenu submenu )
119119
{
120120
return AddSubmenu(text, submenu, IMenuTextSize.Medium);
121121
}
122122

123-
public IMenuBuilder AddSubmenu(string text, Func<IMenu> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium)
123+
public IMenuBuilder AddSubmenu( string text, Func<IMenu> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium )
124124
{
125125
_menu!.Options.Add(new SubmenuMenuOption(text, submenuBuilder, size));
126126
_menu!.Options[^1].Menu = _menu;
127127
return this;
128128
}
129129

130-
public IMenuBuilder AddSubmenu(string text, Func<IMenu> submenuBuilder)
130+
public IMenuBuilder AddSubmenu( string text, Func<IMenu> submenuBuilder )
131131
{
132132
return AddSubmenu(text, submenuBuilder, IMenuTextSize.Medium);
133133
}
134134

135-
public IMenuBuilder AddChoice(string text, string[] choices, string? defaultChoice = null, Action<IPlayer, string>? onChange = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
135+
public IMenuBuilder AddSubmenu( string text, Func<Task<IMenu>> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium )
136+
{
137+
_menu!.Options.Add(new SubmenuMenuOption(text, submenuBuilder, size));
138+
_menu!.Options[^1].Menu = _menu;
139+
return this;
140+
}
141+
142+
public IMenuBuilder AddSubmenu( string text, Func<Task<IMenu>> submenuBuilder )
143+
{
144+
return AddSubmenu(text, submenuBuilder, IMenuTextSize.Medium);
145+
}
146+
147+
public IMenuBuilder AddChoice( string text, string[] choices, string? defaultChoice = null, Action<IPlayer, string>? onChange = null, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
136148
{
137149
_menu!.Options.Add(new ChoiceMenuOption(text, choices, defaultChoice, onChange, size, overflowStyle));
138150
_menu!.Options[^1].Menu = _menu;
139151
return this;
140152
}
141153

142-
public IMenuBuilder AddChoice(string text, string[] choices, string? defaultChoice, Action<IPlayer, IOption, string>? onChange, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
154+
public IMenuBuilder AddChoice( string text, string[] choices, string? defaultChoice, Action<IPlayer, IOption, string>? onChange, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
143155
{
144156
_menu!.Options.Add(new ChoiceMenuOption(text, choices, defaultChoice, onChange, size, overflowStyle));
145157
_menu!.Options[^1].Menu = _menu;
@@ -159,26 +171,26 @@ public IMenuBuilder AddSeparator()
159171
return this;
160172
}
161173

162-
public IMenuBuilder AddProgressBar(string text, Func<float> progressProvider, int barWidth = 20, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null)
174+
public IMenuBuilder AddProgressBar( string text, Func<float> progressProvider, int barWidth = 20, IMenuTextSize size = IMenuTextSize.Medium, MenuHorizontalStyle? overflowStyle = null )
163175
{
164176
_menu!.Options.Add(new ProgressBarMenuOption(text, progressProvider, barWidth, size, overflowStyle));
165177
_menu!.Options[^1].Menu = _menu;
166178
_menu!.RenderOntick = true;
167179
return this;
168180
}
169181

170-
public IMenuBuilder AddProgressBar(string text, Func<float> progressProvider, int barWidth, MenuHorizontalStyle? overflowStyle = null)
182+
public IMenuBuilder AddProgressBar( string text, Func<float> progressProvider, int barWidth, MenuHorizontalStyle? overflowStyle = null )
171183
{
172184
return AddProgressBar(text, progressProvider, barWidth, IMenuTextSize.Medium, overflowStyle);
173185
}
174-
public IMenuBuilder WithParent(IMenu parent)
186+
public IMenuBuilder WithParent( IMenu parent )
175187
{
176188
_parent = parent;
177189
_menu!.Parent = parent;
178190
return this;
179191
}
180192

181-
public IMenuBuilder VisibleWhen(Func<IPlayer, bool> condition)
193+
public IMenuBuilder VisibleWhen( Func<IPlayer, bool> condition )
182194
{
183195
if (_menu!.Options.Count > 0 && _menu!.Options[^1] is ButtonMenuOption button)
184196
{
@@ -207,7 +219,7 @@ public IMenuBuilder VisibleWhen(Func<IPlayer, bool> condition)
207219
return this;
208220
}
209221

210-
public IMenuBuilder EnabledWhen(Func<IPlayer, bool> condition)
222+
public IMenuBuilder EnabledWhen( Func<IPlayer, bool> condition )
211223
{
212224
if (_menu!.Options.Count > 0 && _menu!.Options[^1] is ButtonMenuOption button)
213225
{
@@ -236,7 +248,7 @@ public IMenuBuilder EnabledWhen(Func<IPlayer, bool> condition)
236248
return this;
237249
}
238250

239-
public IMenuBuilder WithValidation(Func<IPlayer, bool> validation, Action<IPlayer>? onFailed = null)
251+
public IMenuBuilder WithValidation( Func<IPlayer, bool> validation, Action<IPlayer>? onFailed = null )
240252
{
241253
if (_menu!.Options.Count > 0 && _menu!.Options[^1] is ButtonMenuOption button)
242254
{
@@ -281,41 +293,41 @@ public IMenuBuilder CloseOnSelect()
281293
return this;
282294
}
283295

284-
public IMenuBuilder AutoClose(float seconds)
296+
public IMenuBuilder AutoClose( float seconds )
285297
{
286298
_menu!.AutoCloseAfter = seconds;
287299
return this;
288300
}
289301

290-
public IMenuBuilder OverrideButtons(Action<IMenuButtonOverrides> configureOverrides)
302+
public IMenuBuilder OverrideButtons( Action<IMenuButtonOverrides> configureOverrides )
291303
{
292304
configureOverrides(_menu!.ButtonOverrides!);
293305
return this;
294306
}
295307

296308
[Obsolete("Use Design.OverrideSelectButton instead")]
297-
public IMenuBuilder OverrideSelectButton(params string[] buttonNames)
309+
public IMenuBuilder OverrideSelectButton( params string[] buttonNames )
298310
{
299311
_menu!.ButtonOverrides!.Select = MenuButtonOverrides.ParseButtons(buttonNames);
300312
return this;
301313
}
302314

303315
[Obsolete("Use Design.OverrideMoveButton instead")]
304-
public IMenuBuilder OverrideMoveButton(params string[] buttonNames)
316+
public IMenuBuilder OverrideMoveButton( params string[] buttonNames )
305317
{
306318
_menu!.ButtonOverrides!.Move = MenuButtonOverrides.ParseButtons(buttonNames);
307319
return this;
308320
}
309321

310322
[Obsolete("Use Design.OverrideExitButton instead")]
311-
public IMenuBuilder OverrideExitButton(params string[] buttonNames)
323+
public IMenuBuilder OverrideExitButton( params string[] buttonNames )
312324
{
313325
_menu!.ButtonOverrides!.Exit = MenuButtonOverrides.ParseButtons(buttonNames);
314326
return this;
315327
}
316328

317329
[Obsolete("Use Design.MaxVisibleItems instead")]
318-
public IMenuBuilder MaxVisibleItems(int count)
330+
public IMenuBuilder MaxVisibleItems( int count )
319331
{
320332
if (count < 1 || count > 5)
321333
{
@@ -337,14 +349,14 @@ public IMenuBuilder ForceFreeze()
337349
return this;
338350
}
339351

340-
public IMenuBuilder HasSound(bool hasSound)
352+
public IMenuBuilder HasSound( bool hasSound )
341353
{
342354
_menu!.HasSound = hasSound;
343355
return this;
344356
}
345357

346358
[Obsolete("Use Design.SetColor instead")]
347-
public IMenuBuilder SetColor(Color color)
359+
public IMenuBuilder SetColor( Color color )
348360
{
349361
_menu!.RenderColor = color;
350362
return this;

managed/src/SwiftlyS2.Core/Modules/Menus/Options/SubmenuMenuOption.cs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ internal class SubmenuMenuOption : IOption
88
{
99
public string Text { get; set; }
1010
public IMenu? Submenu { get; set; }
11-
public Func<IMenu>? SubmenuBuilder { get; set; }
11+
public Func<Task<IMenu>>? SubmenuBuilderAsync { get; set; }
1212
public Func<IPlayer, bool>? VisibilityCheck { get; set; }
1313
public Func<IPlayer, bool>? EnabledCheck { get; set; }
1414
public IMenuTextSize Size { get; set; }
@@ -18,31 +18,38 @@ internal class SubmenuMenuOption : IOption
1818
public bool Visible => true;
1919
public bool Enabled => true;
2020

21-
public SubmenuMenuOption(string text, IMenu? submenu = null, IMenuTextSize size = IMenuTextSize.Medium)
21+
public SubmenuMenuOption( string text, IMenu? submenu = null, IMenuTextSize size = IMenuTextSize.Medium )
2222
{
2323
Text = text;
2424
Submenu = submenu;
2525
Size = size;
2626
}
2727

28-
public SubmenuMenuOption(string text, Func<IMenu> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium)
28+
public SubmenuMenuOption( string text, Func<IMenu> submenuBuilder, IMenuTextSize size = IMenuTextSize.Medium )
2929
{
3030
Text = text;
31-
SubmenuBuilder = submenuBuilder;
31+
SubmenuBuilderAsync = () => Task.FromResult(submenuBuilder());
3232
Size = size;
3333
}
3434

35-
public bool ShouldShow(IPlayer player)
35+
public SubmenuMenuOption( string text, Func<Task<IMenu>> asyncSubmenuBuilder, IMenuTextSize size = IMenuTextSize.Medium )
36+
{
37+
Text = text;
38+
SubmenuBuilderAsync = asyncSubmenuBuilder;
39+
Size = size;
40+
}
41+
42+
public bool ShouldShow( IPlayer player )
3643
{
3744
return VisibilityCheck?.Invoke(player) ?? true;
3845
}
3946

40-
public bool CanInteract(IPlayer player)
47+
public bool CanInteract( IPlayer player )
4148
{
4249
return EnabledCheck?.Invoke(player) ?? true;
4350
}
4451

45-
public string GetDisplayText(IPlayer player, bool updateHorizontalStyle = false)
52+
public string GetDisplayText( IPlayer player, bool updateHorizontalStyle = false )
4653
{
4754
var sizeClass = MenuSizeHelper.GetSizeClass(Size);
4855

@@ -61,8 +68,18 @@ public IMenuTextSize GetTextSize()
6168
return Size;
6269
}
6370

64-
public IMenu? GetSubmenu()
71+
public async Task<IMenu?> GetSubmenuAsync()
6572
{
66-
return Submenu ?? SubmenuBuilder?.Invoke();
73+
if (Submenu != null)
74+
{
75+
return Submenu;
76+
}
77+
78+
if (SubmenuBuilderAsync != null)
79+
{
80+
return await SubmenuBuilderAsync.Invoke();
81+
}
82+
83+
return null;
6784
}
68-
}
85+
}

0 commit comments

Comments
 (0)