Skip to content

Commit 5dfc951

Browse files
committed
Also set time limit from competitive companion
1 parent 9de1b62 commit 5dfc951

File tree

1 file changed

+68
-41
lines changed

1 file changed

+68
-41
lines changed

src/views/judge/provider/JudgeViewProvider.ts

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ function getExitCodeStatus(
5252
return Status.WA;
5353
}
5454

55+
function coerceToObject(data: unknown): unknown {
56+
if (typeof data === 'object' && data !== null) {
57+
return data;
58+
}
59+
return {};
60+
}
61+
function coerceToArray(data: unknown): unknown[] {
62+
const arr = [];
63+
if (Array.isArray(data)) {
64+
for (const obj of data) {
65+
arr.push(coerceToObject(obj));
66+
}
67+
}
68+
return arr;
69+
}
70+
5571
export default class extends BaseViewProvider<ProviderMessage, WebviewMessage> {
5672
private _state: Map<number, IState> = new Map(); // Map also remembers insertion order :D
5773
private _timeLimit = 0;
@@ -63,7 +79,7 @@ export default class extends BaseViewProvider<ProviderMessage, WebviewMessage> {
6379
this.loadCurrentFileData();
6480
break;
6581
case ProviderMessageType.NEXT:
66-
void this._run(this.addTestcaseToFile(), true);
82+
this._nextTestcase();
6783
break;
6884
case ProviderMessageType.ACTION:
6985
this._action(msg);
@@ -101,6 +117,7 @@ export default class extends BaseViewProvider<ProviderMessage, WebviewMessage> {
101117
for (const id of this._state.keys()) {
102118
super._postMessage({ type: WebviewMessageType.DELETE, id });
103119
}
120+
this._timeLimit = 0;
104121
this._state.clear();
105122

106123
const file = vscode.window.activeTextEditor?.document.fileName;
@@ -110,22 +127,14 @@ export default class extends BaseViewProvider<ProviderMessage, WebviewMessage> {
110127
}
111128
super._postMessage({ type: WebviewMessageType.SHOW, visible: true });
112129

113-
const fileData = super.readStorage()[file];
114-
const data: Partial<IFileData> =
115-
typeof fileData === 'object' && fileData !== null ? fileData : {};
116-
this._timeLimit = data.timeLimit ?? 0;
117-
118-
const testcases = Array.isArray(data.testcases) ? data.testcases : [];
130+
const fileData = coerceToObject(
131+
super.readStorage()[file],
132+
) as Partial<IFileData>;
133+
const testcases = coerceToArray(fileData.testcases);
134+
this._timeLimit = fileData.timeLimit ?? 0;
119135
for (let i = 0; i < testcases.length; i++) {
120-
const testcase: Partial<ITestcase> =
121-
testcases[i] !== null && typeof testcases[i] === 'object'
122-
? (testcases[i] as Partial<ITestcase>)
123-
: {};
124-
this._state.set(
125-
this._newId,
126-
this._createTestcaseState(this._newId, testcase),
127-
);
128-
this._newId++;
136+
const testcase = coerceToObject(testcases[i]) as Partial<ITestcase>;
137+
this._addTestcase(testcase);
129138
}
130139

131140
super._postMessage({
@@ -149,40 +158,46 @@ export default class extends BaseViewProvider<ProviderMessage, WebviewMessage> {
149158
};
150159
});
151160

152-
if (file === vscode.window.activeTextEditor?.document.fileName) {
161+
// biome-ignore lint/style/noNonNullAssertion: Caller guarantees there is an active editor and passes a non-empty string
162+
if (file === vscode.window.activeTextEditor!.document.fileName) {
153163
this.deleteAll();
154-
164+
this._timeLimit = data.timeLimit;
155165
for (const testcase of testcases) {
156-
this.addTestcaseToFile(file, testcase);
166+
this._addTestcase(testcase);
157167
}
168+
this._saveFileData();
169+
170+
super._postMessage({
171+
type: WebviewMessageType.INITIAL_STATE,
172+
timeLimit: data.timeLimit,
173+
});
158174
} else {
159-
super.writeStorage(file, testcases);
175+
const fileData: IFileData = {
176+
timeLimit: data.timeLimit,
177+
testcases,
178+
};
179+
super.writeStorage(file, fileData);
160180
}
161181
}
162182

163-
addTestcaseToFile(file?: string, testcase?: ITestcase) {
164-
const pickedFile =
165-
file ?? vscode.window.activeTextEditor?.document.fileName;
166-
if (!pickedFile) {
167-
return -1;
168-
}
183+
addTestcaseToFile(file: string, testcase: ITestcase) {
184+
// used by stress view
169185

170-
if (pickedFile === vscode.window.activeTextEditor?.document.fileName) {
171-
this._state.set(
172-
this._newId,
173-
this._createTestcaseState(this._newId, testcase),
174-
);
175-
this._saveFileData();
176-
return this._newId++;
177-
}
178-
if (testcase) {
179-
const fileData = super.readStorage()[pickedFile];
180-
const state = Array.isArray(fileData) ? fileData : [];
181-
state.push(testcase);
182-
super.writeStorage(pickedFile, state);
186+
// biome-ignore lint/style/noNonNullAssertion: Caller guarantees there is an active editor and passes a non-empty string
187+
if (file === vscode.window.activeTextEditor!.document.fileName) {
188+
this._addTestcase(testcase);
189+
} else {
190+
const fileData = coerceToObject(
191+
super.readStorage()[file],
192+
) as Partial<IFileData>;
193+
const testcases = coerceToArray(fileData.testcases);
194+
testcases.push(testcase);
195+
const data: IFileData = {
196+
timeLimit: fileData.timeLimit ?? 0,
197+
testcases,
198+
};
199+
super.writeStorage(file, data);
183200
}
184-
185-
return -1;
186201
}
187202

188203
runAll() {
@@ -203,6 +218,10 @@ export default class extends BaseViewProvider<ProviderMessage, WebviewMessage> {
203218
}
204219
}
205220

221+
private _nextTestcase() {
222+
void this._run(this._addTestcase(), true);
223+
}
224+
206225
private _action({ id, action }: IActionMessage) {
207226
switch (action) {
208227
case Action.RUN:
@@ -262,6 +281,14 @@ export default class extends BaseViewProvider<ProviderMessage, WebviewMessage> {
262281
super.writeStorage(file, fileData);
263282
}
264283

284+
private _addTestcase(testcase?: Partial<ITestcase>) {
285+
this._state.set(
286+
this._newId,
287+
this._createTestcaseState(this._newId, testcase),
288+
);
289+
return this._newId++;
290+
}
291+
265292
private _createTestcaseState(id: number, testcase?: Partial<ITestcase>) {
266293
// using partial type to have backward compatibility with old testcases
267294
// create a new testcase in webview and fill it in later

0 commit comments

Comments
 (0)