Turtle Graphics#

Adding new turtle functions#

A step-by-step guide using the makeTurtle() and drawGreenScreen() examples to add new turtle functions.

turtle.py#

Use this for functions that involve animations or require to be called sequentially. This is the prefered way.

Define the python fucntion by utilizing the shared array buffer as follows.

```python
def makeTurtle():
    '''
    spawns a new turtle sprite
    '''
    return defaultrunner.callback('turtle', data = [MAKE, 0])

To minimize mistakes later on add the MAKE variable to the global scope.

MAKE = 'make'

pyodideworker.ts#

Three things must be adjusted in this file.

First define a CallableFunction variable right at the top of the file.

let pxGgMakeTurtle: CallableFunction;

Secondly define the callback function and add a layer of abstraction.

const setMakeTurtleCallback = pyodideExpose(async function (
  extras: any,
  makeTurtle: any
) {
  pxGgMakeTurtle = makeTurtle;
  self.ggPx_makeTurtle = ggPx_makeTurtle;
});

function ggPx_makeTurtle(container: any) {
  pxGgMakeTurtle();
}

Lastly, ensure that this callback is exposed at the end.

Comlink.expose({
  runCode,
  initPyodideRunner,
  setDrawGreenScreenCallback,
  setMakeTurtleCallback,
});

pyodideStore.ts#

First add the function to the comlink proxy.

async function initTurtleCallbacks() {
    await taskClient.call(
      taskClient.workerProxy.setDrawGreenScreenCallback,
      Comlink.proxy(drawGreenScreen)
    );
    await taskClient.call(
      taskClient.workerProxy.setMakeTurtleCallback,
      Comlink.proxy(makeTurtle)
    );
}

Then create the callback.

  function makeTurtle() {
    if (!pixiHandler) {
      throw new PixiHandlerNotInstantiatedError("pixiHandler not instantiated");
    }
    return pixiHandler.makeTurtle();
  }

If you went with Method 2 for gturtle.py you must additionally add the corresponding variable to the global scope.

MAKE = "make";

Also add an additional swith statement to the handleTurtle() function.

 async function handleTurtle(params: unknown, buffer: SharedArrayBuffer) {
    let promptObj = params as Object;
    if ("data" in promptObj) {
      let prompt = promptObj["data"];
      let promptArray = prompt as [string, number];
      switch (promptArray[0]) {
        case MAKE:
          makeTurtle();
          break;
        default:
          break;
      }
    }
  }

index.d.ts#

To prevent any typing mistakes add the PixiCallbacks to the index.d.ts file.

declare global {
  interface Window {
    // Turtle PixiCallbacks
    ggPx_drawGreenScreen: any;
    ggPx_makeTurtle: any;
  }
}

Debugging#

For debugging puposes there currently is a function implemented called drawGreenScreen(). This can be called at the different steps of the pipeline to check for errors.