Skip to content

Commit

Permalink
merged master
Browse files Browse the repository at this point in the history
  • Loading branch information
srietkerk committed Jan 27, 2025
2 parents 8336f42 + d2a55d3 commit bab52a2
Show file tree
Hide file tree
Showing 73 changed files with 1,947 additions and 767 deletions.
22 changes: 22 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,28 @@
"sourceMaps": false,
"outFiles": []
},
{
"name": "pxt serve (minecraft)",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/built/pxt.js",
"stopOnEntry": false,
"args": [
"serve",
"--noauth"
],
"cwd": "${workspaceRoot}/../pxt-minecraft",
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "development"
},
"console": "integratedTerminal",
"sourceMaps": false,
"outFiles": []
},
{
"name": "pxt serve (microbit)",
"type": "node",
Expand Down
73 changes: 58 additions & 15 deletions docfiles/pxtweb/cookieCompliance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,50 @@ namespace pxt {
let eventLogger: TelemetryQueue<string, Map<string>, Map<number>>;
let exceptionLogger: TelemetryQueue<any, string, Map<string>>;

type EventListener<T = any> = (payload: T) => void;
type EventSource<T> = {
subscribe(listener: (payload: T) => void): () => void;
emit(payload: T): void;
};

function createEventSource<T = any>(): EventSource<T> {
const listeners: EventListener<T>[] = [];

return {
subscribe(listener: EventListener<T>): () => void {
listeners.push(listener);
// Return an unsubscribe function
return () => {
const index = listeners.indexOf(listener);
if (index !== -1) {
listeners.splice(index, 1);
}
};
},
emit(payload: T): void {
listeners.forEach(listener => listener(payload));
}
};
}

// performance measuring, added here because this is amongst the first (typescript) code ever executed
export namespace perf {
let enabled: boolean;

export const onMilestone = createEventSource<{ milestone: string, time: number, params?: Map<string> }>();
export const onMeasurement = createEventSource<{ name: string, start: number, duration: number, params?: Map<string> }>();

export let startTimeMs: number;
export let stats: {
// name, start, duration
durations: [string, number, number][],
// name, start, duration, params
durations: [string, number, number, Map<string>?][],
// name, event
milestones: [string, number][]
milestones: [string, number, Map<string>?][]
} = {
durations: [],
milestones: []
}
export function isEnabled() { return enabled; }
export let perfReportLogged = false
export function splitMs(): number {
return Math.round(performance.now() - startTimeMs)
Expand All @@ -75,8 +105,10 @@ namespace pxt {
return prettyStr(splitMs())
}

export function recordMilestone(msg: string, time: number = splitMs()) {
stats.milestones.push([msg, time])
export function recordMilestone(msg: string, params?: Map<string>) {
const time = splitMs()
stats.milestones.push([msg, time, params])
onMilestone.emit({ milestone: msg, time, params });
}
export function init() {
enabled = performance && !!performance.mark && !!performance.measure;
Expand All @@ -89,7 +121,7 @@ namespace pxt {
export function measureStart(name: string) {
if (enabled) performance.mark(`${name} start`)
}
export function measureEnd(name: string) {
export function measureEnd(name: string, params?: Map<string>) {
if (enabled && performance.getEntriesByName(`${name} start`).length) {
performance.mark(`${name} end`)
performance.measure(`${name} elapsed`, `${name} start`, `${name} end`)
Expand All @@ -98,7 +130,8 @@ namespace pxt {
let measure = e[0]
let durMs = measure.duration
if (durMs > 10) {
stats.durations.push([name, measure.startTime, durMs])
stats.durations.push([name, measure.startTime, durMs, params])
onMeasurement.emit({ name, start: measure.startTime, duration: durMs, params });
}
}
performance.clearMarks(`${name} start`)
Expand All @@ -108,34 +141,44 @@ namespace pxt {
}
export function report(filter: string = null) {
perfReportLogged = true;

if (enabled) {
const milestones: {[index: string]: number} = {};
const durations: {[index: string]: number} = {};
const milestones: { [index: string]: number } = {};
const durations: { [index: string]: number } = {};

let report = `performance report:\n`
for (let [msg, time] of stats.milestones) {
let report = `Performance Report:\n`
report += `\n`
report += `\tMilestones:\n`
for (let [msg, time, params] of stats.milestones) {
if (!filter || msg.indexOf(filter) >= 0) {
let pretty = prettyStr(time)
report += `\t\t${msg} @ ${pretty}\n`
report += `\t\t${msg} @ ${pretty}`
for (let k of Object.keys(params || {})) {
report += `\n\t\t\t${k}: ${params[k]}`
}
report += `\n`
milestones[msg] = time;
}
}

report += `\n`
for (let [msg, start, duration] of stats.durations) {
report += `\tMeasurements:\n`
for (let [msg, start, duration, params] of stats.durations) {
let filterIncl = filter && msg.indexOf(filter) >= 0
if ((duration > 50 && !filter) || filterIncl) {
let pretty = prettyStr(duration)
report += `\t\t${msg} took ~ ${pretty}`
if (duration > 1000) {
report += ` (${prettyStr(start)} - ${prettyStr(start + duration)})`
for (let k of Object.keys(params || {})) {
report += `\n\t\t\t${k}: ${params[k]}`
}
}
report += `\n`
}
durations[msg] = duration;
}
console.log(report)
enabled = false; // stop collecting milestones and measurements after report
return { milestones, durations };
}
return undefined;
Expand Down Expand Up @@ -210,7 +253,7 @@ namespace pxt {

// App Insights automatically sends a page view event on setup, but we send our own later with additional properties.
// This stops the automatic event from firing, so we don't end up with duplicate page view events.
if(envelope.baseType == "PageviewData" && !envelope.baseData.properties) {
if (envelope.baseType == "PageviewData" && !envelope.baseData.properties) {
return false;
}

Expand Down
20 changes: 13 additions & 7 deletions docs/asset-editor-shortcuts.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ These shortcuts allow you to quickly switch between the tools in the editor.
| **u** | Rectangle tool |
| **c** | Circle tool |
| **m** | Marquee tool |
| **h** | Pan tool |
| **q** | Pan tool |
| **space** | Temporarily enter pan mode (release space to return to previous tool) |
| **alt** | Temporarily enter eyedropper mode (release alt to return to previous tool)

Expand All @@ -40,16 +40,17 @@ These shortcuts are used to perform advanced edit operations on sprites or tilem

Each of these shortcuts are affected by the marquee tool.
If a portion of the asset is selected by the marquee tool, then the shortcut transformation will only apply to the selected area.
If editing an animation, add the **shift** key to the shortcut to affect all frames at once.

| Shortcut | Description |
| -------------- | ----------- |
| **shift + h** | Flip horizontally |
| **shift + v** | Flip vertically |
| **]** | Rotate clockwise |
| **[** | Rotate counterclockwise |
| **Arrow Key** | Move marquee tool selection by one pixel |
| **shift + r** | Replace all instances of selected background color/tile with selected foreground color/tile |
| **backspace** | Delete current marquee tool selection |
| **h** | Flip horizontally |
| **v** | Flip vertically |
| **]** | Rotate clockwise |
| **[** | Rotate counterclockwise |
| **r** | Replace all instances of selected background color/tile with selected foreground color/tile |


## Image/Animation editor-only shortcuts
Expand All @@ -60,4 +61,9 @@ These shortcuts are only available in the image and animation editors (not the t
| ---------------------------------- | ----------- |
| **shift + 1-9** or **shift + a-f** | Outline the current image with the color in the palette corresponding to the selected number. For example, **shift + f** will outline with color number 15 (black) |
| **0-9** | Select a foreground color from the palette (first ten colors only) |

| **.** | Advance forwards one frame in the current animation |
| **,** | Advance backwards one frame in the current animation |
| **PageDown** | Swap the current animation frame with the next frame in the timeline |
| **PageUp** | Swap the current animation frame with the previous frame in the timeline |
| **shift + PageDown** | Rotate all frames in the animation forwards one frame |
| **shift + PageUp** | Rotate all frames in the animation backwards one frame |
8 changes: 8 additions & 0 deletions docs/blog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Microsoft MakeCode Blog

## [MakeCode Code Evaluation Tool Beta](/blog/tools/code-eval-tool)

January 14th, 2025 by [Jaqster](https://github.com/jaqster)

The year 2025 is already off to a great start with the Beta release of a new tool for Teachers! **MakeCode Code Evaluation** is an online tool for teachers to help them understand and evaluate student programs.

**[Continue reading this blog post](/blog/tools/code-eval-tool)**

## [MakeCode for the micro:bit 2024 Update](/blog/microbit/2024-update)

September 4, 2024 by [Jaqster](https://github.com/jaqster)
Expand Down
1 change: 1 addition & 0 deletions docs/blog/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Microsoft MakeCode Blog

* [Blog](/blog)
* [MakeCode Code Evaluation Tool Beta](/blog/tools/code-eval-tool)
* [MakeCode for the micro:bit 2024 Update](/blog/microbit/2024-update)
* [MakeCode Arcade - now more ways to play!](/blog/arcade/arcade-on-microbit-xbox)
* [MakeCode Minecraft 2023 Update](/blog/minecraft/2023-release)
Expand Down
20 changes: 20 additions & 0 deletions docs/blog/tools/code-eval-tool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# MakeCode Code Evaluation Tool Beta

**Posted on January 14th, 2025 by [Jaqster](https://github.com/jaqster)**

The year 2025 is already off to a great start with the Beta release of a new tool for Teachers! MakeCode [Code Evaluation](https://makecode.microbit.org/--eval) is an online tool for teachers to help them understand and evaluate student programs. We’ve heard from many teachers over the years that one of the most onerous parts of their job is assessing and evaluating student projects. With many teachers responsible for over 100 students, taking 10 minutes to understand, evaluate and give feedback for each program their students turn in means over 16 hours of review and grading!

The Code Evaluation tool is our first effort to help teachers with this process. We have released it for use with MakeCode for micro:bit projects initially.

Watch this short video to see how to get started:

https://youtu.be/7pA2EbG4QPk

More documentation can be found on the [Code Evaluation Tool](https://makecode.microbit.org/code-eval-tool) info page.

The Code Evaluation tool has been released as a Beta – meaning that it’s still a work-in-progress. We have ideas on how we could improve it, but we want to hear from you! Please try it out and click on the Give Feedback button to let us know your thoughts - https://makecode.microbit.org/--eval.

Happy Making, Coding, and Evaluating!

<br/>
The MakeCode Team
2 changes: 2 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,8 @@ exports.pxtrunner = gulp.series(
pxtembed,
);

exports.pxtweb = pxtweb;
exports.pxtlib = pxtlib;
exports.skillmapTest = testSkillmap;
exports.updatestrings = updatestrings;
exports.lint = lint
Expand Down
6 changes: 3 additions & 3 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ module.exports = function(config) {

// We don't use the watcher but for some reason this must be set to true for tests to run
autoWatch: true,
browsers: [process.env.TRAVIS ? 'chromium_travis' : 'ChromeHeadless'],
browsers: [process.env.GITHUB_ACTIONS ? 'chromium_githubactions' : 'ChromeHeadless'],

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
Expand All @@ -80,8 +80,8 @@ module.exports = function(config) {

// Launcher for using chromium in Travis
customLaunchers: {
chromium_travis: {
base: "Chrome",
chromium_githubactions: {
base: "ChromeHeadless",
flags: ['--no-sandbox']
}
}
Expand Down
5 changes: 4 additions & 1 deletion localtypings/pxteditor.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,10 @@ declare namespace pxt.editor {
blocklyPatch?: (pkgTargetVersion: string, dom: Element) => void;
webUsbPairDialogAsync?: (pairAsync: () => Promise<boolean>, confirmAsync: (options: any) => Promise<number>) => Promise<number>;
mkPacketIOWrapper?: (io: pxt.packetio.PacketIO) => pxt.packetio.PacketIOWrapper;

onPostHostMessage?: (msg: pxt.editor.EditorMessageRequest) => void;
onPerfMilestone?: (payload: { milestone: string, time: number, params?: Map<string> }) => void;
onPerfMeasurement?: (payload: { name: string, start: number, duration: number, params?: Map<string> }) => void;

// Used with the @tutorialCompleted macro. See docs/writing-docs/tutorials.md for more info
onTutorialCompleted?: () => void;
onMarkdownActivityLoad?: (path: string, title?: string, editorProjectName?: string) => Promise<void>;
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pxt-core",
"version": "11.3.7",
"version": "11.3.13",
"description": "Microsoft MakeCode provides Blocks / JavaScript / Python tools and editors",
"keywords": [
"TypeScript",
Expand Down Expand Up @@ -80,9 +80,9 @@
"diff-match-patch": "^1.0.5",
"dompurify": "2.0.17",
"faye-websocket": "0.11.1",
"karma": "6.3.10",
"karma": "6.4.4",
"karma-chai": "0.1.0",
"karma-chrome-launcher": "3.1.0",
"karma-chrome-launcher": "3.2.0",
"karma-mocha": "2.0.1",
"less": "3.13.1",
"lzma": "2.3.2",
Expand All @@ -91,7 +91,7 @@
"pngjs": "3.4.0",
"postcss": "6.0.21",
"promise.prototype.finally": "^3.1.2",
"puppeteer": "13.0.1",
"puppeteer": "23.11.1",
"request": "2.88.0",
"rimraf": "2.5.4",
"rtlcss": "2.2.1",
Expand Down
3 changes: 3 additions & 0 deletions pxtblocks/builtins/loops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import * as Blockly from "blockly";
import { installBuiltinHelpInfo, setBuiltinHelpInfo, setHelpResources } from "../help";
import { setDuplicateOnDrag } from "../plugins/duplicateOnDrag";

export function initLoops() {
const msg = Blockly.Msg;
Expand Down Expand Up @@ -104,6 +105,7 @@ export function initLoops() {
}
}
};
setDuplicateOnDrag(pxtControlsForId, "VAR");

// controls_simple_for
const controlsSimpleForId = "controls_simple_for";
Expand Down Expand Up @@ -313,6 +315,7 @@ export function initLoops() {
);
}
};
setDuplicateOnDrag(pxtControlsForOfId, "VAR");

// controls_for_of
const controlsForOfId = "controls_for_of";
Expand Down
11 changes: 11 additions & 0 deletions pxtblocks/composableMutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,17 @@ export function initExpandableBlock(info: pxtc.BlocksInfo, b: Blockly.Block, def
// use domToBlockInternal so that we don't trigger a render while
// the block is still being initialized
newBlock = Blockly.Xml.domToBlockInternal(shadow, b.workspace);

// we don't know at this time whether the parent block is an insertion marker
// or not. doing this check lets us clean up the block in the case that it is,
// though we get an annoying flicker
setTimeout(() => {
if (newBlock.isInsertionMarker()) {
Blockly.Events.disable();
newBlock.dispose();
Blockly.Events.enable();
}
})
}
else {
newBlock = Blockly.Xml.domToBlock(shadow, b.workspace);
Expand Down
2 changes: 1 addition & 1 deletion pxtblocks/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ export function decompiledDiffAsync(oldTs: string, oldResp: pxtc.CompileResult,
log(newXml);

// compute diff of typescript sources
const diffLines = pxt.diff.compute(oldTs, newTs, {
const diffLines = pxt.diff.computeFormattedDiff(oldTs, newTs, {
ignoreWhitespace: true,
full: true
});
Expand Down
Loading

0 comments on commit bab52a2

Please sign in to comment.