Carry one immutable prepared collision closure with each accepted near-tier generation and install graph plus flat views through the same retained publication receipt. Apply the same strict package-only rule to live entities, add exact sampled graph-authoritative comparison artifacts and lifecycle counters, and prove cancellation, demotion, rehydrate, revisit, teardown, reconnect, and the nine-stop route with 14,064 zero-mismatch samples. Co-authored-by: OpenAI Codex <codex@openai.com>
68 lines
2.2 KiB
C#
68 lines
2.2 KiB
C#
using AcDream.Content;
|
|
using AcDream.Core.Physics;
|
|
using DatReaderWriter.DBObjs;
|
|
|
|
namespace AcDream.App.Physics;
|
|
|
|
/// <summary>
|
|
/// Publishes the graph and prepared collision views for DAT objects discovered
|
|
/// through the live-object path. Streamed statics carry their prepared closure
|
|
/// on <c>LandblockBuild</c>; live CreateObject/appearance data arrives outside
|
|
/// that transaction and therefore uses this matching strict publisher.
|
|
/// </summary>
|
|
internal sealed class LiveCollisionAssetPublisher
|
|
{
|
|
private readonly PhysicsDataCache _cache;
|
|
private readonly IPreparedCollisionSource _source;
|
|
|
|
public LiveCollisionAssetPublisher(
|
|
PhysicsDataCache cache,
|
|
IPreparedCollisionSource source)
|
|
{
|
|
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
|
|
_source = source ?? throw new ArgumentNullException(nameof(source));
|
|
}
|
|
|
|
public void CacheGfxObj(uint id, GfxObj gfxObj)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(gfxObj);
|
|
FlatGfxObjCollisionAsset? prepared =
|
|
_cache.GetFlatGfxObj(id) is not null
|
|
? null
|
|
: Require(
|
|
_source.ReadGfxObjCollision(id),
|
|
"GfxObj collision",
|
|
id);
|
|
_cache.CacheGfxObj(id, gfxObj, prepared);
|
|
}
|
|
|
|
public void CacheSetup(uint id, Setup setup)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(setup);
|
|
FlatSetupCollision? prepared =
|
|
_cache.GetFlatSetup(id) is not null
|
|
? null
|
|
: Require(
|
|
_source.ReadSetupCollision(id),
|
|
"Setup collision",
|
|
id);
|
|
_cache.CacheSetup(id, setup, prepared);
|
|
}
|
|
|
|
private static T Require<T>(
|
|
PreparedCollisionReadResult<T> result,
|
|
string kind,
|
|
uint id)
|
|
where T : class
|
|
{
|
|
if (result.Status == PreparedAssetReadStatus.Loaded &&
|
|
result.Data is not null)
|
|
{
|
|
return result.Data;
|
|
}
|
|
|
|
throw new InvalidDataException(
|
|
$"{kind} 0x{id:X8} is {result.Status}. " +
|
|
"Live collision cannot publish only one representation.");
|
|
}
|
|
}
|