refactor(editor): 优化dsl更新后画布更新逻辑

This commit is contained in:
roymondchen 2025-01-10 19:44:40 +08:00
parent 895c461e2b
commit ab7df6c21e
2 changed files with 112 additions and 67 deletions

View File

@ -1,6 +1,7 @@
import { computed, onBeforeUnmount, reactive, toRaw, watch } from 'vue'; import { computed, onBeforeUnmount, reactive, toRaw, watch } from 'vue';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import type TMagicCore from '@tmagic/core';
import type { import type {
CodeBlockContent, CodeBlockContent,
DataSourceSchema, DataSourceSchema,
@ -263,67 +264,46 @@ export const initServiceEvents = (
if (!node) return; if (!node) return;
collectIdle([node], true).then(() => { collectIdle([node], true);
afterUpdateNodes([node]); updateStage([node]);
});
}); });
}); });
const getApp = () => stage.value?.renderer?.runtime?.getApp?.(); const getApp = () => {
const renderer = stage.value?.renderer;
const updateDataSourceSchema = (nodes: MNode[], deep: boolean) => { if (!renderer) {
const root = editorService.get('root'); return undefined;
const app = getApp();
if (root && app?.dsl) {
app.dsl.dataSourceDeps = root.dataSourceDeps;
app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
app.dsl.dataSources = root.dataSources;
} }
if (root?.dataSources) { if (renderer.runtime) {
getApp()?.dataSourceManager?.updateSchema(root.dataSources); return renderer.runtime.getApp?.();
} }
if (!root || !stage.value) return; return new Promise<TMagicCore | undefined>((resolve) => {
const timeout = globalThis.setTimeout(() => {
resolve(undefined);
}, 10000);
const allNodes: MNode[] = []; renderer.on('runtime-ready', () => {
if (timeout) {
if (deep) { globalThis.clearTimeout(timeout);
nodes.forEach((node) => { }
traverseNode<MNode>(node, (node) => { resolve(renderer.runtime?.getApp?.());
if (!allNodes.includes(node)) {
allNodes.push(node);
}
});
});
} else {
allNodes.push(...nodes);
}
const deps = Object.values(root.dataSourceDeps || {});
deps.forEach((dep) => {
Object.keys(dep).forEach((id) => {
const node = allNodes.find((node) => node.id === id);
node &&
stage.value?.update({
config: cloneDeep(node),
parentId: editorService.getParentById(node.id)?.id,
root: cloneDeep(root),
});
}); });
}); });
}; };
const afterUpdateNodes = (nodes: MNode[]) => { const updateDataSourceSchema = async () => {
const root = editorService.get('root'); const root = editorService.get('root');
if (!root) return; const app = await getApp();
for (const node of nodes) {
stage.value?.update({ if (root && app?.dsl) {
config: cloneDeep(node), app.dsl.dataSourceDeps = root.dataSourceDeps;
parentId: editorService.getParentById(node.id)?.id, app.dsl.dataSources = root.dataSources;
root: cloneDeep(root), }
});
if (root?.dataSources) {
app?.dataSourceManager?.updateSchema(root.dataSources);
} }
}; };
@ -360,18 +340,72 @@ export const initServiceEvents = (
} }
}; };
const depCollectedHandler = () => { /**
* dsl后会执行依赖收集并调用此方法
* updateStage应当时一次inDeps参数来区分调用时机
* inDeps为true是则更新依赖收集到的节点
* @param nodes
* @param inDeps
* @returns
*/
const updateStage = (nodes: MNode[], inDeps = false) => {
const root = editorService.get('root'); const root = editorService.get('root');
if (!root) return; if (!root) return;
const app = getApp();
const update = (node: MNode) =>
stage.value?.update({
config: cloneDeep(node),
parentId: editorService.getParentById(node.id)?.id,
root: cloneDeep(root),
});
nodes.forEach((node) => {
const inDepsNodeId: Id[] = [];
const deps = Object.values(root.dataSourceDeps || {});
deps.forEach((dep) => {
Object.keys(dep).forEach((id) => {
inDepsNodeId.push(id);
});
});
if (inDeps) {
if (inDepsNodeId.includes(node.id)) {
update(node);
}
} else {
if (!inDepsNodeId.includes(node.id)) {
update(node);
}
}
});
};
const dsDepCollectedHandler = async (nodes: MNode[], deep: boolean) => {
const root = editorService.get('root');
if (!root) return;
const app = await getApp();
if (app?.dsl) { if (app?.dsl) {
app.dsl.dataSourceDeps = root.dataSourceDeps; app.dsl.dataSourceDeps = root.dataSourceDeps;
} }
if (deep) {
nodes.forEach((node) => {
traverseNode<MNode>(
node,
(node) => {
updateStage([node], true);
},
[],
true,
);
});
} else {
updateStage(nodes, true);
}
}; };
depService.on('add-target', targetAddHandler); depService.on('add-target', targetAddHandler);
depService.on('remove-target', targetRemoveHandler); depService.on('remove-target', targetRemoveHandler);
depService.on('collected', depCollectedHandler); depService.on('ds-collected', dsDepCollectedHandler);
const initDataSourceDepTarget = (ds: DataSourceSchema) => { const initDataSourceDepTarget = (ds: DataSourceSchema) => {
depService.addTarget(createDataSourceTarget(ds, reactive({}))); depService.addTarget(createDataSourceTarget(ds, reactive({})));
@ -396,9 +430,9 @@ export const initServiceEvents = (
// 新增节点,收集依赖 // 新增节点,收集依赖
const nodeAddHandler = (nodes: MNode[]) => { const nodeAddHandler = (nodes: MNode[]) => {
collectIdle(nodes, true).then(() => { collectIdle(nodes, true);
afterUpdateNodes(nodes);
}); updateStage(nodes);
}; };
// 节点更新,收集依赖 // 节点更新,收集依赖
@ -430,11 +464,10 @@ export const initServiceEvents = (
}); });
if (needRecollectNodes.length) { if (needRecollectNodes.length) {
collectIdle(needRecollectNodes, true).then(() => { collectIdle(needRecollectNodes, true);
afterUpdateNodes(needRecollectNodes); updateStage(needRecollectNodes);
});
} else if (normalNodes.length) { } else if (normalNodes.length) {
afterUpdateNodes(normalNodes); updateStage(normalNodes);
} }
}; };
@ -446,7 +479,7 @@ export const initServiceEvents = (
// 由于历史记录变化是更新整个page所以历史记录变化时需要重新收集依赖 // 由于历史记录变化是更新整个page所以历史记录变化时需要重新收集依赖
const historyChangeHandler = (page: MPage | MPageFragment) => { const historyChangeHandler = (page: MPage | MPageFragment) => {
collectIdle([page], true).then(() => { collectIdle([page], true).then(() => {
updateDataSourceSchema([page], true); updateDataSourceSchema();
}); });
}; };
@ -472,12 +505,16 @@ export const initServiceEvents = (
codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler); codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler);
codeBlockService.on('remove', codeBlockRemoveHandler); codeBlockService.on('remove', codeBlockRemoveHandler);
const dataSourceAddHandler = (config: DataSourceSchema) => { const dataSourceAddHandler = async (config: DataSourceSchema) => {
initDataSourceDepTarget(config); initDataSourceDepTarget(config);
getApp()?.dataSourceManager?.addDataSource(config); const app = await getApp();
app?.dataSourceManager?.addDataSource(config);
}; };
const dataSourceUpdateHandler = (config: DataSourceSchema, { changeRecords }: { changeRecords: ChangeRecord[] }) => { const dataSourceUpdateHandler = async (
config: DataSourceSchema,
{ changeRecords }: { changeRecords: ChangeRecord[] },
) => {
let needRecollectDep = false; let needRecollectDep = false;
for (const changeRecord of changeRecords) { for (const changeRecord of changeRecords) {
if (!changeRecord.propPath) { if (!changeRecord.propPath) {
@ -506,11 +543,12 @@ export const initServiceEvents = (
initDataSourceDepTarget(config); initDataSourceDepTarget(config);
collectIdle(root.items, true).then(() => { collectIdle(root.items, true).then(() => {
updateDataSourceSchema(root?.items || [], true); updateDataSourceSchema();
}); });
} }
} else if (root?.dataSources) { } else if (root?.dataSources) {
getApp()?.dataSourceManager?.updateSchema(root.dataSources); const app = await getApp();
app?.dataSourceManager?.updateSchema(root.dataSources);
} }
}; };
@ -525,7 +563,7 @@ export const initServiceEvents = (
const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {}); const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {});
const nodes = getNodes(nodeIds, root?.items); const nodes = getNodes(nodeIds, root?.items);
collectIdle(nodes, false).then(() => { collectIdle(nodes, false).then(() => {
updateDataSourceSchema(nodes, false); updateDataSourceSchema();
}); });
removeDataSourceTarget(id); removeDataSourceTarget(id);
@ -538,7 +576,7 @@ export const initServiceEvents = (
onBeforeUnmount(() => { onBeforeUnmount(() => {
depService.off('add-target', targetAddHandler); depService.off('add-target', targetAddHandler);
depService.off('remove-target', targetRemoveHandler); depService.off('remove-target', targetRemoveHandler);
depService.off('collected', depCollectedHandler); depService.off('ds-collected', dsDepCollectedHandler);
editorService.off('history-change', historyChangeHandler); editorService.off('history-change', historyChangeHandler);
editorService.off('root-change', rootChangeHandler); editorService.off('root-change', rootChangeHandler);

View File

@ -499,8 +499,11 @@ export const traverseNode = <T extends NodeItem = NodeItem>(
node: T, node: T,
cb: (node: T, parents: T[]) => void, cb: (node: T, parents: T[]) => void,
parents: T[] = [], parents: T[] = [],
evalCbAfter = false,
) => { ) => {
cb(node, parents); if (!evalCbAfter) {
cb(node, parents);
}
if (Array.isArray(node.items) && node.items.length) { if (Array.isArray(node.items) && node.items.length) {
parents.push(node); parents.push(node);
@ -508,6 +511,10 @@ export const traverseNode = <T extends NodeItem = NodeItem>(
traverseNode(item as T, cb, [...parents]); traverseNode(item as T, cb, [...parents]);
}); });
} }
if (evalCbAfter) {
cb(node, parents);
}
}; };
export const isValueIncludeDataSource = (value: any) => { export const isValueIncludeDataSource = (value: any) => {