1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 10:52:53 +08:00

Handle automapper realm cyclic references via AfterMaps

This may not be the cleanest solution, but there don't seem to be any
way towards this either.

- `UseDestinationValue` has been inherited by default as noted in
https://docs.automapper.org/en/stable/10.0-Upgrade-Guide.html#usedestinationvalue-is-now-inherited-by-default, and its behaviour in this case would be using the nested **managed** realm object for the destination member rather than creating an unmanaged version.

- `MaxDepth` already sets `PreserveReferences` so there's no point of using it.

- `MaxDepth` should probably not be set for all maps, only for those with
cyclic references, to avoid the expensive overhead of `PreserveReferences`, as mentioned in https://docs.automapper.org/en/stable/5.0-Upgrade-Guide.html#circular-references.

That aside, `MaxDepth` should actually only be set to `1` for
`BeatmapSetInfo` mapping, because we don't want AutoMapper to create a
nested instance of `BeatmapSetInfo` in each mapped/detached beatmap, but
for some reason, doing that will cause automapper to not map any beatmap
inside the set and leave it with 0 beatmaps.

While on the other hand, using `MaxDepth(2)` for `BeatmapSetInfo` works,
but creates an unused instance of a `BeatmapSetInfo` inside each mapped
beatmap, which may not be ideal.

For `BeatmapInfo`, it has to be `MaxDepth(2)`, in which the first
`BeatmapInfo` depth would be itself (when detaching a beatmap), and the
second would be nested beatmaps inside the mapped/detached
`BeatmapSetInfo` within the beatmap. (note that when detaching a beatmap
set, the unused instance of `BeatmapSetInfo` within each beatmap of that
beatmap set doesn't also have a list of unused beatmaps as one might expect from the depth specification, it surprisingly has 0 beatmaps)

This causes it to create an unused instance of `BeatmapInfo` in the beatmap set resembling the root mapped/detached beatmap, but that one might be inevitable.
This commit is contained in:
Salman Ahmed 2022-01-12 00:32:32 +03:00 committed by Dean Herbert
parent dc3730f334
commit 6db3c32dd1

View File

@ -34,15 +34,23 @@ namespace osu.Game.Database
c.CreateMap<RealmUser, RealmUser>();
c.CreateMap<RealmFile, RealmFile>();
c.CreateMap<RealmNamedFileUsage, RealmNamedFileUsage>();
c.CreateMap<BeatmapInfo, BeatmapInfo>();
c.CreateMap<BeatmapSetInfo, BeatmapSetInfo>();
c.AddGlobalIgnore(nameof(RealmObjectBase.ObjectSchema));
c.ForAllMaps((a, b) =>
c.CreateMap<BeatmapInfo, BeatmapInfo>().MaxDepth(2).AfterMap((s, d) =>
{
b.PreserveReferences();
b.MaxDepth(2);
for (int i = 0; i < d.BeatmapSet?.Beatmaps.Count; i++)
{
if (d.BeatmapSet.Beatmaps[i].Equals(d))
{
d.BeatmapSet.Beatmaps[i] = d;
break;
}
}
});
c.CreateMap<BeatmapSetInfo, BeatmapSetInfo>().MaxDepth(2).AfterMap((s, d) =>
{
foreach (var beatmap in d.Beatmaps)
beatmap.BeatmapSet = d;
});
c.AddGlobalIgnore(nameof(RealmObjectBase.ObjectSchema));
}).CreateMapper();
private static readonly IMapper read_mapper = new MapperConfiguration(c =>
@ -60,15 +68,23 @@ namespace osu.Game.Database
c.CreateMap<RealmUser, RealmUser>();
c.CreateMap<RealmFile, RealmFile>();
c.CreateMap<RealmNamedFileUsage, RealmNamedFileUsage>();
c.CreateMap<BeatmapInfo, BeatmapInfo>();
c.CreateMap<BeatmapSetInfo, BeatmapSetInfo>();
c.AddGlobalIgnore(nameof(RealmObjectBase.ObjectSchema));
c.ForAllMaps((a, b) =>
c.CreateMap<BeatmapInfo, BeatmapInfo>().MaxDepth(2).AfterMap((s, d) =>
{
b.PreserveReferences();
b.MaxDepth(2);
for (int i = 0; i < d.BeatmapSet?.Beatmaps.Count; i++)
{
if (d.BeatmapSet.Beatmaps[i].Equals(d))
{
d.BeatmapSet.Beatmaps[i] = d;
break;
}
}
});
c.CreateMap<BeatmapSetInfo, BeatmapSetInfo>().MaxDepth(2).AfterMap((s, d) =>
{
foreach (var beatmap in d.Beatmaps)
beatmap.BeatmapSet = d;
});
c.AddGlobalIgnore(nameof(RealmObjectBase.ObjectSchema));
}).CreateMapper();
/// <summary>