Ah, you are defining your code in the simulator, right? Basically there are two “types” of code that make up the simulator for MakeCode:
-
Library code - this is in the libs/ folder and is compiled using the MakeCode compiler. Code in this folder will also work on hardware
-
Simulator code - this is in the sim/ folder and does not go through the MakeCode compiler. This code will only work in the browser (not on hardware)
The library code is not normal JavaScript; it gets compiled by the MakeCode compiler. The compiler spits out a “binary.js” file that runs in the browser to simulate the code. You can actually look at that file by going into the JavaScript view of a project and opening the file explorer below the simulator (it should be in the built/ section). This binary file uses different types than normal JS code that simulate the environment our code runs in on hardware. RefCollection is one of those types.
When you write simulator code, primitive types (strings, numbers, booleans) will all get passed straight down to the simulator code. More complex types are passed using the internal runtime types from MakeCode. These are RefObject, RefCollection, and RefAction; You can look at where they are defined here. However, it’s usually best to avoid using them altogether.
You should write as much code as possible inside the libs/ folder of your target. All of this code goes through the MakeCode compiler so there is no need to worry about any of the internal types. The only code that should go in the sim folder is code that needs to access browser APIs or is mocking out C++ code. On the MakeCode team, we typically follow these two rules:
- If the code defines a block, it goes in the libs/ folder
- Whenever possible, code in the sim/ folder should only take primitive types as arguments
If you need to pass a complex type to the simulator, you can usually break it down into a primitive type and then pass that to the simulator. For example, looks like you are converting that array of points into a string. You could structure your code like this:
In libs/myPackage/drawLine.ts
//% block="draw 3d lines with width $width|height $height|closed $closed|from 2d points $points"
//% width.defl=10
//% height.defl=10
//% closed.defl=true
//% points.defl="inner_shadow_block"
//% linePath.shadow="lists_create_with"
//% advanced=true
//% group="Advanced 3D Shapes"
export function drawLinePath(width: number, height: number, closed: boolean, points: string[]): void
{
const pointsArrayStr = points.join(",");
_drawLineCore(width, height, closed, pointsArrayStr);
}
In sim/drawLine.ts:
//%
export function _drawLineCore(width: number, height: number, closed: boolean, points: string): void
{
// draw the line
}
In this example, adding the //% above the function makes sure that it is usable from the libs/ directory. Adding an underscore to the beginning of the function names will make sure that the function is filtered out of intellisense, so you’ll be able to use it but users will never see it.
I hope that clears things up a little!