Repository navigation
fix: elide unset url and dep in hand DTOs - #185
Draft
claude[bot] wants to merge 1 commit into
Draft
claude[bot] wants to merge 1 commit into
claude[bot] wants to merge 1 commit into
Conversation
ArenaHandLeftJson and ArenaHandRightJson declared url and dep as plain public auto-properties with no [JsonProperty] and no ShouldSerialize guard, so Newtonsoft's default resolver emitted both on every publish - as explicit JSON nulls when unset. ARENA reads a null attribute value as "delete this attribute", so an update could clear a url or dep the client never set. Both members now follow the idiom used by the rest of the schema set: a private static default plus a matching ShouldSerialize that compares against it. Member names are unchanged, so callers compile as before, and populated values still go on the wire. Refs #184
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by mwfarb · Slack thread
Before
ArenaHandLeftJsonandArenaHandRightJsonpublished"url": nulland"dep": nullon every message, whether or not the client had set them:ARENA reads a null attribute value as delete this attribute, so a hand update could clear a
urlordepthe client never touched. It was also the one place inRuntime/Schemas/that broke the documented "send only changed fields" convention (Runtime/Schemas/README.md).After
Unset members stay off the wire; populated ones are unchanged:
How
urlanddepwere plain public auto-properties — no[JsonProperty], no default, no guard — and Newtonsoft's default resolver serializes unattributed public members, so nothing elided them. Both now use the same idiom as the rest of the schema set (private staticdefault +ShouldSerializeX()comparing against it), as inRuntime/Schemas/Attribute/ArenaPhysxJointJson.cs:55-63. Member names are unchanged, soArenaLocalHand.PublishCreateUpdate()compiles as before. Two files, +34 −4.On autogeneration:
Runtime/Schemas/README.mdsays everything inObject/andAttribute/is generated from arenaxr/arena-schemas. These two hand files are the only 2 of the 78 files inObject/that carry no per-file// CAUTION: This file is autogenerated ...header, so they look hand-maintained and this local fix should survive. IfhandLeft/handRightare generated upstream, the real fix belongs in the generator too — otherwise the next regeneration reintroduces the nulls. Worth a matching upstream change either way, since the same guard is what every generated DTO already emits.Closes #184
Verification, and the merge order this needs
The Unity EditMode and pure .NET suites live on
test/unit-test-suite-ci(#183), not onmain, so this branch has nowhere to add a test. Both were still executed, against the real DTO sources.1. Scratch harness (real NUnit 3.14.0, real Newtonsoft.Json 13.0.3, the two DTO sources compiled unmodified with a minimal
UnityEngineshim for[Tooltip]/Debug.LogWarning). The same 7 test cases, run before and after the fix:HandDtos_ElideUnsetUrlAndDep(left, right)Expected: null / But was: <empty>HandLeft/HandRight_StillPublishesUrlAndDepWhenSetHandDtos_RoundTripUrlAndDepFromTheWirePIN_HandDtos_EmitUrlAndDepAsExplicitNulls(left, right)url is emitted even though it is unset / Expected: not null / But was: null2. Trial merge with #183. This branch merges into
test/unit-test-suite-ci(at8f0bcec) with no conflicts. On the merged tree:Tests~/DotNet/ArenaUnity.PureTests): 273 / 273 pass, unaffected;Tests/Editor/ArenaSchemaContractTests.cs, run through an equivalent .NET runner): 523 pass, 2 fail.The 2 failures are by design. #183 added
HandDtos_EmitUrlAndDepAsExplicitNulls_PinsCurrentBuggyBehaviour(Tests/Editor/ArenaSchemaContractTests.cs:258) to pin this bug as current behaviour, and its own doc comment says the expectations becomeIs.Nullonce a fix lands. Nothing else in either suite is affected: the generic contract tests (Dto_EveryWireMemberHasAShouldSerializeMethod,Dto_FreshInstanceSerializesExactlyItsRequiredMembers,Dto_EmitsNoUndeclaredMembers,Dto_EveryDefaultBackingFieldHasAMatchingMember) derive their expectations by reflection and stay green, becauseurlanddepare now attributed fields with matching guards.Required merge order — either order works, but the second one to merge must carry the pin flip:
maingoes red on those 2 cases.The flip is one hunk in one test file, plus a stale-comment fix. Applied on the merged tree it turns 523 pass / 2 fail into 526 / 526 pass, and the flipped test still fails on pre-fix DTO sources (
Expected: null / But was: <empty>) — so it is a real regression test for this bug, not a rubber stamp.Pin-flip diff for
Tests/Editor/ArenaSchemaContractTests.cs(verified on the trial merge)Nothing was pushed to the #183 branch; the trial merge was local only.
Generated by Claude Code