Skip to content

Commit 904037b

Browse files
committed
Improve performance of RichLabel, add AppendText, adapt Typewriter to append text rather than deal with precomputed labels AscensionGameDev#2565
1 parent 8111e5c commit 904037b

File tree

6 files changed

+273
-180
lines changed

6 files changed

+273
-180
lines changed

Framework/Intersect.Framework.Core/Configuration/ClientConfiguration.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,23 @@ public static ClientConfiguration LoadAndSave(string? filePath = default) =>
6161

6262
public const bool DefaultTypewriterEnabled = true;
6363

64-
public static List<char> DefaultTypewriterFullStopCharacters =>
64+
public static HashSet<string> DefaultTypewriterFullStops =>
6565
[
66-
'.',
67-
'!',
68-
'?',
69-
':',
66+
".",
67+
"!",
68+
"?",
69+
":",
7070
];
7171

7272
public const long DefaultTypewriterFullStopDelay = 400;
7373

7474
public const long DefaultTypewriterPartDelay = 6;
7575

76-
public static List<char> DefaultTypewriterPauseCharacters =>
76+
public static HashSet<string> DefaultTypewriterPauses =>
7777
[
78-
',',
79-
';',
80-
'-',
78+
",",
79+
";",
80+
"-",
8181
];
8282

8383
public const long DefaultTypewriterPauseDelay = 80;
@@ -115,8 +115,8 @@ public void Validate()
115115
},
116116
];
117117
Port = Math.Min(Math.Max(Port, (ushort)1), ushort.MaxValue);
118-
TypewriterFullStopCharacters = TypewriterFullStopCharacters?.Distinct()?.ToList() ?? [];
119-
TypewriterPauseCharacters = TypewriterPauseCharacters?.Distinct()?.ToList() ?? [];
118+
TypewriterFullStops ??= [];
119+
TypewriterPauses ??= [];
120120
TypewriterSounds = [..TypewriterSounds?.Distinct() ?? new List<string>()];
121121
UIFont = string.IsNullOrWhiteSpace(UIFont) ? DefaultUIFont : UIFont.Trim();
122122
}
@@ -240,13 +240,13 @@ public void Validate()
240240

241241
public bool TypewriterEnabled { get; set; } = DefaultTypewriterEnabled;
242242

243-
public List<char> TypewriterFullStopCharacters { get; set; } = DefaultTypewriterFullStopCharacters;
243+
public HashSet<string> TypewriterFullStops { get; set; } = DefaultTypewriterFullStops;
244244

245245
public long TypewriterFullStopDelay { get; set; } = DefaultTypewriterFullStopDelay;
246246

247247
public long TypewriterPartDelay { get; set; } = DefaultTypewriterPartDelay;
248248

249-
public List<char> TypewriterPauseCharacters { get; set; } = DefaultTypewriterPauseCharacters;
249+
public HashSet<string> TypewriterPauses { get; set; } = DefaultTypewriterPauses;
250250

251251
public long TypewriterPauseDelay { get; set; } = DefaultTypewriterPauseDelay;
252252

Intersect.Client.Core/Interface/Game/EventWindow.cs

Lines changed: 55 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,16 @@ public partial class EventWindow : Panel
3030
private readonly Panel _optionsPanel;
3131
private readonly Button[] _optionButtons = new Button[4];
3232

33-
private readonly Typewriter? _writer;
34-
private bool _isTypewriting;
33+
private readonly bool _typewriting;
3534
private readonly long _typewriterResponseDelay = ClientConfiguration.Instance.TypewriterResponseDelay;
35+
private readonly Typewriter? _writer;
3636

3737
private readonly Dialog _dialog;
3838

3939
private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(EventWindow))
4040
{
4141
_dialog = dialog;
4242
_defaultFont = GameContentManager.Current.GetFont(name: "sourcesansproblack", 12);
43-
_writer = Globals.Database.TypewriterBehavior == TypewriterBehavior.Off ? default : new Typewriter();
4443

4544
Alignment = [Alignments.Center];
4645
MinimumSize = new Point(520, 180);
@@ -159,7 +158,28 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
159158
// LoadJsonUi(GameContentManager.UI.InGame, Graphics.Renderer?.GetResolutionString());
160159

161160
SkipRender();
162-
ShowDialog();
161+
162+
_promptLabel.ClearText();
163+
_promptLabel.AddText(_dialog.Prompt ?? string.Empty, _promptTemplateLabel);
164+
_promptLabel.ForceImmediateRebuild();
165+
_ = _promptLabel.SizeToChildren();
166+
167+
_typewriting = ClientConfiguration.Instance.TypewriterEnabled &&
168+
Globals.Database.TypewriterBehavior != TypewriterBehavior.Off;
169+
if (_typewriting)
170+
{
171+
_promptLabel.ClearText();
172+
_writer = new Typewriter(_dialog.Prompt ?? string.Empty, text => _promptLabel.AppendText(text, _promptTemplateLabel));
173+
}
174+
175+
Defer(
176+
() =>
177+
{
178+
SizeToChildren(recursive: true);
179+
180+
_promptScroller.ScrollToTop();
181+
}
182+
);
163183

164184
MakeModal(dim: true);
165185
BringToFront();
@@ -185,41 +205,43 @@ public override void Dispose()
185205

186206
private void Update()
187207
{
188-
// Handle typewriting
189-
if (_isTypewriting && IsVisible)
208+
if (!IsVisible || !_typewriting)
190209
{
191-
var voiceIdx = Randomization.Next(0, ClientConfiguration.Instance.TypewriterSounds.Count);
210+
return;
211+
}
192212

193-
// Always show option 1 ("continue" if options empty)
194-
var writerCompleted = _writer?.IsDone ?? true;
195-
for (var optionIndex = 0; optionIndex < _optionButtons.Length; ++optionIndex)
196-
{
197-
var optionButton = _optionButtons[optionIndex];
198-
var optionText = _dialog?.Options[optionIndex];
199-
optionButton.IsVisible = writerCompleted && !string.IsNullOrEmpty(optionText);
200-
}
213+
if (_writer is null)
214+
{
215+
return;
216+
}
201217

202-
_writer?.Write(ClientConfiguration.Instance.TypewriterSounds.ElementAtOrDefault(voiceIdx));
203-
if (writerCompleted)
204-
{
205-
var disableResponse = _writer != default &&
206-
Timing.Global.MillisecondsUtc - _writer.DoneAtMilliseconds <
207-
_typewriterResponseDelay;
208-
foreach (var optionButton in _optionButtons)
209-
{
210-
optionButton.IsDisabled = disableResponse;
211-
}
212-
}
213-
else if (Controls.IsControlPressed(Control.AttackInteract))
214-
{
215-
SkipTypewriting();
216-
}
218+
var writerCompleted = _writer.IsDone;
217219

218-
return;
220+
foreach (var optionButton in _optionButtons)
221+
{
222+
optionButton.IsVisible = writerCompleted && !string.IsNullOrEmpty(optionButton.Text);
219223
}
220224

221-
_isTypewriting = ClientConfiguration.Instance.TypewriterEnabled &&
222-
Globals.Database.TypewriterBehavior == TypewriterBehavior.Word;
225+
if (writerCompleted)
226+
{
227+
var disableResponse = Timing.Global.MillisecondsUtc - _writer.DoneAtMilliseconds <
228+
_typewriterResponseDelay;
229+
foreach (var optionButton in _optionButtons)
230+
{
231+
optionButton.IsDisabled = disableResponse;
232+
}
233+
}
234+
else if (Controls.IsControlPressed(Control.AttackInteract))
235+
{
236+
SkipTypewriting();
237+
_promptScroller.ScrollToBottom();
238+
}
239+
else
240+
{
241+
var soundIndex = Randomization.Next(0, ClientConfiguration.Instance.TypewriterSounds.Count);
242+
_writer.Write(ClientConfiguration.Instance.TypewriterSounds.ElementAtOrDefault(soundIndex));
243+
_promptScroller.ScrollToBottom();
244+
}
223245
}
224246

225247
public static void ShowOrUpdateDialog(Canvas canvas)
@@ -239,33 +261,6 @@ public static void ShowOrUpdateDialog(Canvas canvas)
239261
_instance = new EventWindow(canvas, availableDialog);
240262
}
241263

242-
private void ShowDialog()
243-
{
244-
_promptLabel.ClearText();
245-
_promptLabel.AddText(_dialog?.Prompt ?? string.Empty, _promptTemplateLabel);
246-
247-
_ = _promptLabel.SizeToChildren();
248-
249-
// Do this _after_ sizing so we have lines broken up
250-
if (_isTypewriting)
251-
{
252-
_writer?.Initialize(_promptLabel.FormattedLabels);
253-
foreach (var button in _optionButtons)
254-
{
255-
button.Hide();
256-
}
257-
}
258-
259-
Defer(
260-
() =>
261-
{
262-
SizeToChildren(recursive: true);
263-
264-
_promptScroller.ScrollToTop();
265-
}
266-
);
267-
}
268-
269264
public void CloseEventResponse(EventResponseType response)
270265
{
271266
if (!(_writer?.IsDone ?? true))

0 commit comments

Comments
 (0)