Skip to content

perf(scene): resolve property references through the owning identity scope #54

Closed

Description

@FLwolfy

Verified on branch / awaiting merge

Production implementation: dd5979c613b0fe8ebd9f7026f25001ceee9f8cee. Delivered head: dbae93e8f211d45a69cdffdb6afa3a33a0af0fa5; the subsequent diff contains documentation/acceptance evidence only. Exact-head CI: Engine CI and NuGet dependency graph passed; all six checks on this exact head are successful. All applicable acceptance conditions for this issue are verified; unavailable physical/manual device checks are explicitly scoped, not reported passed.

Owner: Scene property reference scope through exact Core allocator. Implementation commits: e5268920, 163c1938.

Evidence: complete report, exact-head delivery attachment, portable test-case/raw-measurement/requirement indexes linked by the report. Specific proof: Scene67: current/stale/foreign/wrong-kind/alias/throw/nested scopes and canonical graph behavior; Actual SceneEdits History continuous-input comparison; Formal companion SDK/IDE and complete products/CI.

Commands: official tests/Invoke-EditorUiAcceptance.ps1 Contracts/Workflows/Visual/Lifecycle/Products with SDK-selected independent outputs; complete source/entry preparation; formal InnoEngine.Build scripts --ide for the three companions; tests/Invoke-WikiChecks.ps1; controlled public performance fixtures where applicable. The report records original command owners, TRX/binlogs, negative tests, failures, skips, input hashes and device limits.

Profiles overlap; do not sum their pass counts into a distinct-test claim. Windows-only sharing fixtures and Unix-only filesystem fixtures are scoped to the executing host. Real native contexts/simulated display metrics and hidden product feature journeys are not a claim of physical display, OS IME or manual Mac testing. No BGCS/vendor/package/generated-binding modification, parallel Core system, test hook, IVT or private reflection was used.

Keep this issue Open. PR #26 includes an individual Fixes #54 and will close it only when the user merges to master. No automatic merge or premature master-resolution claim.

Original defect, ownership and accepted work

The following baseline observations describe the issue as opened. The verification above supersedes intermediate pending checkpoints; original failed/negative logs remain preserved. Acceptance checkboxes are checked only after the exact delivery-head verification completes.

Approved-plan mapping

Parent #27; required by E08 #35, E11 #38 and the complete editing work in #46. This is a newly confirmed remaining cost in the real Scene edit path, rather than another public capture-key capability.

Confirmed facts and evidence

The new LargeViewsMeasureActualInputAndContinuousEditWork preflight passes on both current and historical producers. Current 10,000-object continuous edits still allocate about 12.77 MB and take approximately 92 ms per complete edit/drawn operation under concurrent load. These timings are not controlled acceptance and do not establish exact attribution.

Source inspection independently confirms that every ScenePropertySerialization.CapturePropertySnapshots builds a list of every object/component/system, a complete object-to-ID dictionary and a complete ID-to-object dictionary. SceneEdits.ChangeProperty legitimately captures before and after, so a scalar edit pays this whole-scene reference setup twice even when no object reference is serialized. The IDs in this property map are exactly Core persistent identities.

The scalar/keyed dirty-inspection improvement alone therefore does not close the actual editing path. Do not skip related-property snapshots or setter side effects to reduce its cost.

Ownership and design

Keep reference tokens and public APIs unchanged. Core Identity remains the live object authority. Scene owns same-scene reference semantics; full graph/subtree/prefab serialization owns its frozen local-ID maps.

Separate these two current responsibilities behind one internal Scene reference scope:

  • The existing frozen graph map keeps its subset/local-ID/alias behavior for graph construction, prefab, reload and subtree operations.
  • Single-property/element editing resolves actual references through the owning Core allocator when needed and validates domain, registration, generation, kind, type and Scene ownership. It does not enumerate or index the entire Scene.
  • Property restore aliases remain a frozen neutral Guid-to-Guid overlay, validated through Core. They never become a second live-object registry.

Reuse the existing scoped execution slot. No public resolver API, global cache, revision service, event bus, serializer, pool, compatibility overload or platform branch is needed. Keep the complete asset/serialization context.

Implementation files

src/content/scene/Inno.Scene/Serialization/
  SceneGraph/
    SceneReferenceScope.cs             # shared scoped token and reference protocol
    SceneGraphReferenceMap.cs          # existing frozen graph/local-ID mapping
    ScenePropertyReferenceScope.cs     # current Scene property binding via Core Identity
  ScenePropertySerialization.cs
  SerializedPropertyValueCodec.cs
  Converters/{GameObjectConverter,GameComponentReferenceConverter,GameSystemReferenceConverter}.cs
  PrefabOverrideProcessor.cs
tests/scene/Inno.Scene.Tests/
  ScenePropertyReferenceTests.cs
tests/editor/Inno.Editor.PlayMode.Tests/
  LargePanelPerformanceTests.Input.cs
docs/scene/Inno.Scene.md
docs/architecture/IDENTITY_REFERENCE_RELOAD_STANDARD.md
records/architecture/EDITOR_UI_CLOSURE_PLAN.md

Adjust exact file placement to the existing owners; do not create a new project or public facade.

Failure and lifecycle semantics

The property scope is synchronous and owner-thread bound. It must resolve current live references through the correct Core domain, reject destroyed/detached/cross-scene/cross-domain targets and never retain plugin objects after the operation. Frozen graph construction retains its separate, necessary frozen-ID boundary. Getter/converter/restore failures leave the surrounding scope and existing rollback owner intact. Missing/alias recovery must preserve payloads, identity and barriers.

Acceptance

  • Scalar before/after captures and restores do not construct whole-scene live-reference dictionaries.
  • Ordinary object/component/system and asset references round-trip through the owning Core authority; same persistent identity replacement resolves the current valid object.
  • Cross-scene/domain, stale, destroyed/detached, wrong-kind/type, invalid/colliding alias and missing-target cases reject explicitly without publishing invalid results.
  • Full graph/subtree/prefab/reload local IDs, external-reference rejection and recovery remain unchanged.
  • Nested scopes and throwing getters/converters restore the original scope; retained neutral results do not pin retired ALCs.
  • Existing Core/Scene/History/Missing/Play/reload and actual product workflows pass.
  • Five controlled continuous-edit process pairs retain all work/count/CPU/allocation/GC data. Compare against the unchanged historical producer and the recorded pre-correction current case; do not substitute scalar direct writes for the actual History path.
  • XML/Wiki/architecture, formal compiler consumers and final exact-head CI pass; BGCS/vendor/packages/generated bindings remain untouched.

Keep Open until complete branch verification. Add an individual Fixes line to PR #26 only after all applicable gates pass; close on merge, without automatic merging.

Activity

  1. FLwolfy commented on Oct 29, 2026

    @FLwolfy
    MemberAuthor

    The isolated Scene implementation now passes all 56 existing cases plus five new public-boundary regressions (61 total): allocation independence from unrelated objects, current object/component/system restoration after identity replacement, foreign Scene/domain rejection, destroyed/missing targets, and nested/throwing getter scope restoration. An independent test-owned runtime using the officially built pre-correction Scene producer fails the same allocation contract: ten captures allocate 56,480 bytes in a small Scene versus 26,823,728 bytes with 5,000 unrelated objects. The new implementation passes the unchanged small-plus-64-KiB bound. No shared output, package or generated file was altered for that negative test. Further kind/alias/asset and full History/product/quantitative gates remain open. The main candidate is kept fixed while its complete suite runs; this correction is isolated until its own boundary checks finish.

  2. FLwolfy commented on Oct 29, 2026

    @FLwolfy
    MemberAuthor

    The isolated correction now passes 66 Scene cases (56 existing plus ten new), including valid current-envelope alias round-trip, alias redirection, collisions, missing/malformed aliases, an invalid reference-kind payload, wrong current component type, canonical Asset resolver identity, nested/throwing getters, foreign domains/Scenes, replacement and allocation bounds. Invalid input fixtures use the ordinary public serializer and validated current envelopes; no internal visibility or private reflection was introduced. The prior producer's expected allocation failure remains retained. The change has no new public API or project. It still requires main-candidate integration, real edit timing/allocation pairs, full product and final CI before verification/merge closure.

  3. FLwolfy commented on Oct 29, 2026

    @FLwolfy
    MemberAuthor

    Source architecture gate correction

    The current ordinary verify replay evaluated ownership for all 241 projects and failed exactly eight source-documentation declarations in the new internal Scene reference scope hierarchy. The compiler's public XML warning policy does not reject these internal types, while the repository's syntax gate requires explicit documentation on every protected declaration. The remote Windows architecture step also failed; its oversized job log currently truncates before that step, so the retained local result is the exact diagnostic evidence.

    e54/current-architecture.log preserves all eight violations. Meaningful English XML now documents the base Scene/subtree ownership, identifier admission and resolution outcomes; overrides inherit the contract and the property scope additionally describes current Core/domain and foreign/destroyed-object rejection. No behavior, visibility, public API, generation code, BGCS package or validator rule was changed. The corrected complete repository gate is running under e54/corrected-architecture.log.

    The integrated ordinary producer preparation already passes Core 97 and Scene 66 plus SourceRelease, selected Player, Debug/Release test graphs, both Editor configurations and the Build entry. Those focused/preparation results do not replace final exact-source contracts, product/performance, Wiki and CI. Keep Open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions