/** * @author Martin Karkowski * @email m.karkowski@zema.de * @create date 2020-02-20 19:42:06 * @modify date 2020-11-25 17:29:25 * @desc [description] */ import * as handlebars from "handlebars"; import { updateIds } from "../../ZISS-Network/helpers/idUpdater"; import { ILogicNetwork } from "../../ZISS-Network/type/ILogicNetwork"; import { defineFlows } from "../../ZISS-Petri-Net/src/wrappers/loader"; import { IArcExpression } from "../../ZISS-Petri-Net/types/IArcAnnotation"; import { analyzeLogic } from "../src/analyze.logic"; import { IParseableLogic, IParsedLogic, ITransitionDescription } from "../types/interface"; export type THelperFunction = (data: IParsedLogic) => string; export interface IParser { mainLoop(context: IParsedLogic): string; variableDefinition(context: IParsedLogic): string; instanceCreation(context: IParsedLogic): string; } export class AbstractParser { public variableDefinition(context: IParsedLogic): string { throw new Error("Method not implemented."); } // Array, containing all Elements which should be replaced. protected _replace: { regex: RegExp; replacer: string; }[] = []; /** * Function, which will be used to adapt the Path. * @param value */ protected _adaptGuard( guard: string, simplifiedGuard: string, OriginalScope: { [index: string]: { source: string; schema: IJsonSchema; }; }, simplifiedScope: { [index: string]: { source: string; schema: IJsonSchema; }; }, mappingOriginalToSimplified: Map, mappingSimplifiedToOriginal: Map, mappingSimplifiedToAdapted: Map, mappingAdaptedToSimplified: Map, mappingVariableToRoot: Map ): string { throw Error("Please Create a Valid Instance"); } /** * Function, which will be used to adapt a Variable Name. * @param value The original Variable Name */ protected _adaptVariableName( variable: string, simplifiedName: string, path: string ): string { throw Error("Please Create a Valid Instance"); } /** * Function, which will be used to generate Function Code. * @param taskData */ protected _getFunctionTriggerCode(taskData): string { throw Error("Please Create a Valid Instance"); } protected _getVariableName(taskData): string { throw Error("Please Create a Valid Instance"); } protected _templates: { [index: string]: string; } = {}; linkTemplates(...args) { for (const partial in this._templates) { handlebars.registerPartial(partial, this._templates[partial]); } } /** * Helper Function, to Generate the desired Logic. * @param _network */ parseLogic(_network: ILogicNetwork) { let network = deepClone(_network); // Reference to the Own Object. const _this = this; // Update the Ids. network = updateIds(network); // Define the Flow of the Network. network = defineFlows(network); const context = analyzeLogic(network, { padSizeNames: true, // The Adapted Values shouldn't be stored in the Network-Object adaptGuard: (...args) => _this._adaptGuard(...args), adaptVariableName: (...args) => _this._adaptVariableName(...args) }); return context; } /** * Function to Get the Transitions of the Network, Sorted by there Priority * @param network The Network Describing the Logic. */ getTransitionDescriptions( network: ILogicNetwork, sort: "priority" | "id" = "priority" ): ITransitionDescription[] { const context = this.parseLogic(network); const transitions = Array.from(context.transitions.values()); transitions.sort(dynamicSort(sort)); return transitions; } protected _convertInput(definition: { // Amount of Tokens that will be consumed (Result must be greater the minTokens) consumed: IArcExpression; placeId: string; type: | "expression" | "inhibitor" | "multiexpression" | "test" | "value" | "variable"; minTokens: number; }): { placeId: string; minTokens: number; tokensToRemove: number; } { throw Error("Not implemented"); } protected _convertOutput(definition: { // Amount of Tokens that will be produced produced: IArcExpression; placeId: string; type: | "expression" | "inhibitor" | "multiexpression" | "test" | "value" | "variable"; maxTokens: number; }): { // Amount of Tokens that will be produced placeId: string; maxTokens: number; tokensToAdd: number; } { throw Error("Not implemented"); } /** * * @param network */ getParseableLogic(network: ILogicNetwork) { const _this = this; const context = this.parseLogic(network); const ret: IParseableLogic = { initialMarking: [], places: context.places, transitions: [], transitionsSortedByPriority: [], variables: context.variables, subscribedVariables: context.subscribedVariables, actions: [] }; const transtionsSortedById = this.getTransitionDescriptions(network, "id"); // Iterate over the const _createTrans = ( idx: number, trans: ITransitionDescription, length: number ) => { return { externalGuard: trans.adaptedExternalGuard, dynamicParams: trans.simplifiedDynamicParams, id: trans.id, consumed: Array.from(trans.inputs.consumed.values()).map((item) => _this._convertInput(item) ), avoided: Array.from(trans.inputs.prevents.values()), required: Array.from(trans.inputs.required.values()).map((item) => _this._convertInput(item) ), isAction: trans.isAction, label: trans.label, logicalGuard: trans.logicalGuard, produced: Array.from(trans.outputs.values()).map((item) => _this._convertOutput(item) ), priority: trans.priority, scope: trans.simplifiedScope, taskID: trans.taskID, triggers: trans.triggers, functionName: trans.functionName, mode: trans.mode, params: trans.params, isFirst: idx === 0, isLast: length - 1 === idx, maxTime: trans.maxTime, minTime: trans.minTime, useMaxTime: trans.useMaxTime, useTimes: trans.useTimes, locks: trans.locks, releases: trans.releases, idx }; }; for (const [idx, trans] of transtionsSortedById.entries()) { const _trans = _createTrans(idx, trans, transtionsSortedById.length); ret.transitions.push(_trans); if (trans.isAction) { ret.actions.push(deepClone(_trans)); } } const transtionsSortedByPriority = this.getTransitionDescriptions( network, "priority" ); for (const [idx, trans] of transtionsSortedByPriority.entries()) { const _trans = _createTrans( idx, trans, transtionsSortedByPriority.length ); ret.transitionsSortedByPriority.push(_trans); } if (ret.actions.length > 0) { ret.actions[0].isFirst = true; ret.actions[ret.actions.length - 1].isLast = true; } return ret; } /** * Function, which will generate the MainLoop. * @param network */ mainLoop(network: ILogicNetwork): string { throw new Error("Method not implemented."); } instanceCreation(context: IParsedLogic): string { throw new Error("Method not implemented."); } }