收敛 UI 编辑器锁与历史事务

新增统一的加锁并包裹历史事务操作

将 AI 建议、识别、合并和批量绑定改用统一入口
This commit is contained in:
2026-09-03 11:05:04 +08:00
parent f79724cb17
commit 15caf1cafc
2 changed files with 16 additions and 4 deletions
@@ -658,6 +658,12 @@ export function useUiEditorState(initialState: State = EMPTY_UI_EDITOR_STATE) {
[],
);
const runWithStateLockedAndHistory = useCallback(
async <T>(operation: (snapshot: State) => Promise<T>): Promise<T> =>
runInHistoryTransaction(() => runWithStateLocked(operation)),
[runInHistoryTransaction, runWithStateLocked],
);
const setImageName = useCallback(
(id: UIDesignImageId, name: string): UiEditorOperationResult => {
const blocked = guard();
@@ -1544,6 +1550,7 @@ export function useUiEditorState(initialState: State = EMPTY_UI_EDITOR_STATE) {
endHistoryTransaction,
cancelHistoryTransaction,
runInHistoryTransaction,
runWithStateLockedAndHistory,
resetHistory,
isLocked,
@@ -942,7 +942,7 @@ export function useUiEditorSession(
setSuggestionStatus(null);
setIsSuggesting(true);
try {
await editor.runWithStateLocked(async (snapshot) => {
await editor.runWithStateLockedAndHistory(async (snapshot) => {
const suggestions = await invoke<UIDesignSuggestionTreeNode[]>(
'suggest_ui_design_semantic',
{ projectPath, state: snapshot },
@@ -965,7 +965,7 @@ export function useUiEditorSession(
setRecognitionStatus(null);
setIsRecognizing(true);
try {
await editor.runWithStateLocked(async (snapshot) => {
await editor.runWithStateLockedAndHistory(async (snapshot) => {
const result = await invoke<RecognitionDTO>('recognize_ui', {
projectPath,
state: snapshot,
@@ -990,7 +990,7 @@ export function useUiEditorSession(
setMergeStatus(null);
setIsMerging(true);
try {
await editor.runWithStateLocked(async (snapshot) => {
await editor.runWithStateLockedAndHistory(async (snapshot) => {
const result = await invoke<MergeDTO>('merge_ui', { state: snapshot });
editor.replaceState(applyMergeResult(snapshot, result));
setSelectedNodeId(null);
@@ -1008,7 +1008,7 @@ export function useUiEditorSession(
setBindingStatus(null);
setIsBinding(true);
try {
await editor.runWithStateLocked(async (snapshot) => {
await editor.runWithStateLockedAndHistory(async (snapshot) => {
const allSpriteIds = Object.keys(snapshot.sprite_assets);
const batches: string[][] = [];
for (
@@ -1228,6 +1228,11 @@ export function useUiEditorSession(
deleteNode,
openClearDialog: () => setClearOpen(true),
},
history: {
...editor.historyState,
undo: editor.undo,
redo: editor.redo,
},
inspector: {
isLocked: editor.isLocked,
projectPath,