修正自动切分素材检查条件
移除自动切分对预先导入独立素材的错误要求。 统一自动切分前置与结果检查,并补齐图片和字体引用校验。 在新建和重新开始自动切分时执行前置检查,恢复流程继续尽力完成。
This commit is contained in:
@@ -72,7 +72,7 @@ export function validateComponentRecognitionPrerequisites(
|
||||
return issues;
|
||||
}
|
||||
|
||||
export function validateAssetRecognitionPrerequisites(
|
||||
export function validateAssetSeparationPrerequisites(
|
||||
state: State,
|
||||
): UiEditorPrerequisiteIssue[] {
|
||||
const issues = validateComponentRecognitionPrerequisites(state);
|
||||
@@ -91,58 +91,9 @@ export function validateAssetRecognitionPrerequisites(
|
||||
});
|
||||
}
|
||||
}
|
||||
if (Object.keys(state.sprite_assets).length === 0) {
|
||||
issues.push({
|
||||
code: 'missing-sprite-assets',
|
||||
message: '请先导入独立素材',
|
||||
});
|
||||
}
|
||||
return issues;
|
||||
}
|
||||
|
||||
export function validateLayoutGenerationPrerequisites(
|
||||
state: State,
|
||||
): UiEditorPrerequisiteIssue[] {
|
||||
const issues = validateAssetRecognitionPrerequisites(state);
|
||||
const visit = (nodes: State['ui_trees'][number]['root']['children']) => {
|
||||
for (const node of nodes) {
|
||||
const component = node.component;
|
||||
if (component) {
|
||||
if (
|
||||
'Image' in component &&
|
||||
component.Image.target_graphic !== null &&
|
||||
!(component.Image.target_graphic in state.sprite_assets)
|
||||
) {
|
||||
issues.push({
|
||||
code: 'missing-target-graphic',
|
||||
message: '图片组件引用的独立素材不存在',
|
||||
resourceId: component.Image.target_graphic,
|
||||
});
|
||||
}
|
||||
if ('Text' in component) {
|
||||
const font = component.Text.font;
|
||||
if (typeof font !== 'string' && !(font.Bound in state.font_assets)) {
|
||||
issues.push({
|
||||
code: 'missing-font',
|
||||
message: '文本组件引用的字体不存在',
|
||||
resourceId: font.Bound,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
visit(node.children);
|
||||
}
|
||||
};
|
||||
for (const tree of state.ui_trees) visit([tree.root]);
|
||||
return issues;
|
||||
}
|
||||
|
||||
export function validateLayoutReviewPrerequisites(
|
||||
state: State,
|
||||
): UiEditorPrerequisiteIssue[] {
|
||||
return validateLayoutGenerationPrerequisites(state);
|
||||
}
|
||||
|
||||
function layoutStatusIssue(
|
||||
status: StageStatus,
|
||||
): UiEditorPrerequisiteIssue | null {
|
||||
@@ -214,7 +165,7 @@ export function validateStructureRecognitionResult(
|
||||
return issues;
|
||||
}
|
||||
|
||||
export function validateVisualBindingResult(
|
||||
export function validateAssetSeparationResult(
|
||||
state: State,
|
||||
): UiEditorPrerequisiteIssue[] {
|
||||
const issues: UiEditorPrerequisiteIssue[] = [];
|
||||
@@ -225,6 +176,32 @@ export function validateVisualBindingResult(
|
||||
}
|
||||
const issue = componentStatusIssue(node.metadata.component_status);
|
||||
if (issue) issues.push(issue);
|
||||
const component = node.component;
|
||||
if ('Image' in component) {
|
||||
const targetGraphic = component.Image.target_graphic;
|
||||
if (targetGraphic === null) {
|
||||
issues.push({
|
||||
code: 'missing-separated-image',
|
||||
message: '图片组件尚未完成素材切分',
|
||||
});
|
||||
} else if (!(targetGraphic in state.sprite_assets)) {
|
||||
issues.push({
|
||||
code: 'missing-target-graphic',
|
||||
message: '图片组件引用的切分素材不存在',
|
||||
resourceId: targetGraphic,
|
||||
});
|
||||
}
|
||||
}
|
||||
if ('Text' in component) {
|
||||
const font = component.Text.font;
|
||||
if (typeof font !== 'string' && !(font.Bound in state.font_assets)) {
|
||||
issues.push({
|
||||
code: 'missing-font',
|
||||
message: '文本组件引用的字体不存在',
|
||||
resourceId: font.Bound,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return issues;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import {
|
||||
type UiEditorPrerequisiteIssue,
|
||||
validateAssetRecognitionPrerequisites,
|
||||
validateAssetSeparationPrerequisites,
|
||||
validateAssetSeparationResult,
|
||||
validateComponentRecognitionPrerequisites,
|
||||
validateLayoutReviewPrerequisites,
|
||||
validateReferenceAnalysisResult,
|
||||
validateStructureRecognitionResult,
|
||||
validateVisualBindingResult,
|
||||
} from '../../../features/ui-editor/requisites';
|
||||
import type { State } from '../../../features/ui-editor/types/State';
|
||||
import type { UiEditorStepId } from '../model';
|
||||
@@ -22,7 +21,7 @@ export function prerequisiteIssuesForStep(
|
||||
case 'structure-recognition':
|
||||
return validateComponentRecognitionPrerequisites(state);
|
||||
case 'asset-separation':
|
||||
return validateAssetRecognitionPrerequisites(state);
|
||||
return validateAssetSeparationPrerequisites(state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +35,7 @@ export function postCheckIssuesForStep(
|
||||
case 'structure-recognition':
|
||||
return validateStructureRecognitionResult(state);
|
||||
case 'asset-separation':
|
||||
return validateVisualBindingResult(state);
|
||||
return validateAssetSeparationResult(state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +45,7 @@ export function postCheckIssuesForSave(
|
||||
return [
|
||||
...validateReferenceAnalysisResult(state),
|
||||
...validateStructureRecognitionResult(state),
|
||||
...validateVisualBindingResult(state),
|
||||
...validateAssetSeparationResult(state),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -58,8 +57,8 @@ export function activeStepPrerequisiteIssues(
|
||||
case 'reference-analysis':
|
||||
return validateComponentRecognitionPrerequisites(state);
|
||||
case 'structure-recognition':
|
||||
return validateAssetRecognitionPrerequisites(state);
|
||||
return validateComponentRecognitionPrerequisites(state);
|
||||
case 'asset-separation':
|
||||
return validateLayoutReviewPrerequisites(state);
|
||||
return validateAssetSeparationPrerequisites(state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1241,6 +1241,19 @@ export function useUiEditorSession(
|
||||
setSeparationRecovery(recovery);
|
||||
return;
|
||||
}
|
||||
const prerequisiteIssues = prerequisiteIssuesForStep(
|
||||
editor.state,
|
||||
'asset-separation',
|
||||
);
|
||||
if (prerequisiteIssues.length > 0) {
|
||||
reportWorkflowCompletion(
|
||||
'asset-separation',
|
||||
'failure',
|
||||
prerequisiteIssues.map((issue) => issue.message).join(';'),
|
||||
setSeparationStatus,
|
||||
);
|
||||
return;
|
||||
}
|
||||
await runSeparationWorkflow();
|
||||
} catch (cause) {
|
||||
setSeparationStatus(
|
||||
@@ -1257,6 +1270,19 @@ export function useUiEditorSession(
|
||||
async function restartSeparation() {
|
||||
if (!resourceId) return;
|
||||
setSeparationRecovery(null);
|
||||
const prerequisiteIssues = prerequisiteIssuesForStep(
|
||||
editor.state,
|
||||
'asset-separation',
|
||||
);
|
||||
if (prerequisiteIssues.length > 0) {
|
||||
reportWorkflowCompletion(
|
||||
'asset-separation',
|
||||
'failure',
|
||||
prerequisiteIssues.map((issue) => issue.message).join(';'),
|
||||
setSeparationStatus,
|
||||
);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await invoke('discard_separation_recovery', {
|
||||
projectPath,
|
||||
|
||||
@@ -85,6 +85,7 @@ Rust 在接收并校验工具结果后,才把这两个枚举变体映射为正
|
||||
## 前端正式接入
|
||||
|
||||
- UI 编辑器点击“自动切分素材”时,前端只调用一次 `separate_ui`,消费完整 `SeparationDTO`;separation 内部 batch 不向前端暴露,也不在 UI 中显示 batch 进度。
|
||||
- 自动切分的前置检查只要求界面图及对应 UI tree 有效,不要求用户预先导入 SpriteAsset;结果检查负责报告未回填的 Image、丢失的切分素材引用、丢失的字体引用及组件审阅状态。新建和重新开始切分时执行前置检查,继续已有 sidecar 时直接按恢复状态尽力完成。
|
||||
- 如果 sidecar 已存在未完成的 `state.json`,点击入口时先打开独立弹窗,由用户选择“继续上次自动切分素材”或“开始新的自动切分素材”。继续复用 sidecar 的 pending tree;重新开始只替换当前 `state.json`,不删除 sidecar 图片。
|
||||
- `BoundNode.cut_image_path` 必须是项目根相对路径。前端使用现有 `import_local_project_image_assets` 登记 cut 图片;由于该通用命令单次最多 100 个路径,前端可以在资源登记阶段按 100 条分组调用,但这不属于 separation batch,也不向用户展示。
|
||||
- 现有本地资源导入按清洗后的文件名 stem 与内容摘要生成目标路径;相同目标路径直接复用已有 manifest asset ID,内容不同则拒绝覆盖或生成不同摘要路径。前端不自行猜测 SpriteAsset 是否存在,也不从 NodeId 派生 SpriteAssetId。
|
||||
|
||||
Reference in New Issue
Block a user