spine-runtimes/todos/done/2025-01-21-19-06-33-circular-reference-display-analysis.md
Mario Zechner 6f81d43faa [cpp] Enhance circular reference display with deterministic object identifiers
Replace "<circular>" with meaningful reference strings using a hybrid approach:
- Objects with names: <EventData-walk>, <BoneData-head>, <Animation-run>
- Objects without names: <TrackEntry-1>, <Bone-2>, <SliderTimeline-3>

Each serialized object now includes "refString" as its first field, enabling
easy navigation from circular references to full object definitions.
2025-07-22 02:09:01 +02:00

74 lines
2.5 KiB
Markdown

# Circular Reference Display Analysis
## Current Implementation
The circular reference detection is implemented in:
### 1. **Java SkeletonSerializer**
**File:** `spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/utils/SkeletonSerializer.java`
- Uses pattern: `if (visitedObjects.contains(obj)) { json.writeValue("<circular>"); return; }`
- Found on 100+ lines throughout write methods
### 2. **C++ SkeletonSerializer**
**File:** `spine-cpp/tests/SkeletonSerializer.h`
- Uses pattern: `if (_visitedObjects.containsKey(obj)) { _json.writeValue("<circular>"); return; }`
- Similar implementation to Java version
### 3. **Generator Scripts**
- `tests/src/generate-java-serializer.ts` (lines 189-192)
- `tests/src/generate-cpp-serializer.ts` (lines 182-183, 274-275)
- Both inject the circular reference detection pattern
### 4. **Test Runner**
- `tests/src/headless-test-runner.ts` (line 409)
- Handles "<circular>" values during JSON comparison
## Object Identification Patterns
### Name-based Identification
Most Spine objects use `name` as primary identifier:
```java
// Event.java - toString returns the event's name
public String toString() { return data.name; }
// Attachment.java - toString returns attachment name
public String toString() { return name; }
// Skeleton.java - toString returns skeleton data name or falls back
public String toString() {
return data.name != null ? data.name : super.toString();
}
```
### ID-based Identification
TypeScript VertexAttachment uses auto-incrementing IDs:
```typescript
export abstract class VertexAttachment extends Attachment {
private static nextID = 0;
/** The unique ID for this attachment. */
id = VertexAttachment.nextID++;
}
```
### Type-based Identification
Serializers include explicit type information:
```java
json.writeName("type");
json.writeValue("Animation");
```
## Current Limitations
1. **No type information** - Can't quickly understand what type of object caused the circular reference
2. **No unique identification** - Can't distinguish between multiple circular references of the same type
3. **No navigation aid** - Can't easily locate the original object definition in large object graphs
## Enhancement Opportunities
The existing infrastructure supports enhancement:
- Consistent naming patterns across objects
- Unique ID patterns could be expanded
- Type information already captured in serializers
- Object reference tracking infrastructure is mature
Enhanced format could be: `<circular: Animation#"walk">` or `<circular: Bone#"head">` instead of just `<circular>`.