mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 15:33:05 +08:00
Improved logic
This commit is contained in:
parent
585318400c
commit
949dc1c0f9
@ -172,7 +172,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestUndo()
|
public void TestUndoEditHistory()
|
||||||
{
|
{
|
||||||
SkinComponentsContainer firstTarget = null!;
|
SkinComponentsContainer firstTarget = null!;
|
||||||
TestSkinEditorChangeHandler changeHandler = null!;
|
TestSkinEditorChangeHandler changeHandler = null!;
|
||||||
@ -205,17 +205,28 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue));
|
revertAndCheckUnchanged();
|
||||||
AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState()));
|
|
||||||
|
AddStep("Move components", () =>
|
||||||
|
{
|
||||||
|
changeHandler.BeginChange();
|
||||||
|
testComponents.ForEach(c => ((Drawable)c).Position += Vector2.One);
|
||||||
|
changeHandler.EndChange();
|
||||||
|
});
|
||||||
|
revertAndCheckUnchanged();
|
||||||
|
|
||||||
AddStep("Select components", () => skinEditor.SelectedComponents.AddRange(testComponents));
|
AddStep("Select components", () => skinEditor.SelectedComponents.AddRange(testComponents));
|
||||||
AddStep("Bring to front", () => skinEditor.BringSelectionToFront());
|
AddStep("Bring to front", () => skinEditor.BringSelectionToFront());
|
||||||
AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue));
|
revertAndCheckUnchanged();
|
||||||
AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState()));
|
|
||||||
|
|
||||||
AddStep("Remove components", () => testComponents.ForEach(c => firstTarget.Remove(c, false)));
|
AddStep("Remove components", () => testComponents.ForEach(c => firstTarget.Remove(c, false)));
|
||||||
AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue));
|
revertAndCheckUnchanged();
|
||||||
AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState()));
|
|
||||||
|
void revertAndCheckUnchanged()
|
||||||
|
{
|
||||||
|
AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue));
|
||||||
|
AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(false)]
|
[TestCase(false)]
|
||||||
|
@ -60,49 +60,48 @@ namespace osu.Game.Overlays.SkinEditor
|
|||||||
SerialisedDrawableInfo[] skinnableInfos = deserializedContent.ToArray();
|
SerialisedDrawableInfo[] skinnableInfos = deserializedContent.ToArray();
|
||||||
ISerialisableDrawable[] targetComponents = firstTarget.Components.ToArray();
|
ISerialisableDrawable[] targetComponents = firstTarget.Components.ToArray();
|
||||||
|
|
||||||
// Store indexes based on type for later lookup
|
// Store components based on type for later lookup
|
||||||
|
var typedComponents = new Dictionary<Type, List<ISerialisableDrawable>>();
|
||||||
|
|
||||||
var targetComponentsIndexes = new Dictionary<Type, List<int>>();
|
foreach (var component in targetComponents)
|
||||||
|
|
||||||
for (int i = 0; i < targetComponents.Length; i++)
|
|
||||||
{
|
{
|
||||||
Type lookup = targetComponents[i].GetType();
|
Type lookup = component.GetType();
|
||||||
|
|
||||||
if (!targetComponentsIndexes.TryGetValue(lookup, out List<int>? componentIndexes))
|
if (!typedComponents.TryGetValue(lookup, out List<ISerialisableDrawable>? typeComponents))
|
||||||
targetComponentsIndexes.Add(lookup, componentIndexes = new List<int>());
|
typedComponents.Add(lookup, typeComponents = new List<ISerialisableDrawable>());
|
||||||
|
|
||||||
componentIndexes.Add(i);
|
typeComponents.Add(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
var indexCounting = new Dictionary<Type, int>();
|
// Remove all components
|
||||||
|
for (int i = targetComponents.Length - 1; i >= 0; i--)
|
||||||
|
firstTarget.Remove(targetComponents[i], false);
|
||||||
|
|
||||||
var empty = new List<int>(0);
|
// Keeps count of how many components for each type were already revived
|
||||||
|
Dictionary<Type, int> typedComponentCounter = typedComponents.Keys.ToDictionary(t => t, _ => 0);
|
||||||
|
|
||||||
for (int i = 0; i < skinnableInfos.Length; i++)
|
foreach (var skinnableInfo in skinnableInfos)
|
||||||
{
|
{
|
||||||
Type lookup = skinnableInfos[i].Type;
|
Type lookup = skinnableInfo.Type;
|
||||||
|
|
||||||
if (!targetComponentsIndexes.TryGetValue(lookup, out List<int>? componentIndexes))
|
if (!typedComponents.TryGetValue(lookup, out List<ISerialisableDrawable>? typeComponents))
|
||||||
componentIndexes = empty;
|
{
|
||||||
|
firstTarget.Add((ISerialisableDrawable)skinnableInfo.CreateInstance());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!indexCounting.ContainsKey(lookup))
|
int typeComponentsUsed = typedComponentCounter[lookup]++;
|
||||||
indexCounting.Add(lookup, 0);
|
|
||||||
|
|
||||||
if (i >= componentIndexes.Count)
|
ISerialisableDrawable component;
|
||||||
// Add new component
|
|
||||||
firstTarget.Add((ISerialisableDrawable)skinnableInfos[i].CreateInstance());
|
if (typeComponentsUsed < typeComponents.Count)
|
||||||
|
// Re-use unused component
|
||||||
|
((Drawable)(component = typeComponents[typeComponentsUsed])).ApplySerialisedInfo(skinnableInfo);
|
||||||
else
|
else
|
||||||
// Modify existing component
|
// Create new one
|
||||||
((Drawable)targetComponents[componentIndexes[indexCounting[lookup]++]]).ApplySerialisedInfo(skinnableInfos[i]);
|
component = (ISerialisableDrawable)skinnableInfo.CreateInstance();
|
||||||
}
|
|
||||||
|
|
||||||
foreach ((Type lookup, List<int> componentIndexes) in targetComponentsIndexes)
|
firstTarget.Add(component);
|
||||||
{
|
|
||||||
indexCounting.TryGetValue(lookup, out int i);
|
|
||||||
|
|
||||||
// Remove extra components that weren't removed above
|
|
||||||
for (; i < componentIndexes.Count; i++)
|
|
||||||
firstTarget.Remove(targetComponents[componentIndexes[i]], false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user