diff --git a/cmds/cmds.ts b/cmds/cmds.ts deleted file mode 100644 index 6e5e1fec..00000000 --- a/cmds/cmds.ts +++ /dev/null @@ -1,60 +0,0 @@ -/// -/// - -import * as fs from "fs"; -import * as path from "path"; -import * as child_process from "child_process"; - -let writeFileAsync: any = Promise.promisify(fs.writeFile) -let execAsync: (cmd: string, options?: { cwd?: string }) => Promise = Promise.promisify(child_process.exec) -let readDirAsync = Promise.promisify(fs.readdir) - - -export function deployCoreAsync(res: ts.pxtc.CompileResult) { - return getBitDrivesAsync() - .then(drives => { - if (drives.length == 0) { - console.log("cannot find any drives to deploy to"); - return Promise.resolve(0); - } - - console.log(`copy ${ts.pxtc.BINARY_HEX} to ` + drives.join(", ")); - - let writeHexFile = (filename: string) => { - return writeFileAsync(filename + ts.pxtc.BINARY_HEX, res.outfiles[ts.pxtc.BINARY_HEX]) - .then(() => console.log("wrote hex file to " + filename)); - }; - - return Promise.map(drives, d => writeHexFile(d)) - .then(() => drives.length); - }); -} - -function getBitDrivesAsync(): Promise { - if (process.platform == "win32") { - const rx = new RegExp("^([A-Z]:).* " + pxt.appTarget.compile.deployDrives) - return execAsync("wmic PATH Win32_LogicalDisk get DeviceID, VolumeName, FileSystem") - .then(buf => { - let res: string[] = [] - buf.toString("utf8").split(/\n/).forEach(ln => { - let m = rx.exec(ln) - if (m) { - res.push(m[1] + "/") - } - }) - return res - }) - } - else if (process.platform == "darwin") { - const rx = new RegExp(pxt.appTarget.compile.deployDrives) - return readDirAsync("/Volumes") - .then(lst => lst.filter(s => rx.test(s)).map(s => "/Volumes/" + s + "/")) - } else if (process.platform == "linux") { - const rx = new RegExp(pxt.appTarget.compile.deployDrives) - const user = process.env["USER"] - return readDirAsync(`/media/${user}`) - .then(lst => lst.filter(s => rx.test(s)).map(s => `/media/${user}/${s}/`)) - } else { - return Promise.resolve([]) - } -} diff --git a/cmds/pxtrequire.ts b/cmds/pxtrequire.ts index 26442585..227781fb 100644 --- a/cmds/pxtrequire.ts +++ b/cmds/pxtrequire.ts @@ -1,3 +1,6 @@ +/// +/// + import * as path from "path"; export let pxtCore = require("pxt-core"); // require.resolve() gives path to [pxt dir]/built/pxt.js, so move up twice to get pxt root dir diff --git a/docs/index-ref.json b/docs/index-ref.json index 9f6ae978..6534e86d 100644 --- a/docs/index-ref.json +++ b/docs/index-ref.json @@ -1,3 +1,3 @@ { - "appref": "v0.6.13" + "appref": "v0.6.36" } diff --git a/docs/projects/compass.md b/docs/projects/compass.md index f22ffe04..38c6667c 100644 --- a/docs/projects/compass.md +++ b/docs/projects/compass.md @@ -10,12 +10,10 @@ Welcome! This guided tutorial will show you how to program a script that display ### ~ - ## Step 1 Create a loop that will continuously update the reading of the compass. - ```blocks basic.forever(() => { diff --git a/docs/projects/flashing-heart.md b/docs/projects/flashing-heart.md index 95f612b1..40be3ba3 100644 --- a/docs/projects/flashing-heart.md +++ b/docs/projects/flashing-heart.md @@ -2,8 +2,7 @@ ### ~avatar avatar -Use the LEDs to display a flashing heart, and then create -an animation of a broken heart. :( +Use the LEDs to display a flashing heart! ### ~ @@ -38,19 +37,19 @@ basic.clearScreen(); ## Step 3 -Put a [forever loop](/reference/basic/forever) around it. +Put a [forever loop](/reference/basic/forever) around it to repeat the animation. ```blocks basic.forever(() => { -basic.showLeds(` - . # . # . - # # # # # - # # # # # - . # # # . - . . # . .` - ); -basic.pause(500); -basic.clearScreen(); + basic.showLeds(` + . # . # . + # # # # # + # # # # # + . # # # . + . . # . .` + ); + basic.pause(500); + basic.clearScreen(); }) ``` @@ -60,45 +59,50 @@ Add a [pause](/reference/basic/pause) to wait after clearing the screen. ```blocks basic.forever(() => { -basic.showLeds(` - . # . # . - # # # # # - # # # # # - . # # # . - . . # . .` - ); -basic.pause(500); -basic.clearScreen(); -basic.pause(500); + basic.showLeds(` + . # . # . + # # # # # + # # # # # + . # # # . + . . # . .` + ); + basic.pause(500); + basic.clearScreen(); + basic.pause(500); }) ``` -## Step 5 +## Send your heartbeats over radio! -Add a second image of a broken heart. +Do you have a second @boardname@ at hand? You could use radio and send your heartbeats to other +@boardname@ and show a heart when you receive one. +* move the code in the **forever** inside +a [on data packet received](/reference/radio/on-data-packet-received) handler. +The handler will run whenever a message is received from another @boardname@. +* use [send number](/reference/radio/send-number) and [pause](/reference/basic/pause) +to broadcast a packet of data every second. ```blocks basic.forever(() => { -basic.showLeds(` - . # . # . - # # # # # - # # # # # - . # # # . - . . # . .` - ); -basic.pause(500); -basic.clearScreen(); -basic.pause(500); -basic.showLeds(` - . # . # . - # . # # # - # . . . # - . # # # . - . . # . .` - ); -basic.pause(500); -basic.clearScreen(); -basic.pause(500); + radio.sendNumber(0) + basic.pause(1000) +}) +radio.onDataPacketReceived(({receivedNumber}) => { + basic.showLeds(` + . # . # . + # # # # # + # # # # # + . # # # . + . . # . .`); + basic.pause(500) + basic.clearScreen() + basic.pause(500) }) ``` + +Download the .hex file onto both @boardname@ and try it out! + +```package +radio +``` \ No newline at end of file diff --git a/docs/projects/smiley-buttons.md b/docs/projects/smiley-buttons.md index f7eb51cb..2b0ff343 100644 --- a/docs/projects/smiley-buttons.md +++ b/docs/projects/smiley-buttons.md @@ -12,8 +12,8 @@ Use [show leds](/reference/basic/show-leds) to make a smiley face: ```blocks basic.showLeds(` - . # . # . - . # . # . + # # . # # + # # . # # . . . . . # . . . # . # # # .` @@ -22,56 +22,93 @@ basic.showLeds(` ## Step 2 -Add an input block for when [button A is pressed](/reference/input/button-is-pressed), and put a -frowny face inside it: +Add an input block for when [button A is pressed](/reference/input/button-is-pressed), +and **move** the smiley face inside it: ```blocks -basic.showLeds(` - . # . # . - . # . # . - . . . . . - # . . . # - . # # # .` - ); input.onButtonPressed(Button.A, () => { basic.showLeds(` - . # . # . - . # . # . - . . . . . - . # # # . - # . . . #` - ); -}); -``` - -## Step 3 - -Now add blocks so that when [button B is pressed](/reference/input/button-is-pressed), a smiley appears: - -```blocks -basic.showLeds(` - . # . # . - . # . # . - . . . . . - # . . . # - . # # # .` - ); -input.onButtonPressed(Button.A, () => { - basic.showLeds(` - . # . # . - . # . # . - . . . . . - . # # # . - # . . . #` - ); -}); -input.onButtonPressed(Button.B, () => { - basic.showLeds(` - . # . # . - . # . # . + # # . # # + # # . # # . . . . . # . . . # . # # # .` ); }); ``` + +Try pressing button A! + +## Step 3 + +Now add blocks so that when [button B is pressed](/reference/input/on-button-pressed), +a frowney appears: + +```blocks +input.onButtonPressed(Button.A, () => { + basic.showLeds(` + # # . # # + # # . # # + . . . . . + # . . . # + . # # # .` + ); +}); +input.onButtonPressed(Button.B, () => { + basic.showLeds(` + # # . # # + # # . # # + . . . . . + . # # # . + # . . . #` + ); +}); +``` + +Try pressing ``A`` or ``B``! + +## Send your smileys over radio + +Do you have a second @boardname@ at hand? You could use radio and send your smileys or frownies to other +@boardname@. + +Since radio can send numbers, we decide that ``0`` is the code for displaying a smiley +and ``1`` is the code for a frowney. + +Change your code as follows: +* [radio send number](/reference/radio/send-number) sends a number +to any other @boardname@ in range +* [radio on data packet received](/reference/radio/on-data-packet-received) runs code +when data is received over radio + +```blocks +input.onButtonPressed(Button.A, () => { + radio.sendNumber(0) +}) +input.onButtonPressed(Button.B, () => { + radio.sendNumber(1) +}) +radio.onDataPacketReceived(({receivedNumber}) => { + if (receivedNumber == 0) { + basic.showLeds(` + # # . # # + # # . # # + . . . . . + # . . . # + . # # # . + `) + } else { + basic.showLeds(` + # # . # # + # # . # # + . . . . . + . # # # . + # . . . # + `) + } +}) +``` + +```package +radio +``` diff --git a/docs/reference/bluetooth/advertise-url.md b/docs/reference/bluetooth/advertise-url.md index 9a0a808d..852f4090 100644 --- a/docs/reference/bluetooth/advertise-url.md +++ b/docs/reference/bluetooth/advertise-url.md @@ -18,18 +18,18 @@ Read more at https://lancaster-university.github.io/microbit-docs/ble/eddystone/ ## ~ ```sig -bluetooth.advertiseUrl("https://pxt.microbit.org/", 7); +bluetooth.advertiseUrl("https://pxt.microbit.org/", 7, true); ``` ### Parameters -* ``url`` - a [string](/reference/types/string) containing the URL to broadcast, at most 18 characters long +* ``url`` - a [string](/reference/types/string) containing the URL to broadcast, at most 17 characters long, excluding the protocol (eg: ``https://``) which gets encoded as 1 byte. * ``power`` - a [number](/reference/types/number) representing the power level between 0 (short) and 7 (maximum range). ### Example: Broadcast a secret code ```blocks -bluetooth.advertiseUrl("https://pxt.io?secret=42", 7); +bluetooth.advertiseUrl("https://pxt.io?secret=42", 7, true); ``` ## See Also @@ -38,4 +38,4 @@ bluetooth.advertiseUrl("https://pxt.io?secret=42", 7); ```package bluetooth -``` \ No newline at end of file +``` diff --git a/docs/reference/serial/read-until.md b/docs/reference/serial/read-until.md new file mode 100644 index 00000000..4303b30b --- /dev/null +++ b/docs/reference/serial/read-until.md @@ -0,0 +1,28 @@ +# Serial Read Until + +Read a text from the serial port until a delimiter is found. + +```sig +serial.readUntil(","); +``` + +### Returns + +* a [string](/reference/types/string) containing input from the serial port, such as a response typed by a user + +### Example + +The following example reads strings separated by commands (``,``). + +```blocks +basic.forever(() => { + let answer = serial.readUntil(","); + serial.writeLine(answer); +}); +``` + +### See also + +[serial](/device/serial), +[serial write line](/reference/serial/write-line), +[serial write value](/reference/serial/write-value) diff --git a/docs/uploader.md b/docs/uploader.md index 165ccb56..587c9ddb 100644 --- a/docs/uploader.md +++ b/docs/uploader.md @@ -38,7 +38,7 @@ That's it! ### Installation Instructions -* Download the [Microsoft.Uploader.Microbit.zip](https://pxt.microbit.org/microbit-uploader.zip) file to your local computer. +* Download the [Microsoft.Uploader.Microbit.zip](https://www.touchdevelop.com/microbituploader.zip) file to your local computer. * Unzip the .zip file to your desktop. * Launch the Microsoft.Uploader.exe file before working on your @boardname@. diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 7b23ac25..44b19763 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -85,7 +85,7 @@ "game.setLife": "Sets the current life value", "game.setLife|param|value": "TODO", "game.setScore": "Sets the current score value", - "game.setScore|param|value": "TODO", + "game.setScore|param|value": "new score value.", "game.showScore": "Displays the score on the screen.", "game.startCountdown": "Starts a game countdown timer", "game.startCountdown|param|ms": "countdown duration in milliseconds, eg: 10000", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index 264fced3..080f1221 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -110,6 +110,7 @@ "game.createSprite|block": "create sprite at|x: %x|y: %y", "game.gameOver|block": "game over", "game.score|block": "score", + "game.setScore|block": "set score %points", "game.startCountdown|block": "start countdown|(ms) %duration", "game|block": "game", "images.createBigImage|block": "create big image", diff --git a/libs/core/game.ts b/libs/core/game.ts index ccd36552..d16642a7 100644 --- a/libs/core/game.ts +++ b/libs/core/game.ts @@ -40,7 +40,7 @@ namespace game { * @param x sprite horizontal coordinate, eg: 2 * @param y sprite vertical coordinate, eg: 2 */ - //% weight=60 + //% weight=60 blockGap=8 //% blockId=game_create_sprite block="create sprite at|x: %x|y: %y" //% parts="ledmatrix" export function createSprite(x: number, y: number): LedSprite { @@ -146,8 +146,9 @@ namespace game { /** * Sets the current score value - * @param value TODO + * @param value new score value. */ + //% blockId=game_set_score block="set score %points" blockGap=8 //% weight=10 help=game/set-score export function setScore(value: number): void { _score = Math.max(0, value); @@ -646,6 +647,7 @@ namespace game { * Deletes the sprite from the game engine. All further operation of the sprite will not have any effect. * @param this sprite to delete */ + //% weight=59 //% blockId="game_delete_sprite" block="delete %this" public delete(): void { sprites.removeElement(this); diff --git a/libs/core/pxt.cpp b/libs/core/pxt.cpp index 5295de84..af031013 100644 --- a/libs/core/pxt.cpp +++ b/libs/core/pxt.cpp @@ -131,7 +131,9 @@ namespace pxt { if (refmask[i]) decr(r->fields[i]); r->fields[i] = 0; } - delete r; + //RefRecord is allocated using placement new + r->~RefRecord(); + ::operator delete(r); } void RefRecord_print(RefRecord *r) @@ -259,7 +261,9 @@ namespace pxt { decr(fields[i]); fields[i] = 0; } - delete this; + //RefAction is allocated using placement new + this->~RefAction(); + ::operator delete(this); } void RefAction::print() diff --git a/package.json b/package.json index 57c651f9..dc15db6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pxt-microbit", - "version": "0.6.31", + "version": "0.6.36", "description": "micro:bit target for PXT", "keywords": [ "JavaScript", @@ -34,6 +34,6 @@ "semantic-ui-less": "^2.2.4" }, "dependencies": { - "pxt-core": "0.5.91" + "pxt-core": "0.5.99" } } diff --git a/sim/state/accelerometer.ts b/sim/state/accelerometer.ts index 8bc42bd4..18d3d588 100644 --- a/sim/state/accelerometer.ts +++ b/sim/state/accelerometer.ts @@ -23,15 +23,15 @@ namespace pxsim.input { } export function rotation(kind: number): number { - let b = board().accelerometerState; - let acc = b.accelerometer; + const b = board().accelerometerState; + const acc = b.accelerometer; acc.activate(); - let x = acc.getX(MicroBitCoordinateSystem.NORTH_EAST_DOWN); - let y = acc.getX(MicroBitCoordinateSystem.NORTH_EAST_DOWN); - let z = acc.getX(MicroBitCoordinateSystem.NORTH_EAST_DOWN); + const x = acc.getX(MicroBitCoordinateSystem.NORTH_EAST_DOWN); + const y = acc.getY(MicroBitCoordinateSystem.NORTH_EAST_DOWN); + const z = acc.getZ(MicroBitCoordinateSystem.NORTH_EAST_DOWN); - let roll = Math.atan2(y, z); - let pitch = Math.atan(-x / (y * Math.sin(roll) + z * Math.cos(roll))); + const roll = Math.atan2(y, z); + const pitch = Math.atan(-x / (y * Math.sin(roll) + z * Math.cos(roll))); let r = 0; switch (kind) { diff --git a/sim/visuals/microbit.ts b/sim/visuals/microbit.ts index 116ac6d9..0a2ece48 100644 --- a/sim/visuals/microbit.ts +++ b/sim/visuals/microbit.ts @@ -556,12 +556,12 @@ namespace pxsim.visuals { private updateTilt() { if (this.props.disableTilt) return; - let state = this.board; + const state = this.board; if (!state || !state.accelerometerState.accelerometer.isActive) return; - let x = state.accelerometerState.accelerometer.getX(); - let y = state.accelerometerState.accelerometer.getY(); - let af = 8 / 1023; + const x = state.accelerometerState.accelerometer.getX(); + const y = -state.accelerometerState.accelerometer.getY(); + const af = 8 / 1023; this.element.style.transform = "perspective(30em) rotateX(" + y * af + "deg) rotateY(" + x * af + "deg)" this.element.style.perspectiveOrigin = "50% 50% 50%"; @@ -704,7 +704,7 @@ namespace pxsim.visuals { } let tiltDecayer = 0; this.element.addEventListener(pointerEvents.move, (ev: MouseEvent) => { - let state = this.board; + const state = this.board; if (!state.accelerometerState.accelerometer.isActive) return; if (tiltDecayer) { @@ -712,14 +712,14 @@ namespace pxsim.visuals { tiltDecayer = 0; } - let bbox = this.element.getBoundingClientRect(); - let ax = (ev.clientX - bbox.width / 2) / (bbox.width / 3); - let ay = (ev.clientY - bbox.height / 2) / (bbox.height / 3); + const bbox = this.element.getBoundingClientRect(); + const ax = (ev.clientX - bbox.width / 2) / (bbox.width / 3); + const ay = (ev.clientY - bbox.height / 2) / (bbox.height / 3); - let x = - Math.max(- 1023, Math.min(1023, Math.floor(ax * 1023))); - let y = Math.max(- 1023, Math.min(1023, Math.floor(ay * 1023))); - let z2 = 1023 * 1023 - x * x - y * y; - let z = Math.floor((z2 > 0 ? -1 : 1) * Math.sqrt(Math.abs(z2))); + const x = - Math.max(- 1023, Math.min(1023, Math.floor(ax * 1023))); + const y = - Math.max(- 1023, Math.min(1023, Math.floor(ay * 1023))); + const z2 = 1023 * 1023 - x * x - y * y; + const z = Math.floor((z2 > 0 ? -1 : 1) * Math.sqrt(Math.abs(z2))); state.accelerometerState.accelerometer.update(x, y, z); this.updateTilt();