Skip to content

Commit

Permalink
Переключение в текстовый режим при ошибке чтения визуальной схемы (#444)
Browse files Browse the repository at this point in the history
  • Loading branch information
L140-beep authored Sep 6, 2024
1 parent 0c45354 commit 9b8c785
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 19 deletions.
5 changes: 3 additions & 2 deletions src/renderer/src/lib/data/GraphmlBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ import { isDefaultComponent, convertDefaultComponent } from './ElementsValidator

import { ChoiceState } from '../drawable';

function exportMeta(meta: Meta, platform: Platform): CGMLMeta {
function exportMeta(visual: boolean, meta: Meta, platform: Platform): CGMLMeta {
return {
id: 'coreMeta',
values: {
...meta,
standardVersion: platform.standardVersion,
platformVersion: platform.version,
lapkiVisual: visual.toString(),
},
};
}
Expand Down Expand Up @@ -391,7 +392,7 @@ export function exportCGML(elements: Elements): string {
throw new Error('Внутренняя ошибка! В момент экспорта схемы платформа не инициализирована.');
}
const cgmlElements: CGMLElements = createEmptyElements();
cgmlElements.meta = exportMeta(elements.meta, platform);
cgmlElements.meta = exportMeta(elements.visual, elements.meta, platform);
cgmlElements.format = 'Cyberiada-GraphML-1.0';
cgmlElements.platform = elements.platform;
cgmlElements.stateMachines['g'] = {
Expand Down
61 changes: 44 additions & 17 deletions src/renderer/src/lib/data/GraphmlParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function initArgList(args: string[]): ArgList {
return argList;
}

const pictoRegex: RegExp = /.+\..+\(.*\)/;
const pictoRegex: RegExp = /.+(\.|::).+\(.*\)/;

function parseAction(unproccessedAction: string): Action | undefined | string {
if (unproccessedAction === '') {
Expand Down Expand Up @@ -208,11 +208,16 @@ function getChoices(rawChoices: { [id: string]: CGMLVertex }): {
return choices;
}

function getStates(rawStates: { [id: string]: CGMLState }): { [id: string]: State } {
function getStates(rawStates: { [id: string]: CGMLState }): [boolean, { [id: string]: State }] {
const states: { [id: string]: State } = {};
let visual = true;
for (const rawStateId in rawStates) {
const rawState = rawStates[rawStateId];
const events: EventData[] = actionsToEventData(rawState.actions);
const [isVisual, events] = actionsToEventData(rawState.actions);
// FIXME: здесь нужно пробросить предупреждение о переходе в тестовый режим
if (!isVisual) {
visual = false;
}
states[rawStateId] = {
// ПОМЕНЯТЬ ЦВЕТ
color: rawState.color ?? '#FFFFFF',
Expand All @@ -229,11 +234,14 @@ function getStates(rawStates: { [id: string]: CGMLState }): { [id: string]: Stat
events: events,
};
}
return states;
return [visual, states];
}

function actionsToEventData(rawActions: Array<CGMLAction | CGMLTransitionAction>): EventData[] {
function actionsToEventData(
rawActions: Array<CGMLAction | CGMLTransitionAction>
): [boolean, EventData[]] {
const eventDataArr: EventData[] = [];
let visual = true;
for (const action of rawActions) {
const eventData: EventData = {
trigger: {
Expand All @@ -244,6 +252,10 @@ function actionsToEventData(rawActions: Array<CGMLAction | CGMLTransitionAction>
};
if (action.action) {
const parsedActions = parseActions(action.action);
if (parsedActions && !Array.isArray(parsedActions)) {
// FIXME: здесь нужно пробросить предупреждение о переходе в тестовый режим
visual = false;
}
if (parsedActions) {
eventData.do = parsedActions;
}
Expand All @@ -259,13 +271,14 @@ function actionsToEventData(rawActions: Array<CGMLAction | CGMLTransitionAction>
}
eventDataArr.push(eventData);
}
return eventDataArr;
return [visual, eventDataArr];
}

function getTransitions(
rawTransitions: Record<string, CGMLTransition>
): Record<string, Transition> {
): [boolean, Record<string, Transition>] {
const transitions: Record<string, Transition> = {};
let visual = true;
for (const id in rawTransitions) {
const rawTransition = rawTransitions[id];
if (rawTransition.actions.length == 0) {
Expand All @@ -277,20 +290,23 @@ function getTransitions(
continue;
}
// В данный момент поддерживается только один триггер на переход
const eventData = actionsToEventData(rawTransition.actions)[0];
const [isVisual, eventData] = actionsToEventData(rawTransition.actions);
if (!isVisual) {
visual = isVisual;
}
transitions[id] = {
sourceId: rawTransition.source,
targetId: rawTransition.target,
color: rawTransition.color,
label: {
position: rawTransition.labelPosition ?? { x: -1, y: -1 },
trigger: eventData.trigger,
do: eventData.do,
condition: eventData.condition,
trigger: eventData[0].trigger,
do: eventData[0].do,
condition: eventData[0].condition,
},
};
}
return transitions;
return [visual, transitions];
}

function getComponents(rawComponents: { [id: string]: CGMLComponent }): {
Expand Down Expand Up @@ -427,12 +443,16 @@ function getAllComponent(platformComponents: { [name: string]: ComponentProto })
return components;
}

function getVisualFlag(rawMeta: CGMLMeta, platformVisual: boolean): boolean {
function getVisualFlag(
rawMeta: CGMLMeta,
platformVisual: boolean,
computedValue: boolean // Значение, которое выдал парсер после парсинга схемы
): boolean {
const visual: boolean | undefined = rawMeta.values['lapkiVisual']
? rawMeta.values['lapkiVisual'] === 'true'
: undefined;
if (visual === undefined) {
return platformVisual;
return platformVisual && computedValue;
}
if (visual && !platformVisual) {
throw new Error(
Expand Down Expand Up @@ -464,6 +484,7 @@ export function importGraphml(
if (!isPlatformAvailable(rawElements.platform)) {
throw new Error(`Неизвестная платформа ${rawElements.platform}.`);
}

// TODO: добавить в платформу флаг для статических компонентов
const platform: Platform | undefined = getPlatform(elements.platform);
if (platform === undefined) {
Expand All @@ -478,8 +499,10 @@ export function importGraphml(
elements.initialStates = getInitialStates(sm.initialStates);
elements.finalStates = getFinals(sm.finals);
elements.notes = sm.notes;
elements.states = getStates(sm.states);
elements.transitions = getTransitions(sm.transitions);
const [stateVisual, states] = getStates(sm.states);
elements.states = states;
const [transitionVisual, transitions] = getTransitions(sm.transitions);
elements.transitions = transitions;
elements.states = labelStateParameters(
elements.states,
platform.components,
Expand All @@ -492,7 +515,11 @@ export function importGraphml(
platform.components,
elements.components
);
elements.visual = getVisualFlag(rawElements.meta, platform.visual);
elements.visual = getVisualFlag(
rawElements.meta,
platform.visual,
stateVisual && transitionVisual
);

validateElements(elements, platform);
return elements;
Expand Down

0 comments on commit 9b8c785

Please sign in to comment.