Files
GhostEngine/Ghost.Editor.Core/SceneGraph/Serialization/SceneAssetData.cs
Misaki fdf831630b feat: implement complete scene graph system with hierarchical editor support
- Add SceneNode and EntityNode classes for editor-only metadata storage
- Implement SceneGraph view-model with O(1) entity lookup via internal caching
- Create IdRemapTable for file-local to global entity ID remapping on load
- Implement SceneSerializationContext for load/save operation tracking
- Add JSON-serializable SceneAssetData, EntityData, and ComponentData models
- Implement SceneSerializer for save/load with validation and reference remapping
- Add comprehensive documentation: README.md, IMPLEMENTATION_GUIDE.md, SYSTEM_SUMMARY.md
- Update Ghost.Editor.Core.csproj to reference Ghost.Entities assembly
- Support parent-child relationships via Hierarchy component
- Enforce no cross-scene entity references
- Keep runtime minimal: only SceneID, Hierarchy, LocalToWorld components
- All editor metadata (names, UI state) stored in editor-only SceneNode/EntityNode classes

This implements the architecture from SceneGraph Plan.md with clean separation of concerns,
minimal runtime footprint, and AOT compatibility.
2026-01-25 21:42:03 +09:00

99 lines
2.8 KiB
C#

using System.Text.Json.Serialization;
namespace Ghost.Editor.Core.SceneGraph.Serialization;
/// <summary>
/// JSON-serializable representation of a component instance.
/// Only used in the editor for saving/loading scenes.
/// </summary>
[Serializable]
public class ComponentData
{
/// <summary>
/// Fully qualified type name of the component (e.g., "Ghost.Engine.Components.Transform").
/// </summary>
[JsonPropertyName("type")]
public string ComponentTypeName { get; set; } = string.Empty;
/// <summary>
/// Serialized component data as a dictionary.
/// Field names map to JSON values.
/// </summary>
[JsonPropertyName("data")]
public Dictionary<string, object?> Data { get; set; } = new();
}
/// <summary>
/// JSON-serializable representation of an entity within a scene.
/// Only used in the editor for saving/loading scenes.
///
/// The index in the entities list corresponds to the file-local ID.
/// </summary>
[Serializable]
public class EntityData
{
/// <summary>
/// File-local entity ID within the scene.
/// Set by the serializer based on position in the entities list.
/// </summary>
[JsonPropertyName("fileLocalId")]
public int FileLocalId { get; set; }
/// <summary>
/// Editor-only name for the entity.
/// </summary>
[JsonPropertyName("name")]
public string Name { get; set; } = "Entity";
/// <summary>
/// File-local ID of the parent entity, or -1 if root.
/// </summary>
[JsonPropertyName("parentFileLocalId")]
public int ParentFileLocalId { get; set; } = -1;
/// <summary>
/// All components attached to this entity.
/// </summary>
[JsonPropertyName("components")]
public List<ComponentData> Components { get; set; } = new();
}
/// <summary>
/// JSON-serializable representation of a scene.
/// Only used in the editor for saving/loading scenes.
/// </summary>
[Serializable]
public class SceneAssetData
{
/// <summary>
/// Scene metadata version for forward compatibility.
/// </summary>
[JsonPropertyName("version")]
public int Version { get; set; } = 1;
/// <summary>
/// Unique identifier for this scene (GUID).
/// </summary>
[JsonPropertyName("sceneGuid")]
public Guid SceneGuid { get; set; } = Guid.NewGuid();
/// <summary>
/// Editor-friendly name of the scene.
/// </summary>
[JsonPropertyName("name")]
public string Name { get; set; } = "Scene";
/// <summary>
/// Runtime scene ID.
/// </summary>
[JsonPropertyName("sceneId")]
public short SceneId { get; set; }
/// <summary>
/// All entities in the scene, ordered by file-local ID.
/// Index in this list == file-local ID.
/// </summary>
[JsonPropertyName("entities")]
public List<EntityData> Entities { get; set; } = new();
}