Skip to content

Commit 96c1845

Browse files
Seperation of system instructions and prompt, playback safety and fix deadlock while marking broken elements of broken XML
- Prompt and system instructions are seperated and now sent through GenerativeAI.SystemInstruction. - Playback safety is ensured by preventing playing music if a note is already playing. - Deadlock issue in marking broken elements in AI generated NBPML error window.
2 parents 0737b5f + 8f42cda commit 96c1845

1 file changed

Lines changed: 45 additions & 43 deletions

File tree

NeoBleeper/AIGeneratedNBPMLError.cs

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -115,63 +115,65 @@ private void AIGeneratedNBPMLError_SystemColorsChanged(object sender, EventArgs
115115
}
116116

117117
/// <summary>
118-
/// Parses the specified XML string, displays it in a RichTextBox, and highlights the first character where a
118+
/// Parses the specified XML string, displays it in a RichTextBox, and highlights the entire tag where a
119119
/// parsing error occurs.
120120
/// </summary>
121121
/// <remarks>This method visually distinguishes the first XML parsing error by highlighting the
122-
/// corresponding character in the RichTextBox. Only the first error encountered is highlighted; subsequent
122+
/// entire tag containing the error in the RichTextBox. Only the first error encountered is highlighted; subsequent
123123
/// errors are not marked. The method does not modify the input string.</remarks>
124-
/// <param name="brokenXML">The XML string to display and analyze for errors. If the string contains invalid XML, the first problematic
124+
/// <param name="brokenXML">The XML string to display and analyze for errors. If the string contains invalid XML, the entire tag with the first problematic
125125
/// character will be highlighted.</param>
126126
private void WriteToRichTextBoxAndHighlightError(string brokenXML)
127127
{
128128
// Collect parts of the XML with error info
129129
List<(string text, bool isError)> parts = new();
130130
string xml = brokenXML;
131-
int offset = 0;
132131

133-
while (!string.IsNullOrEmpty(xml))
132+
try
134133
{
135-
try
136-
{
137-
// Try to parse the 'broken' XML
138-
var doc = new XmlDocument();
139-
doc.LoadXml(xml);
140-
// If successful, add the remaining part and exit
141-
parts.Add((xml, false));
142-
break;
143-
}
144-
catch (XmlException ex)
145-
{
146-
// Find error position
147-
int line = ex.LineNumber;
148-
int pos = ex.LinePosition;
149-
150-
// Find character index in the string
151-
int charIndex = 0;
152-
string[] lines = xml.Split('\n');
153-
for (int i = 0; i < line - 1 && i < lines.Length; i++)
154-
charIndex += lines[i].Length + 1;
155-
charIndex += pos - 1;
156-
157-
// Seperate the string into parts
158-
string before = xml.Substring(0, Math.Min(charIndex, xml.Length));
159-
string errorChar = (charIndex < xml.Length) ? xml.Substring(charIndex, 1) : "";
160-
string after = (charIndex + 1 < xml.Length) ? xml.Substring(charIndex + 1) : "";
161-
162-
if (!string.IsNullOrEmpty(before))
163-
parts.Add((before, false));
164-
if (!string.IsNullOrEmpty(errorChar))
165-
parts.Add((errorChar, true));
166-
167-
// Retry with the remaining string
168-
xml = after;
169-
offset += charIndex + 1;
170-
}
134+
// Try to parse the entire XML
135+
var doc = new XmlDocument();
136+
doc.LoadXml(xml);
137+
// If successful, add the entire string as normal
138+
parts.Add((xml, false));
139+
}
140+
catch (XmlException ex)
141+
{
142+
// Find error position
143+
int line = ex.LineNumber;
144+
int pos = ex.LinePosition;
145+
146+
// Find character index in the string
147+
int charIndex = 0;
148+
string[] lines = xml.Split('\n');
149+
for (int i = 0; i < line - 1 && i < lines.Length; i++)
150+
charIndex += lines[i].Length + 1;
151+
charIndex += pos - 1;
152+
153+
// Find the start of the tag (last '<' before error)
154+
int tagStart = xml.LastIndexOf('<', charIndex);
155+
if (tagStart == -1) tagStart = 0;
156+
157+
// Find the end of the tag (next '>' after error)
158+
int tagEnd = xml.IndexOf('>', charIndex);
159+
if (tagEnd == -1) tagEnd = xml.Length;
160+
else tagEnd += 1; // Include the '>'
161+
162+
// Separate the string into parts: before tag (normal), tag (highlighted), after tag (normal)
163+
string before = xml.Substring(0, tagStart);
164+
string errorTag = xml.Substring(tagStart, tagEnd - tagStart);
165+
string after = (tagEnd < xml.Length) ? xml.Substring(tagEnd) : "";
166+
167+
if (!string.IsNullOrEmpty(before))
168+
parts.Add((before, false));
169+
if (!string.IsNullOrEmpty(errorTag))
170+
parts.Add((errorTag, true));
171+
if (!string.IsNullOrEmpty(after))
172+
parts.Add((after, false));
171173
}
172174

173-
// Create RTF content with highlights
174-
string EscapeRtf(string s) => s.Replace(@"\", @"\\").Replace("{", @"\{").Replace("}", @"\}");
175+
// Create RTF content with highlights and proper newline handling
176+
string EscapeRtf(string s) => s.Replace(@"\", @"\\").Replace("{", @"\{").Replace("}", @"\}").Replace("\n", "\\line ");
175177
var rtf = @"{\rtf1\ansi{\colortbl ;\red255\green255\blue255;\red255\green0\blue0;}";
176178
foreach (var part in parts)
177179
{

0 commit comments

Comments
 (0)