-
Notifications
You must be signed in to change notification settings - Fork 10
/
execute.ts
136 lines (105 loc) · 4.63 KB
/
execute.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* Script that executes the selected text in Unreal Engine, if nothing is selected the entire active document will be executed.
*/
import * as vscode from 'vscode';
import * as crypto from 'crypto';
import * as path from 'path';
import * as fs from 'fs';
import * as utils from '../modules/utils';
import * as remoteHandler from "../modules/remote-handler";
import * as vsCodeExec from "../modules/code-exec";
import { IRemoteExecutionMessageCommandOutputData, RemoteExecution } from "unreal-remote-execution";
const INPUT_TEMP_PYTHON_FILENAME = "temp_exec";
// ------------------------------------------------------------------------------------------
// Filepaths
// ------------------------------------------------------------------------------------------
/**
* Get a filepath where a temp python file can be saved
* @param commandId: The command ID will be appended to the filename
*/
function getTempPythonExecFilepath(commandId: string) {
return path.join(utils.getExtentionTempDir(), `${INPUT_TEMP_PYTHON_FILENAME}-${commandId}.py`);
}
// ------------------------------------------------------------------------------------------
// File handlers
// ------------------------------------------------------------------------------------------
/**
* Clean up all temp files related to a spesific command
* @param commandId The ID of which files to delete
*/
async function cleanUpTempFiles(commandId: string) {
const filepaths = [
getTempPythonExecFilepath(commandId),
];
for (const filepath of filepaths) {
if (fs.existsSync(filepath)) {
fs.unlinkSync(filepath);
}
}
}
// ------------------------------------------------------------------------------------------
// Remote Exec
// ------------------------------------------------------------------------------------------
/**
* Handle data recived from the Unreal python server
* Because 'vscode_execute.py' re-directs all of the output through a .txt file, `message` will be empty,
* instead use `readResponse` to fetch the output.
* */
function handleResponse(message: IRemoteExecutionMessageCommandOutputData, commandId: string) {
// If user is debugging MB, all output will automatically be appended to the debug console
if (utils.isDebuggingUnreal()) {
vscode.debug.activeDebugConsole.appendLine(">>>");
return;
}
const outputChannel = utils.getOutputChannel();
if (!outputChannel) {
return;
}
for (const output of message.output) {
outputChannel.appendLine(output.output.trimEnd());
}
outputChannel.appendLine(">>>");
if (utils.getExtensionConfig().get("execute.showOutput")) {
outputChannel.show(true);
}
// Cleanup all temp that were written by this command
cleanUpTempFiles(commandId);
}
export async function main() {
if (!vscode.window.activeTextEditor) {
return;
}
// Generate a random id, used to differentiate from other commands run at the same time
const commandId = crypto.randomUUID();
// Get a file to execute
const tempExecFilepath = getTempPythonExecFilepath(commandId);
const fileToExecute = vsCodeExec.getFileToExecute(tempExecFilepath);
if (!fileToExecute) {
return;
}
const extensionConfig = utils.getExtensionConfig();
// Clear the output channel if enabled in user settings
if (extensionConfig.get("execute.clearOutput")) {
const outputChannel = utils.getOutputChannel(false);
if (outputChannel) {
outputChannel.clear();
}
}
// Write an info file telling mb what script to run, etc.
const bIsDebugging = utils.isDebuggingUnreal();
const nameVar: string | undefined = extensionConfig.get("execute.name");
let vscodeData: any = {
"file": fileToExecute,
"__file__": vscode.window.activeTextEditor.document.uri.fsPath, // eslint-disable-line @typescript-eslint/naming-convention
"__name__": nameVar, // eslint-disable-line @typescript-eslint/naming-convention
// "id": commandId,
"isDebugging": bIsDebugging
};
// Set `vscodeData` as a global dict variable, that can be read by the python script
const globalVariables = { "vscode_globals": JSON.stringify(vscodeData) }; // eslint-disable-line @typescript-eslint/naming-convention
const execFile = utils.FPythonScriptFiles.getAbsPath(utils.FPythonScriptFiles.executeEntry);
const response = await remoteHandler.executeFile(execFile, globalVariables);
if (response) {
handleResponse(response, commandId);
}
}