Skip to content

Commit

Permalink
let editor extensions contribute experiments (#10252)
Browse files Browse the repository at this point in the history
* let editor extensions contribute experiments

* add log level to logger

* fix typing

* more typings fixes
  • Loading branch information
riknoll authored Oct 31, 2024
1 parent e3e9ec7 commit ce89ae0
Show file tree
Hide file tree
Showing 24 changed files with 200 additions and 70 deletions.
8 changes: 4 additions & 4 deletions cli/buildengine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -762,12 +762,12 @@ export async function compileWithLocalCompileService(extinfo: pxtc.ExtensionInfo
const resp = await runDockerCompileAsync(extinfo.compileData);

if (resp.hexfile) {
console.log("Compile successful");
pxt.log("Compile successful");
}
else {
console.log("Compile failed");
console.log(resp.stderr)
console.log(resp.stdout)
pxt.log("Compile failed");
pxt.log(resp.stderr)
pxt.log(resp.stdout)
}

return resp.hexfile && {
Expand Down
2 changes: 1 addition & 1 deletion cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7521,7 +7521,7 @@ export function mainCli(targetDir: string, args: string[] = process.argv.slice(2

if (process.env["PXT_DEBUG"]) {
pxt.options.debug = true;
pxt.debug = pxt.log;
pxt.setLogLevel(pxt.LogLevel.Debug);
}

if (process.env["PXT_ASMDEBUG"]) {
Expand Down
4 changes: 3 additions & 1 deletion cli/commandparser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ export class CommandParser {
const debugFlag = flagName || match[2];
if (debugFlag == "debug" || debugFlag == "d" || debugFlag == "dbg") {
pxt.options.debug = true;
pxt.debug = console.log;
if (pxt.options.debug) {
pxt.setLogLevel(pxt.LogLevel.Debug);
}
pxt.log(`debug mode`);
if (!flagName)
continue;
Expand Down
4 changes: 3 additions & 1 deletion kiosk/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ window.addEventListener("DOMContentLoaded", () => {
const bundle = (window as any).pxtTargetBundle as pxt.TargetBundle;

pxt.options.debug = /dbg=1/i.test(window.location.href);
if (pxt.options.debug) pxt.debug = console.debug;
if (pxt.options.debug) {
pxt.setLogLevel(pxt.LogLevel.Debug)
}

pxt.setupWebConfig((window as any).pxtConfig || pxt.webConfig);
pxt.setAppTarget(bundle);
Expand Down
12 changes: 12 additions & 0 deletions localtypings/pxteditor.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,7 @@ declare namespace pxt.editor {
blocklyToolbox: ToolboxDefinition;
monacoToolbox: ToolboxDefinition;
projectView: IProjectView;
showNotification: (msg: string) => void;
}

export interface IToolboxOptions {
Expand Down Expand Up @@ -1152,6 +1153,17 @@ declare namespace pxt.editor {
// Used with @codeStart, @codeStop metadata (MINECRAFT HOC ONLY)
onCodeStart?: () => void;
onCodeStop?: () => void;

experiments?: Experiment[];
}

export interface Experiment {
id: string; // == field in apptheme also assumes image at /static/experiments/ID.png
name: string;
description: string;
feedbackUrl?: string; // allows user to put feedback
enableOnline?: boolean; // requires internet connection, disable in offline app
onClick?: () => void; // code to run when the experiment is clicked
}

export interface FieldExtensionOptions {
Expand Down
5 changes: 3 additions & 2 deletions multiplayer/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ window.addEventListener("DOMContentLoaded", () => {
const bundle = (window as any).pxtTargetBundle as pxt.TargetBundle;

pxt.options.debug = /dbg=1/i.test(window.location.href);
if (pxt.options.debug)
pxt.debug = console.debug;
if (pxt.options.debug) {
pxt.setLogLevel(pxt.LogLevel.Debug);
}

pxt.setupWebConfig((window as any).pxtConfig || pxt.webConfig);
pxt.setAppTarget(bundle);
Expand Down
29 changes: 19 additions & 10 deletions pxteditor/experiments.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
export interface Experiment {
id: string; // == field in apptheme also assumes image at /static/experiments/ID.png
name: string;
description: string;
feedbackUrl?: string; // allows user to put feedback
enableOnline?: boolean; // requires internet connection, disable in offline app
}
import Experiment = pxt.editor.Experiment;

function key(experiment: Experiment | string): string {
const id = (typeof experiment === "object") ? experiment.id : experiment;
return `experiments-${id}`
}

let editorExtensionExperiments: Experiment[];

export function setEditorExtensionExperiments(experiments: Experiment[]) {
editorExtensionExperiments = experiments;
}

export function syncTheme() {
const theme: pxt.Map<boolean> = <pxt.Map<boolean>><any>pxt.savedAppTheme();
const r: pxt.Map<string | number> = {};
Expand All @@ -31,7 +31,7 @@ export function syncTheme() {
export function all(): Experiment[] {
const ids = pxt.appTarget.appTheme.experiments;
if (!ids) return [];
return [
const exps: Experiment[] = [
{
id: "print",
name: lf("Print Code"),
Expand Down Expand Up @@ -182,7 +182,11 @@ export function all(): Experiment[] {
name: lf("Time Machine"),
description: lf("Save and restore past versions of a project")
},
].filter(experiment => ids.indexOf(experiment.id) > -1 && !(pxt.BrowserUtils.isPxtElectron() && experiment.enableOnline));
];

return exps.filter(experiment => ids.indexOf(experiment.id) > -1)
.concat(editorExtensionExperiments || [])
.filter(experiment => !(pxt.BrowserUtils.isPxtElectron() && experiment.enableOnline));
}

export function clear() {
Expand All @@ -199,7 +203,12 @@ export function isEnabled(experiment: Experiment | string): boolean {
}

export function toggle(experiment: Experiment) {
setState(experiment, !isEnabled(experiment));
if (experiment.onClick) {
experiment.onClick();
}
else {
setState(experiment, !isEnabled(experiment));
}
}

export function state(): string {
Expand Down
49 changes: 48 additions & 1 deletion pxtlib/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,77 @@ namespace pxt {
debug(...args: any[]): void;
error(...args: any[]): void;
warn(...args: any[]): void;

setLogLevel(level: LogLevel): void;
getLogLevel(): LogLevel;
}

export enum LogLevel {
Debug = 0,
Info = 1,
Log = 1,
Warning = 2,
Error = 3
}

class ConsoleLogger implements Logger {
export class ConsoleLogger implements Logger {
protected logLevel: LogLevel;

constructor() {
this.setLogLevel(LogLevel.Info);
}

setLogLevel(level: LogLevel): void {
this.logLevel = level;
}

getLogLevel(): LogLevel {
return this.logLevel;
}

info(...args: any[]): void {
if (!this.shouldLog(LogLevel.Info)) return;

if (console?.info) {
console.info.call(null, ...args);
}
}

log(...args: any[]): void {
if (!this.shouldLog(LogLevel.Log)) return;

if (console?.log) {
console.log.call(null, ...args);
}
}

debug(...args: any[]): void {
if (!this.shouldLog(LogLevel.Debug)) return;

if (console?.debug) {
console.debug.call(null, ...args);
}
}

error(...args: any[]): void {
if (!this.shouldLog(LogLevel.Error)) return;

if (console?.error) {
console.error.call(null, ...args);
}
}

warn(...args: any[]): void {
if (!this.shouldLog(LogLevel.Warning)) return;

if (console?.warn) {
console.warn.call(null, ...args);
}
}

protected shouldLog(level: LogLevel) {
return level >= this.logLevel;
}
}

let logger: Logger = new ConsoleLogger();
Expand All @@ -62,6 +101,14 @@ namespace pxt {
}

export function setLogger(impl: Logger) {
const level = logger?.getLogLevel();
logger = impl;
if (level !== undefined) {
logger.setLogLevel(level);
}
}

export function setLogLevel(level: LogLevel) {
logger.setLogLevel(level);
}
}
22 changes: 11 additions & 11 deletions pxtsim/allocator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ namespace pxsim {
} else {
let instIdx = (<PinInstantiationIdx>pinDef.target).pinInstantiationIdx;
if (!(!!instPins && instPins[instIdx] !== undefined)) {
pxt.log(`error: parts no pin found for PinInstantiationIdx: ${instIdx}. (Is the part missing an ArgumentRole or "trackArgs=" annotations?)`);
pxsim.log(`error: parts no pin found for PinInstantiationIdx: ${instIdx}. (Is the part missing an ArgumentRole or "trackArgs=" annotations?)`);
return undefined;
}
pinTarget = instPins[instIdx];
Expand Down Expand Up @@ -282,13 +282,13 @@ namespace pxsim {
fnNms.forEach(fnNm => { if (this.opts.fnArgs[fnNm]) this.opts.fnArgs[fnNm].forEach((targetArg: string) => { callsitesTrackedArgsHash[targetArg] = 1 }); });
let callsitesTrackedArgs: string[] = Object.keys(callsitesTrackedArgsHash);
if (!(!!callsitesTrackedArgs && !!callsitesTrackedArgs.length)) {
pxt.log(`error: parts failed to read pin(s) from callsite for: ${fnNms}`);
pxsim.log(`error: parts failed to read pin(s) from callsite for: ${fnNms}`);
return undefined;
}
callsitesTrackedArgs.forEach(fnArgsStr => {
const fnArgsSplit = fnArgsStr.split(",");
if (fnArgsSplit.length != fnAlloc.argumentRoles.length) {
pxt.log(`error: parts mismatch between number of arguments at callsite (function name: ${fnNms}) vs number of argument roles in part definition (part: ${name}).`);
pxsim.log(`error: parts mismatch between number of arguments at callsite (function name: ${fnNms}) vs number of argument roles in part definition (part: ${name}).`);
return;
}
let instPins: PinTarget[] = [];
Expand Down Expand Up @@ -352,7 +352,7 @@ namespace pxsim {
let totalSpaceNeeded = colCounts.map(d => d.colCount).reduce((p, n) => p + n, 0);
let extraSpace = totalColumnsCount - totalSpaceNeeded;
if (extraSpace <= 0) {
pxt.log("Not enough breadboard space!");
pxsim.log("Not enough breadboard space!");
//TODO
}
let padding = Math.floor(extraSpace / (partsCount - 1 + 2));
Expand Down Expand Up @@ -474,7 +474,7 @@ namespace pxsim {
return this.opts.getBBCoord(loc);
});
if (!firstTopAndBot[0] || !firstTopAndBot[1]) {
pxt.debug(`No more available "${location}" locations!`);
pxsim.debug(`No more available "${location}" locations!`);
//TODO
}
let nearTop = visuals.findClosestCoordIdx(nearestCoord, firstTopAndBot) == 0;
Expand Down Expand Up @@ -513,12 +513,12 @@ namespace pxsim {
return <BBLoc>location;
} else if (location === "MOSI" || location === "MISO" || location === "SCK") {
if (!this.opts.boardDef.spiPins)
pxt.debug("No SPI pin mappings found!");
pxsim.debug("No SPI pin mappings found!");
let pin = (<any>this.opts.boardDef.spiPins)[location as string] as string;
return { type: "dalboard", pin: pin };
} else if (location === "SDA" || location === "SCL") {
if (!this.opts.boardDef.i2cPins)
pxt.debug("No I2C pin mappings found!");
pxsim.debug("No I2C pin mappings found!");
let pin = (<any>this.opts.boardDef.i2cPins)[location as string] as string;
return { type: "dalboard", pin: pin };
} else {
Expand All @@ -527,7 +527,7 @@ namespace pxsim {
let mbPin = <MicrobitPin>location;
let boardPin = this.opts.boardDef.gpioPinMap[mbPin] || mbPin;
if (!boardPin) { // this pin is internal
pxt.debug(`unknown pin location for ${mbPin}`)
pxsim.debug(`unknown pin location for ${mbPin}`)
return undefined;
}
return { type: "dalboard", pin: boardPin };
Expand All @@ -536,23 +536,23 @@ namespace pxsim {
private getBoardGroundPin(): string {
let pin = this.opts.boardDef.groundPins && this.opts.boardDef.groundPins[0] || null;
if (!pin) {
pxt.debug("No available ground pin on board!");
pxsim.debug("No available ground pin on board!");
//TODO
}
return pin;
}
private getBoardThreeVoltPin(): string {
let pin = this.opts.boardDef.threeVoltPins && this.opts.boardDef.threeVoltPins[0] || null;
if (!pin) {
pxt.debug("No available 3.3V pin on board!");
pxsim.debug("No available 3.3V pin on board!");
//TODO
}
return pin;
}
private getBoardFiveVoltPin(): string {
let pin = this.opts.boardDef.fiveVoltPins && this.opts.boardDef.fiveVoltPins[0] || null;
if (!pin) {
pxt.debug("No available 5V pin on board!");
pxsim.debug("No available 5V pin on board!");
//TODO
}
return pin;
Expand Down
2 changes: 1 addition & 1 deletion pxtsim/debugProtocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ namespace pxsim.protocol {

public sendResponse(response: DebugProtocol.Response): void {
if (response.seq > 0) {
pxt.error(`attempt to send more than one response for command ${response.command}`);
pxsim.error(`attempt to send more than one response for command ${response.command}`);
} else {
this.send('response', response);
}
Expand Down
4 changes: 2 additions & 2 deletions pxtsim/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,9 +523,9 @@ namespace pxsim {

const serviceWorkerUrl = window.location.href.replace(/---simulator.*$/, "---simserviceworker");
navigator.serviceWorker.register(serviceWorkerUrl).then(function (registration) {
pxt.log("Simulator ServiceWorker registration successful with scope: ", registration.scope);
pxsim.log("Simulator ServiceWorker registration successful with scope: ", registration.scope);
}, function (err) {
pxt.log("Simulator ServiceWorker registration failed: ", err);
pxsim.log("Simulator ServiceWorker registration failed: ", err);
});
}
}
Expand Down
Loading

0 comments on commit ce89ae0

Please sign in to comment.