Skip to content

Commit

Permalink
refactor(Studio): Improve input merging behaviour
Browse files Browse the repository at this point in the history
Should now mimic v2's behaviour more closely
  • Loading branch information
psyGamer committed Sep 4, 2024
1 parent 17be03b commit e9194b2
Showing 1 changed file with 64 additions and 58 deletions.
122 changes: 64 additions & 58 deletions Studio/CelesteStudio/Editing/ContextActions/CombineInputFrames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,21 @@ public class CombineConsecutiveSameInputs : ContextAction {
}

public static bool CombineInputs(bool sameActions, bool dryRun = false) {
using var __ = Document.Update();
using var __ = Document.Update(raiseEvents: !dryRun);

bool hasChanges = false;

if (Document.Selection.Empty) {
// Merge current input with surrounding inputs
int curr = Document.Caret.Row;
if (!Editor.TryParseAndFormatActionLine(curr, out var currActionLine)) {
if (!ActionLine.TryParse(Document.Lines[curr], out var currActionLine)) {
return false;
}

// Above
int above = curr - 1;
for (; above >= 0; above--) {
if (!Editor.TryParseAndFormatActionLine(above, out var otherActionLine)) {
if (!ActionLine.TryParse(Document.Lines[above], out var otherActionLine)) {
break;
}

Expand All @@ -81,7 +81,7 @@ public static bool CombineInputs(bool sameActions, bool dryRun = false) {
// Below
int below = curr + 1;
for (; below < Document.Lines.Count; below++) {
if (!Editor.TryParseAndFormatActionLine(below, out var otherActionLine)) {
if (!ActionLine.TryParse(Document.Lines[below], out var otherActionLine)) {
break;
}

Expand Down Expand Up @@ -113,73 +113,79 @@ public static bool CombineInputs(bool sameActions, bool dryRun = false) {
int minRow = Document.Selection.Min.Row;
int maxRow = Document.Selection.Max.Row;

ActionLine? activeActionLine = null;
int activeRowStart = -1;
ActionLine? forceMergeTarget = null;
ActionLine? currentActionLine = null;
int currentActionLineRow = -1;

for (int row = minRow; row <= maxRow; row++) {
if (string.IsNullOrWhiteSpace(Document.Lines[row])) {
continue;
}
if (!Editor.TryParseAndFormatActionLine(row, out var currActionLine)) {
// "Flush" the previous lines
if (activeActionLine != null) {
Document.RemoveLines(activeRowStart, row - 1);
Document.InsertLine(activeRowStart, activeActionLine.Value.ToString());

maxRow -= row - 1 - activeRowStart;
row = activeRowStart + 1;

activeActionLine = null;
activeRowStart = -1;
if (!sameActions) {
// The algorithm goes backwards, but the target actions are the first valid line forwards
for (int row = minRow; row >= maxRow; row++) {
if (ActionLine.TryParse(Document.Lines[row], out var nextActionLine)) {
forceMergeTarget = nextActionLine;
break;
}
continue; // Skip non-input lines
}

if (activeActionLine == null) {
activeActionLine = currActionLine;
activeRowStart = row;
continue;
}

if (!sameActions) {
// Just merge them, regardless if they are the same actions
activeActionLine = activeActionLine.Value with { FrameCount = activeActionLine.Value.FrameCount + currActionLine.FrameCount };
hasChanges = true;
continue;
if (forceMergeTarget == null) {
return false;
}
}

if (currActionLine.Actions == activeActionLine.Value.Actions &&
currActionLine.FeatherAngle == activeActionLine.Value.FeatherAngle &&
currActionLine.FeatherMagnitude == activeActionLine.Value.FeatherMagnitude &&
!IsScreenTransition(row))
{
activeActionLine = activeActionLine.Value with { FrameCount = activeActionLine.Value.FrameCount + currActionLine.FrameCount };
hasChanges = true;
for (int row = maxRow; row >= minRow; row--) {
if (string.IsNullOrWhiteSpace(Document.Lines[row])) {
continue;
}

if (!dryRun) {
// Current line is different, so change the active one
Document.RemoveLines(activeRowStart, row - 1);
Document.InsertLine(activeRowStart, activeActionLine.Value.ToString());
}

activeActionLine = currActionLine;
activeRowStart++;
var nextActionLine = ActionLine.Parse(Document.Lines[row]);
if (nextActionLine != null) {
if (currentActionLine == null) {
currentActionLine = nextActionLine;
currentActionLineRow = row;
continue;
}

// Account for changed line counts
maxRow -= row - activeRowStart;
row = activeRowStart;
}
if (!sameActions) {
// Just merge them, regardless if they are the same actions
currentActionLine = forceMergeTarget!.Value with {
FrameCount = currentActionLine.Value.FrameCount + nextActionLine.Value.FrameCount
};
if (!dryRun) {
Document.RemoveLines(row + 1, currentActionLineRow);
Document.ReplaceLine(row, currentActionLine.Value.ToString());
maxRow -= currentActionLineRow - row;
}

currentActionLineRow = row;
hasChanges = true;

continue;
}

// "Flush" the remaining line
if (activeActionLine != null) {
if (!dryRun) {
Document.RemoveLines(activeRowStart, maxRow);
Document.InsertLine(activeRowStart, activeActionLine.Value.ToString());
if (currentActionLine.Value.Actions == nextActionLine.Value.Actions &&
currentActionLine.Value.FeatherAngle == nextActionLine.Value.FeatherAngle &&
currentActionLine.Value.FeatherMagnitude == nextActionLine.Value.FeatherMagnitude &&
!IsScreenTransition(row))
{
// Merge them, if they are the same kind
currentActionLine = currentActionLine.Value with {
FrameCount = currentActionLine.Value.FrameCount + nextActionLine.Value.FrameCount
};
if (!dryRun) {
Document.RemoveLines(row + 1, currentActionLineRow);
Document.ReplaceLine(row, currentActionLine.Value.ToString());
maxRow -= currentActionLineRow - row;
}

currentActionLineRow = row;
hasChanges = true;

continue;
}
}

maxRow = activeRowStart;
// Prevent merges over commands, comments, etc.
currentActionLine = nextActionLine;
currentActionLineRow = row;
}

if (!dryRun) {
Expand Down

0 comments on commit e9194b2

Please sign in to comment.