-
Notifications
You must be signed in to change notification settings - Fork 0
Modules
(We should probably call this something other than modules since that also refers to javascript ES6 modules)
Lets go through creating a module
$ npm run init_module
Enter a viz name: amazingModule
Enter description: does amazing things
1. Generating source..
2. Creating file: javascript/modules/moduleAmazingModule.js
3. Adding module entry in javascript/modules/modules.js
Done!
Lets go to javascript/modules/moduleAmazingModule.js and examine what was created. The module minimally requires the following:
class VIZ_AmazingModule {
constructor(seq, sketch, config){
this.seq = seq
this.sketch = sketch
}
setup(){
}
draw(){
}
}The constructor has three parameters
constructor(seq, sketch, config)- seq: This is an instance of SequenceGenerator, it is not a list, and can't be accessed with the brackets [], but provides a method seq.getElement(n) that returns the nth number.
- sketch: There is no global p5 instance, sketch is the only way to call p5 functions and access properties, the reason we do this is to be able to draw an arbitrary number of canvases at the same time.
- config: This is where you will receive all the config values specific to your drawing tool, defined via a schema, which is the second thing module file must have.
As a sort of guideline for what goes into constructor and what goes into setup use the following:
- constructor: If you want values that persist between calls make sure to store them in the constructor, especially save the arguments passed (seq, sketch, config) otherwise you won't be able to use them in setup or draw.
- setup: Anything that interacts or manipulates with the sketch must be in setup, otherwise those you'll encounter strange bugs. It makes sense if you take a look at NScore.generatep5:
let myp5 = new p5(function (sketch) {
let moduleInstance = new moduleClass(seq, sketch, config)
sketch.setup = function () {
sketch.createCanvas(width, height);
sketch.background("white")
moduleInstance.setup();
};Notice that the drawing module's class is instantiated before the canvas is created, and the module's setup function is called after the canvas is created.
const SCHEMA_AmazingModule = {
}This is where we define the config values our viz class wants to use. Say for example we want to get a number called myconfigvalue:
const SCHEMA_AmazingModule = {
myconfigvalue: {
type: 'number',
title: 'config value',
}
}This will generate in the user interface the following:

Which can then be accessed like so:
this.val = config.myconfigvalueNotice that the keys in SCHEMA_AmazingModule become properties of the config parameter passed to the VIZ_AmazingModule constructor. This way makes it's very easy to declaretively say "I want so and so config values" without having to write the HTML interface or extract the values yourself. You define in SCHEMA and expect it in config. (This is thanks to JSONform). Look at the other module files to various ways to declare your SCHEMA, you can specify more things than just type and title.
const MODULE_AmazingModule = {
viz: VIZ_AmazingModule,
name: 'AmazingModule',
description: '',
configSchema: SCHEMA_AmazingModule
}This is where the various parts of the module are collected into one place, NScore can then instantiate the module via MODULE_AmazingModule.viz, it knows how that it requires the config defined in MODULE_AmazingModule.configSchema, and it'll display the name in defined in MODULE_AmazingModule.name.
Note: Right now there is no validation on the inputs, but if a config.value is "" that means it was left empty.
module.exports = MODULE_AmazingModule
This line is necessary to make this module importable. Besides the four parts described above, you're free to define whatever you want in the file in terms of helper functions or classes.
The final part is the following line
MODULES['AmazingModule'] = require('./moduleAmazingModule.js')is appended to javascript/modules/modules.js. NScore uses the MODULES object to know what modules are available. All these steps can be done manually or via the npm commanded provided.