Commit f15ce1cc authored by Dominic's avatar Dominic
Browse files

Implement ImportFile, Improve taskManagerTypes

parent 844da224
Pipeline #29482 passed with stages
in 3 minutes and 7 seconds
...@@ -12,7 +12,11 @@ export const importFileCtrl = ['$rootScope', '$routeParams', 'fileTypes', 'taskM ...@@ -12,7 +12,11 @@ export const importFileCtrl = ['$rootScope', '$routeParams', 'fileTypes', 'taskM
const fileType = $routeParams.fileType; const fileType = $routeParams.fileType;
const container = document.getElementById("importfile-react-container"); const container = document.getElementById("importfile-react-container");
const importFiles = React.createElement(ImportFile, { fileType: fileType }, null); const importFiles = React.createElement(
ImportFile,
{ fileType: fileType, taskManager: taskManager },
null
);
const render = () => { const render = () => {
ReactDOM.render( ReactDOM.render(
......
...@@ -6,7 +6,7 @@ import { Button, Checkbox, Modal, ProgressBar } from "react-bootstrap"; ...@@ -6,7 +6,7 @@ import { Button, Checkbox, Modal, ProgressBar } from "react-bootstrap";
import { LTSTransition } from "../../../../../../../../pseuco-shared-components/lts/lts"; import { LTSTransition } from "../../../../../../../../pseuco-shared-components/lts/lts";
import { TranslatorTraceReturndata } from "../../../../../../worker/translatorTrace"; import { TranslatorTraceReturndata } from "../../../../../../worker/translatorTrace";
import { StateKey } from "../../../../../editors/ltsEditor/ltsEditorTypes"; import { StateKey } from "../../../../../editors/ltsEditor/ltsEditorTypes";
import { WorkerConfigurations } from "../../../../../util/taskmanagerTypes"; import { TranslatorWorkerConfiguration } from "../../../../../util/taskmanagerTypes";
import { pluralize } from "../../../../../utils"; import { pluralize } from "../../../../../utils";
import { ActionComponentAPI } from "../../ActionComponentHost"; import { ActionComponentAPI } from "../../ActionComponentHost";
import { ActionBehavior, DataActionComponent } from "../../actions"; import { ActionBehavior, DataActionComponent } from "../../actions";
...@@ -84,12 +84,12 @@ export const TraceModal: DataActionComponent<{prefilledTrace?: LTSTransition[]}> ...@@ -84,12 +84,12 @@ export const TraceModal: DataActionComponent<{prefilledTrace?: LTSTransition[]}>
setStatus("running"); setStatus("running");
const taskData : WorkerConfigurations["trace"]["workerData"]= { const taskData : TranslatorWorkerConfiguration["trace"]["workerData"]= {
stepCount: stepCount, stepCount: stepCount,
dataId: data.extended.dataId, dataId: data.extended.dataId,
startState: currentState startState: currentState
}; };
const traceTaskId = worker.submitTask<"trace">('trace', taskData, (resultData: TranslatorTraceReturndata["data"], completed: TranslatorTraceReturndata["taskCompleted"]) => { const traceTaskId = worker.submitTask<"trace">('trace', taskData, (resultData, completed) => {
if (completed && resultData === null) { if (completed && resultData === null) {
// computation exceeded step count // computation exceeded step count
setTraceTask(undefined); setTraceTask(undefined);
......
import { PetriNetObject } from '@pseuco/colored-petri-nets/dist/coloredPetriNets';
import React, { useCallback, useEffect, useState } from 'react';
import { Button, ProgressBar } from 'react-bootstrap';
import { LTS } from '../../../../pseuco-shared-components/lts/lts';
import { TaskManagerAPI } from '../util/taskmanagerTypes';
import { redirect } from '../utils';
import { FilesAPI, fileTypes } from './filesAPI';
import { FileTypes } from './fileTypes';
export type PossibleImport = {
formatName: string,
data: LTS | PetriNetObject
};
let debounceTimeoutId: number | null = null;
export const ImportFile: React.FC<{
fileType: keyof FileTypes,
taskManager: TaskManagerAPI
}> = ({ fileType: fileTypeName, taskManager }) => {
const fileType = fileTypes[fileTypeName];
const [currentTask, setCurrentTask] = useState<null | number>(null);
const [, _setImportData] = useState("");
const fullscreenMode = false; // TODO: detect fullscreen, embed
const [possibleImports, setPossibleImports] = useState<PossibleImport[]>([]);
const [worker] = useState(taskManager.requestWorker("importer", (e) => {
console.log("Importer worker crashed",e);
}));
useEffect(() => () => worker.terminateWorker());
const parse = useCallback((newstr: string) => {
// sanity check
if (fileTypeName === "pseuco" || fileTypeName === "ccs") return;
// kill running workers
if (currentTask !== null) worker.cancelTask(currentTask);
const taskId = worker.submitTask('parse', {
data: newstr,
fileType: fileTypeName
}, ({possibleImports}) => {
setPossibleImports(possibleImports);
setCurrentTask(null);
}, null, 5);
setCurrentTask(taskId);
}, [currentTask, fileTypeName, worker]);
const setImportData = (newData: string) => {
_setImportData(newData);
if (debounceTimeoutId !== null) window.clearTimeout(debounceTimeoutId);
debounceTimeoutId = window.setTimeout(() => {
parse(newData);
}, 1000);
};
const performImport = (possibleImports: PossibleImport): void => {
const file = FilesAPI.createFile(fileTypeName);
FilesAPI.setFileContent(file, possibleImports.data);
redirect("edit/local/" + file.id);
};
return <div className="container">
<h1>Import { fileType.fullName } file</h1>
<p>Paste or type a {fileType.fullName} file below. We support {fileType.importableFilesStatement}.</p>
<textarea onChange={(e) => setImportData(e.target.value)} className="import-box"></textarea>
{!fullscreenMode ?
<ProgressBar active={currentTask !== null} striped now={100} />
: null}
{possibleImports.length === 0 ?
<p>
Sorry, we can't parse the data you provided. Please make sure you are using a supported file format.
</p>
: possibleImports.map((possibleImport, index) =>
<Button key={index} onClick={() => performImport(possibleImport)} bsStyle="success" style={{ marginRight: 10 }}>
<span className="glyphicon glyphicon-import pad-right-5" /> Import as {possibleImport.formatName}
</Button>
)
}
</div>;
};
\ No newline at end of file
...@@ -7,6 +7,7 @@ import { TranslateWorkerData, TranslateWorkerResultData } from '../fileEdit/data ...@@ -7,6 +7,7 @@ import { TranslateWorkerData, TranslateWorkerResultData } from '../fileEdit/data
import { DataForTranslationWorker } from '../fileEdit/dataAuthority/dataAuthorityUtils'; import { DataForTranslationWorker } from '../fileEdit/dataAuthority/dataAuthorityUtils';
import { ExportLTSFormat } from '../fileEdit/fileEditUi/actionManager/actions/exportLTS/exportLTS'; import { ExportLTSFormat } from '../fileEdit/fileEditUi/actionManager/actions/exportLTS/exportLTS';
import { FileTypes } from '../files/fileTypes'; import { FileTypes } from '../files/fileTypes';
import { PossibleImport } from '../files/ImportFile';
import { Callback } from '../utils'; import { Callback } from '../utils';
import { LTSExplorationData, LTSExplorationReturnData } from './ltsExplorer'; import { LTSExplorationData, LTSExplorationReturnData } from './ltsExplorer';
...@@ -21,7 +22,7 @@ export type GenericWorkerData = { ...@@ -21,7 +22,7 @@ export type GenericWorkerData = {
dataId: number dataId: number
} }
export type WorkerConfigurations = { export type TranslatorWorkerConfiguration = {
trace: { trace: {
workerData: TranslatorTraceData, workerData: TranslatorTraceData,
resultData: TranslatorTraceReturndata resultData: TranslatorTraceReturndata
...@@ -34,7 +35,6 @@ export type WorkerConfigurations = { ...@@ -34,7 +35,6 @@ export type WorkerConfigurations = {
data: null | { data: null | {
dataId: number dataId: number
}, },
taskCompleted: boolean
} }
}, },
storeData: { storeData: {
...@@ -43,7 +43,6 @@ export type WorkerConfigurations = { ...@@ -43,7 +43,6 @@ export type WorkerConfigurations = {
data: null | { data: null | {
dataId: number dataId: number
}, },
taskCompleted: boolean
} }
}, },
exploreLts: { exploreLts: {
...@@ -59,7 +58,6 @@ export type WorkerConfigurations = { ...@@ -59,7 +58,6 @@ export type WorkerConfigurations = {
data: null | { data: null | {
}, },
taskCompleted: boolean
} }
}, },
minimizeLts: { minimizeLts: {
...@@ -71,7 +69,6 @@ export type WorkerConfigurations = { ...@@ -71,7 +69,6 @@ export type WorkerConfigurations = {
command: "minimized", command: "minimized",
data: LTSFileData data: LTSFileData
}, },
taskCompleted: boolean
} }
}, },
translate: { translate: {
...@@ -87,7 +84,6 @@ export type WorkerConfigurations = { ...@@ -87,7 +84,6 @@ export type WorkerConfigurations = {
actions: Array<LTSTransition["label"]>, actions: Array<LTSTransition["label"]>,
complete: boolean complete: boolean
}, },
taskCompleted: boolean
} }
}, },
traceForAction: { traceForAction: {
...@@ -102,7 +98,6 @@ export type WorkerConfigurations = { ...@@ -102,7 +98,6 @@ export type WorkerConfigurations = {
command: "trace", command: "trace",
trace: LTSTransition[] trace: LTSTransition[]
}, },
taskCompleted: boolean
} }
}, },
exportLts: { exportLts: {
...@@ -118,36 +113,63 @@ export type WorkerConfigurations = { ...@@ -118,36 +113,63 @@ export type WorkerConfigurations = {
command: "failure", command: "failure",
error: string error: string
}, },
taskCompleted: boolean
} }
} }
}; };
// TODO: make resultData less redundant, flatten resultData into resultData.data and remove taskCompleted:boolean
export type TranslatorWorkerAPI = { type MinimalWorkerConfiguration<T> = { [k in keyof T]: {
id: TaskID; workerData: {
terminateWorker: (finishCallback?: FinishCallback) => void; }, resultData: {
submitTask: <T extends keyof WorkerConfigurations>( data: unknown,
taskName: T & string, }
data: WorkerConfigurations[T]["workerData"], }}
export type WorkerAPI<Configuration extends MinimalWorkerConfiguration<Configuration>> = {
id: TaskID,
terminateWorker: (FinishCallback?: FinishCallback) => void,
submitTask: <Task extends keyof Configuration>(
taskName: Task & string,
data: Configuration[Task]["workerData"],
resultCallback: null | (( resultCallback: null | ((
resultData: WorkerConfigurations[T]["resultData"]["data"], resultData: Configuration[Task]["resultData"]["data"],
completed: WorkerConfigurations[T]["resultData"]["taskCompleted"] completed: boolean
) => void), ) => void),
CancellationCallback: null | (() => void), CancellationCallback : null | (() => void),
priority: TaskPriority priority: TaskPriority
) => TaskID; ) => TaskID,
cancelTask: (taskId: TaskID) => void; cancelTask: (taskId: TaskID) => void,
isTerminating: () => boolean; isTerminating: () => boolean
}; };
export type ImporterWorkerConfiguration = {
parse: {
workerData: {
fileType: "lts" | "cpn" | "cpnpp",
data: string
},
resultData: {
data: {
possibleImports: PossibleImport[]
}
}
}
}
export type ImporterWorkerAPI = WorkerAPI<ImporterWorkerConfiguration>;
export type TranslatorWorkerAPI = WorkerAPI<TranslatorWorkerConfiguration>;
export type TaskType = "minimizeLts" | "translate" | "dropData" | "exploreLts" | "prioritizeStates" | "storeData"; export type TaskType = "minimizeLts" | "translate" | "dropData" | "exploreLts" | "prioritizeStates" | "storeData";
export type PseucoWorkerType = "translator" | "importer"; export type PseucoWorkers = {
translator: TranslatorWorkerAPI,
importer: ImporterWorkerAPI
}
export type PseucoWorkerType = keyof PseucoWorkers;
export type TaskManagerAPI = { export type TaskManagerAPI = {
getRunningTaskCount: () => number; getRunningTaskCount: () => number;
requestWorker: (type: PseucoWorkerType, crashCallback: (error: any) => void) => TranslatorWorkerAPI; requestWorker: <T extends PseucoWorkerType> (type: T & string, crashCallback: (error: any) => void) => PseucoWorkers[T];
}; };
export type WorkerData = { export type WorkerData = {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment