5.3 KiB
UHM Editor - state replay hiện tại
Tài liệu này mô tả đúng flow replay mode hiện tại của /editor/[id].
Nguồn thật:
src/app/editor/[id]/page.tsxsrc/uhm/lib/editor/state/useEditorState.tssrc/uhm/lib/editor/project/useProjectCommands.tssrc/uhm/lib/editor/snapshot/editorSnapshot.ts
1. Kết luận ngắn
Replay mode hiện tại có 2 lớp state:
activeReplayDraft- là
BattleReplayđang chỉnh - chỉ chứa
geometry_id,target_geometry_ids,detail
- là
replayDraft- là
FeatureCollectionlocal, được FE hydrate lại từmainDraft + target_geometry_ids - chỉ dùng để map/render/select trong replay mode
- là
Điểm quan trọng:
replayDraftkhông còn được persist vào commit/API- commit chỉ lưu
replays[]vớitarget_geometry_ids - snapshot cũ còn
replay_featuressẽ được FE migrate sangtarget_geometry_idskhi load
2. Shape replay hiện tại
type BattleReplay = {
id: string;
geometry_id: string;
target_geometry_ids: string[];
detail: ReplayStage[];
};
Ý nghĩa:
geometry_id- MAIN geo của replay
- cũng là key để tìm replay tương ứng
id- hiện luôn bằng
geometry_id - thêm để schema replay có id riêng rõ ràng hơn
- hiện luôn bằng
target_geometry_ids- toàn bộ geo được đưa vào replay
- phần tử đầu nên luôn là MAIN geo
detail- stage/step/actions của kịch bản
3. Replay được mở như thế nào
Khi vào replay từ UI:
- editor lấy
triggerId- ưu tiên
selectedFeatureIds[0] - nếu chưa có selection thì dùng
featureIdvừa click
- ưu tiên
- gọi
editor.switchReplayContext(triggerId, selectedFeatureIds) switchReplayContext()sẽ:- flush replay cũ nếu đang mở replay khác
- tìm replay đã tồn tại theo
geometry_id - nếu chưa có thì tạo seed mới
4. Seed replay được tạo ra sao
Replay seed mới có dạng:
{
id: triggerId,
geometry_id: triggerId,
target_geometry_ids: [...],
detail: []
}
target_geometry_ids được build từ:
- MAIN geo
- toàn bộ bulk selection hiện tại
- toàn bộ
bindingcủa MAIN geo trongmainDraft
Rule hiện tại:
- MAIN geo luôn đứng đầu
- geo trùng sẽ được dedupe
- nếu replay đã tồn tại sẵn, FE giữ
detailcũ và chỉ append thêm geo mới còn thiếu vàotarget_geometry_ids
5. replayDraft được hydrate thế nào
replayDraft không còn nằm trong snapshot.
Mỗi lần:
- mở replay
- undo replay session
- restore
activeReplayDraft
FE sẽ hydrate lại:
replayDraft = hydrate(mainDraft, activeReplayDraft.target_geometry_ids)
Hydrate hiện tại:
- lấy feature từ
mainDrafttheo đúng thứ tựtarget_geometry_ids - clone ra
FeatureCollectionmới - flatten
bindingthành[]để các geo trong replay bình đẳng với nhau
6. Trong replay mode map đang đọc gì
useEditorState() vẫn switch active draft như cũ:
const activeDraft = mode === "replay" ? replayDraft : mainDraft;
Nên khi mode === "replay":
editor.drafttrỏ vàoreplayDrafteditor.draftReftrỏ vàoreplayDraftRef- map chỉ render tập geo đang nằm trong
target_geometry_ids
7. Replay mode còn sửa geometry không
Không.
Hiện tại state layer đã chặn toàn bộ nhánh mutate geometry trong replay mode:
createFeaturecreateFeatureWithSnapshotEntitiespatchFeaturePropertiespatchFeaturePropertiesBatchupdateFeaturedeleteFeature
Nghĩa là:
- replay mode chỉ còn là nơi viết script replay
- không còn persist hay commit geometry edit riêng của replay
8. Cái gì vẫn được sửa trong replay mode
Replay sidebar vẫn sửa:
detail[]stagestep- các action
UI / map / geo / narrative
Các thay đổi đó đi qua:
editor.mutateActiveReplayapplyReplaySessionMutation()
Undo replay vẫn riêng ở:
replayUndoStack
9. Khi nào replay được flush về replays[]
activeReplayDraft chỉ là session đang mở.
Nó được flush về replays[] khi:
- thoát replay mode
- chuyển sang replay khác
Hàm chịu trách nhiệm là:
finalizeActiveReplaySession()
10. Commit lấy replay từ đâu
Commit không lấy activeReplayDraft trực tiếp.
Nó lấy:
editor.effectiveReplays
effectiveReplays là:
replays- cộng thêm overlay của
activeReplayDraftnếu session hiện tại đã thay đổi nhưng chưa flush
Vì vậy:
- đang còn ở replay mode vẫn commit được replay mới nhất
- không cần thoát replay mode mới lưu được script
11. Replay đi qua API ra sao
Payload commit hiện tại chỉ gửi:
geometry_idtarget_geometry_idsdetail
Không gửi:
replayDraftreplay_featuresFeatureCollectionlocal của replay mode
12. Migrate dữ liệu cũ
Snapshot cũ nếu còn:
replay_features?: FeatureCollection
thì FE sẽ:
- đọc
replay_features.features[].properties.id - chuyển chúng thành
target_geometry_ids - bỏ
replay_featureskhỏi runtime replay mới
Nên dữ liệu cũ vẫn mở được, nhưng commit mới sẽ ra schema mới.