feat(headless): hydrate isolated collision worlds
This commit is contained in:
parent
9569dadb57
commit
b6547ff38c
20 changed files with 1960 additions and 101 deletions
|
|
@ -1,5 +1,7 @@
|
|||
using System.Collections.Immutable;
|
||||
using AcDream.Content;
|
||||
using AcDream.Headless.Configuration;
|
||||
using DatReaderWriter.DBObjs;
|
||||
|
||||
namespace AcDream.Headless.Hosting;
|
||||
|
||||
|
|
@ -25,7 +27,8 @@ internal interface IHeadlessProcessContentFactory
|
|||
internal sealed record HeadlessOpenedProcessContent(
|
||||
IDatReaderWriter Dats,
|
||||
IPreparedAssetSource Prepared,
|
||||
MagicCatalog Magic);
|
||||
MagicCatalog Magic,
|
||||
ImmutableArray<float> HeightTable);
|
||||
|
||||
internal sealed class ProductionHeadlessProcessContentFactory
|
||||
: IHeadlessProcessContentFactory
|
||||
|
|
@ -50,10 +53,24 @@ internal sealed class ProductionHeadlessProcessContentFactory
|
|||
dats,
|
||||
diagnostic);
|
||||
MagicCatalog magic = MagicCatalog.Load(dats);
|
||||
Region region = dats.Get<Region>(0x13000000u)
|
||||
?? throw new InvalidOperationException(
|
||||
"Region dat id 0x13000000 is missing.");
|
||||
float[]? sourceHeightTable =
|
||||
region.LandDefs.LandHeightTable;
|
||||
if (sourceHeightTable is null
|
||||
|| sourceHeightTable.Length < 256)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Region.LandDefs.LandHeightTable is missing or truncated.");
|
||||
}
|
||||
ImmutableArray<float> heightTable =
|
||||
ImmutableArray.CreateRange(sourceHeightTable);
|
||||
return new HeadlessOpenedProcessContent(
|
||||
dats,
|
||||
prepared,
|
||||
magic);
|
||||
magic,
|
||||
heightTable);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -80,6 +97,7 @@ internal sealed class HeadlessProcessContentOwner : IDisposable
|
|||
{
|
||||
private readonly object _gate = new();
|
||||
private readonly MagicCatalog _magic;
|
||||
private readonly ImmutableArray<float> _heightTable;
|
||||
private IDatReaderWriter? _dats;
|
||||
private IPreparedAssetSource? _prepared;
|
||||
private SharedPreparedCollisionCache? _collision;
|
||||
|
|
@ -105,8 +123,13 @@ internal sealed class HeadlessProcessContentOwner : IDisposable
|
|||
IDatReaderWriter? dats = opened.Dats;
|
||||
IPreparedAssetSource? prepared = opened.Prepared;
|
||||
MagicCatalog? magic = opened.Magic;
|
||||
ImmutableArray<float> heightTable = opened.HeightTable;
|
||||
bool incomplete =
|
||||
dats is null || prepared is null || magic is null;
|
||||
dats is null
|
||||
|| prepared is null
|
||||
|| magic is null
|
||||
|| heightTable.IsDefaultOrEmpty
|
||||
|| heightTable.Length < 256;
|
||||
if (incomplete || prepared is not IPreparedCollisionSource)
|
||||
{
|
||||
try
|
||||
|
|
@ -127,6 +150,7 @@ internal sealed class HeadlessProcessContentOwner : IDisposable
|
|||
_dats = dats!;
|
||||
_prepared = prepared!;
|
||||
_magic = magic!;
|
||||
_heightTable = heightTable;
|
||||
_collision = new SharedPreparedCollisionCache(
|
||||
(IPreparedCollisionSource)prepared!);
|
||||
}
|
||||
|
|
@ -149,7 +173,8 @@ internal sealed class HeadlessProcessContentOwner : IDisposable
|
|||
_dats!,
|
||||
_prepared!,
|
||||
_collision!,
|
||||
_magic);
|
||||
_magic,
|
||||
_heightTable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,6 +245,7 @@ internal sealed class HeadlessProcessContentOwner : IDisposable
|
|||
private readonly IPreparedAssetSource _prepared;
|
||||
private readonly IPreparedCollisionSource _collision;
|
||||
private readonly MagicCatalog _magic;
|
||||
private readonly ImmutableArray<float> _heightTable;
|
||||
|
||||
internal HeadlessProcessContentLease(
|
||||
HeadlessProcessContentOwner owner,
|
||||
|
|
@ -227,7 +253,8 @@ internal sealed class HeadlessProcessContentOwner : IDisposable
|
|||
IDatReaderWriter dats,
|
||||
IPreparedAssetSource prepared,
|
||||
IPreparedCollisionSource collision,
|
||||
MagicCatalog magic)
|
||||
MagicCatalog magic,
|
||||
ImmutableArray<float> heightTable)
|
||||
{
|
||||
_owner = owner;
|
||||
SessionId = sessionId;
|
||||
|
|
@ -235,6 +262,7 @@ internal sealed class HeadlessProcessContentOwner : IDisposable
|
|||
_prepared = prepared;
|
||||
_collision = collision;
|
||||
_magic = magic;
|
||||
_heightTable = heightTable;
|
||||
}
|
||||
|
||||
internal string SessionId { get; }
|
||||
|
|
@ -275,6 +303,15 @@ internal sealed class HeadlessProcessContentOwner : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
internal ImmutableArray<float> HeightTable
|
||||
{
|
||||
get
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_owner is null, this);
|
||||
return _heightTable;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
HeadlessProcessContentOwner? owner =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue