Help with extension

so, i have so problem with my extensions but you choose what problem to help me with.

problem #1

So, i need help with my extension because when i put the variable in these blocks i won’t allow it so, here’s the code for the blocks:

    //% block="On game update every $ms do if $tru"
    //% draggableParameters
    //% subcategory="Logic"
    export function GameUpdateEveryIf(ms: number, tru: Boolean, handler: () => void) {
        game.onUpdateInterval(ms, function() {
            if (tru) {
                handler();
            }
        })
    }

    //% block="On game update if $tru"
    //% draggableParameters
    //% subcategory="Logic"
    export function GameUpdateIf(tru: Boolean, handler: () => void) {
        game.onUpdate(function() {
            if (tru) {
                handler();
            }
        })
    }

    //% block="forever if $tru"
    //% subcategory="Logic"
    export function onEventAsStatement(tru: Boolean, handler: () => void) {
        forever(function() {
            if (tru) {
                handler();
            }
        })
    }
problem #2

So how to you add a “+” button to the “false is -1 or 0: $toggle” ? heres the code:


    //% block="Convert $n|to number|false is -1 or 0: $toggle"
    //% subcategory="Logic"
    //% toggle.shadow="toggleYesNo"
    export function ConvertToNum(n: boolean, toggle: boolean) {
        if (n) {
            return CyberScripts.fib(toggle, 0, -1);
        } else {
            return 1;
        }
    }

    //% block="if|$t then|$input1 else|$input2"
    //% subcategory="Logic"
    export function fib(t: boolean, input1: any, input2: any): any {
        if (t) {
            return input1;
        } else {
            return input2;
        }
    }

if i’m reading this code right, it sounds like in problem 1 you’re trying to create a block that basically does this:

where someBooleanExpression is an expression that could change over time.

well, that’s not possible. when you call a function with a boolean argument, the value of that boolean will be captured in the initial call and will never change.

if you wanted to do something like that in javascript, you would write your function like this:

function conditionalOnGameUpdate(condition: () => boolean, handler: () => void) {
    game.onGameUpdate(() => {
        if (condition()) {
            handler()
        }
    });
}

the condition argument in this example is a function that returns a boolean. that function gets called every frame and allows the expression to be re-evaluated.

unfortunately, while this is totally doable in javascript, there is no way to make a block that does this (actually there is one block that works this way and it’s pause until, but it’s special and you can’t replicate it in an extension)

as for problem 2, i have no idea what you’re trying to do here. can you draw a picture of what your block should look like and maybe give some sample code to show how it’s used?

6 Likes

here is game.onUpdate:

and forever:

Problem #1: Variables won’t plug into $tru

The main issue is this:

tru: Boolean

For MakeCode/PXT block definitions, you generally want the primitive TypeScript type:

tru: boolean

Boolean and boolean aren’t interchangeable for PXT’s block type inference. Boolean is the boxed JavaScript object type, while boolean is the actual primitive type that MakeCode recognizes as a Boolean input.

So change all three to:

tru: boolean

(NOTE: maybe change tru to condition)

For example:

//% block="On game update every $ms do if $tru"
//% draggableParameters
//% subcategory="Logic"
export function GameUpdateEveryIf(ms: number, tru: boolean, handler: () => void) {
    game.onUpdateInterval(ms, function () {
        if (tru) {
            handler()
        }
    })
}

And similarly:

export function GameUpdateIf(tru: boolean, handler: () => void) {

and:

export function onEventAsStatement(tru: boolean, handler: () => void) {

That should make the Boolean expression socket accept variables.

One other thing: if you’re trying to make $tru accept any expression rather than specifically a Boolean, then the type needs to match what you actually want. But for a normal true/false socket, boolean is the right type.


Problem #2: Adding a + button

For problem #2, yes, expandableArgumentMode is what you’re looking for. You can use || in the //% block definition to mark the start of the expandable argument section. For example:

//% block="set the motor to run || $direction|at $speed|for $duration ms"
//% expandableArgumentMode="enabled"

The || separates the regular part of the block from the expandable arguments, and expandableArgumentMode="enabled" enables the + button for that section.

So for the first problem, try boolean instead of Boolean, and for the second, use the || + expandableArgumentMode="enabled" combination.

2 Likes
1

here is the source code for game.onUpdate and forever

2

I don’t know why you have so much extra stuff, but are you thinking of something like this:

    //% block="Convert $n to number"
    //% subcategory="Logic"
    //% n.shadow="toggleYesNo"
    export function BToN(n: boolean) {
        return +n
    }

?

1 Like