fix(physics): seal collision generations before activation
This commit is contained in:
parent
be94bc9b06
commit
d94145e6b8
15 changed files with 1556 additions and 410 deletions
|
|
@ -25,19 +25,25 @@ The asynchronous unit is now one Runtime-owned collision generation:
|
|||
GfxObj/Setup catalogs are not copied; the accepted build's exact closure is
|
||||
populated by the existing cursors.
|
||||
3. App and Headless publish terrain, EnvCells, topology, buildings, prepared
|
||||
collision assets, static owners, and retained dynamic-owner cell sets only
|
||||
into that private generation.
|
||||
4. Each dynamic owner refresh captures its exact `ShadowObjectRegistry`
|
||||
mutation version. Movement, state/payload change, spawn, suspension, or
|
||||
deletion changes that version.
|
||||
5. `CommitCollisionGeneration` validates the admission, exact affected-owner
|
||||
set, and all captured versions. If any owner is dirty, it returns the sorted
|
||||
dirty IDs without touching the active world; App advances those IDs through
|
||||
its existing work meter and retries.
|
||||
6. Once fresh, Runtime precomputes the replacement arrays and synchronously
|
||||
replaces the landblock's cache/graph/engine/building/static and dynamic
|
||||
shadow state on the same update thread. Only after the complete replacement
|
||||
does it emit `CollisionGenerationCommitted` and a ready acknowledgement.
|
||||
collision assets, and target-root static owners only into that private
|
||||
generation.
|
||||
4. A mutation-stable cursor captures every non-suspended owner that touches —
|
||||
or has a withdrawn repair marker for — the target prefix. That includes
|
||||
live dynamic owners and statics rooted in an adjacent landblock. Only a
|
||||
target-root static is omitted, because the authored replacement supersedes
|
||||
it. Each retained owner refresh captures its exact
|
||||
`ShadowObjectRegistry` mutation version; a rowless withdrawn owner therefore
|
||||
remains freshness-gated when state or payload changes.
|
||||
5. Explicit one-work-unit cursors build the complete replacement before the
|
||||
activation frame: requested global collision records, cells/topology,
|
||||
buildings, cell graph removals, affected static owners, retained-owner
|
||||
states, and removal lists. An active-owner mutation restarts capture and
|
||||
sealing without touching the active world.
|
||||
6. `CommitCollisionGeneration` performs only the final mutation-version check
|
||||
and installs the already sealed replacement synchronously on the update
|
||||
thread. The dense 256-owner gate measures zero managed bytes in this final
|
||||
activation. Only after the complete replacement does Runtime emit
|
||||
`CollisionGenerationCommitted` and a ready acknowledgement.
|
||||
|
||||
The stable borrowed `PhysicsEngine` and `PhysicsDataCache` object identities do
|
||||
not change. Presentation and no-window hosts use the same Runtime transaction.
|
||||
|
|
@ -47,6 +53,9 @@ shadow state.
|
|||
## Failure and lifetime rules
|
||||
|
||||
- A newer admission invalidates an older prepared generation.
|
||||
- Cancellation names one admission and its private staging generation. It can
|
||||
never withdraw or demote the active landblock, and cancelling a stale receipt
|
||||
cannot invalidate a newer admission.
|
||||
- Demotion, withdrawal, reset, and disposal invalidate the admission before
|
||||
changing the active generation.
|
||||
- Disposing a stale/cancelled prepared generation clears only its private
|
||||
|
|
@ -64,7 +73,15 @@ The focused Runtime/App tests pin:
|
|||
- stale admission replacement has no active-world side effect;
|
||||
- movement during staging rejects, refreshes only the dirty owner, and then
|
||||
installs its latest cell set;
|
||||
- an authoritative state change on a retained rowless owner rejects a stale
|
||||
seal and installs the refreshed state on retry;
|
||||
- a neighboring static whose shadow crossed the seam is restored atomically
|
||||
on reload and its withdrawn-prefix marker clears only at activation;
|
||||
- spawn and deletion during staging both reject stale activation;
|
||||
- Headless faults immediately after admission and after staging preserve the
|
||||
prior complete world and leave no collision admission behind;
|
||||
- dense sealing consumes at most one work unit per call, while its final
|
||||
256-owner activation allocates zero managed bytes;
|
||||
- graphical and no-window publishers use the same Runtime transaction;
|
||||
- removal and terminal teardown converge the active ownership ledger.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue