Skip to content

Commit

Permalink
feat: Improved running GM from vscode
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-coster committed Mar 31, 2023
1 parent 097c994 commit 2c6f3cf
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 24 deletions.
2 changes: 2 additions & 0 deletions packages/vscode/src/extension.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ export class StitchConfig {
return this.config.get<string>('task.run.defaultConfig') || null;
}
}

export const config = new StitchConfig();
3 changes: 3 additions & 0 deletions packages/vscode/src/extension.gml.mts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class GmlFile {
readonly dir: string;
readonly resourceType: YyResourceType;
readonly resourceName: string;
readonly globalFunctions: Map<string, ParsedNode> = new Map();

// Track any globals defined in this file
readonly globals: Set<string> = new Set();
Expand Down Expand Up @@ -70,6 +71,8 @@ export class GmlFile {
if (!node.name) {
continue;
}
this.globalFunctions.set(name, node);

const paramNames = node.info.map((p) => p.name);
this.addProjectCompletion(
name,
Expand Down
61 changes: 61 additions & 0 deletions packages/vscode/src/extension.project.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { Yy, Yyp, YypResource } from '@bscotch/yy';
import path from 'path';
import vscode from 'vscode';
import { StitchTaskDefinition, config } from './extension.config.mjs';
import { GmlFile } from './extension.gml.mjs';
import { GameMakerResource } from './extension.resource.mjs';

Expand Down Expand Up @@ -50,6 +51,64 @@ export class GameMakerProject

protected gmlFiles: Map<string, GmlFile> = new Map();

/**
* Generate a GML-parseable string showing how all global
* functions map to their scripts, in the format:
* `func1:script1,func2:script2,func3:script3`
*/
createFunctionScriptString() {
const asString = [...this.resources]
.reduce((acc, [, resource]) => {
if (resource.type !== 'scripts') {
return acc;
}
resource.gmlFiles.forEach((gmlFile) => {
gmlFile.globalFunctions.forEach((func) => {
if (!func.name) {
return;
}
acc.push(`${func.name}:${resource.name}`);
});
});

return acc;
}, [] as string[])
.join(',');
return asString;
}

async asRunTask() {
const taskDefinition: StitchTaskDefinition = {
type: 'stitch',
task: 'run',
compiler: config.runCompilerDefault,
config:
config.runConfigDefault ||
this.yyp.configs.children[0]?.name ||
this.yyp.configs.name,
projectName: this.name,
};
const command = await this.computeRunCommand(taskDefinition);
if (!command) {
return;
}
return new vscode.Task(
taskDefinition,
vscode.TaskScope.Workspace,
taskDefinition.task,
this.name,
new vscode.ProcessExecution(command.cmd, command.args, {
cwd: this.rootPath,
env: {
VSCODE_STITCH_VERSION: vscode.extensions.getExtension(
'bscotch.bscotch-stitch-vscode',
)?.packageJSON.version,
VSCODE_STITCH_SCRIPT_FUNCTIONS: this.createFunctionScriptString(),
},
}),
);
}

async openInIde() {
vscode.window.showInformationMessage(
`Opening project with GameMaker v${this.ideVersion}...`,
Expand Down Expand Up @@ -100,6 +159,8 @@ export class GameMakerProject
project: this.yypPath.fsPath,
config: options?.config ?? undefined,
yyc: options?.compiler === 'yyc',
noCache: false,
quiet: true,
});
}

Expand Down
33 changes: 9 additions & 24 deletions packages/vscode/src/extension.provider.mts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import os from 'os';
import process from 'process';
import vscode from 'vscode';
import { debounce } from './debounce.mjs';
import { StitchConfig, StitchTaskDefinition } from './extension.config.mjs';
import { config } from './extension.config.mjs';
import { GameMakerProject } from './extension.project.mjs';
import { GmlSpec, parseSpec } from './spec.mjs';

Expand Down Expand Up @@ -40,7 +40,7 @@ export class GmlProvider
globalHovers: Map<string, vscode.Hover> = new Map();
globalSignatures: Map<string, vscode.SignatureHelp> = new Map();
protected projects: GameMakerProject[] = [];
static config = new StitchConfig();
static config = config;

protected constructor(readonly spec: GmlSpec) {
for (const func of spec.functions) {
Expand Down Expand Up @@ -126,34 +126,19 @@ export class GmlProvider
return project;
}

// TODO: Make the runner use F5 somehow?
// TODO: Investigate GameMaker error objects/messages -- how can we get a problem matcher working?
// TODO: Add a problem matcher. What happens with a compile error vs. a runtime error?
async provideTasks(): Promise<vscode.Task[]> {
const tasks: vscode.Task[] = [];
if (!this.projects.length || !GmlProvider.config.autoDetectTasks) {
return tasks;
}
for (const project of this.projects) {
const taskDefinition: StitchTaskDefinition = {
type: 'stitch',
task: 'run',
compiler: GmlProvider.config.runCompilerDefault,
config:
GmlProvider.config.runConfigDefault ||
project.yyp.configs.children[0]?.name ||
project.yyp.configs.name,
projectName: project.name,
};
const command = await project.computeRunCommand(taskDefinition);
if (!command) continue;
const task = new vscode.Task(
taskDefinition,
vscode.TaskScope.Workspace,
taskDefinition.task,
`Run ${project.name}`,
new vscode.ProcessExecution(command.cmd, command.args, {
cwd: project.rootPath,
}),
);
tasks.push(task);
const task = await project.asRunTask();
if (task) {
tasks.push(task);
}
}
return tasks;
}
Expand Down

0 comments on commit 2c6f3cf

Please sign in to comment.