Contribute To The API
Need for Contribution
Many people have asked for the API documentation to be improved. This is a major task, with lots of files needing comments. Comments are very useful for future development and maintenance of the code, and they are even more useful now because, in the correct format, they can be read by “TYPEDOC” to produce the API documentation for the classes, properties, and methods used by Babylon.js. The core team has worked to make this happen, as you can see in the new API documentation. Volunteers are needed to add comments, so even if you only have time to work on a couple of files, please do volunteer.
How to Contribute
You need to add appropriate comments according to the formats given below. Check the comments for errors and submit a PR when everything is validated.
- Fork and clone Babylon.js from GitHub;
- Install dependencies with
npm install - Edit files from within the src folder by adding comments;
- Run
npm run lint:checkto check linting issues with your docs (or use the eslint extension for your IDE) - When validated submit a PR.
Format of Comments
We follow tsdoc as a standard for our comments.
Below are descriptions of the comment format for the various code entities, with examples.
Comments go immediately before the entity and take the form of plain comments:
/*** comment* more comments*/or comments plus key @words
| @word | followed by |
|---|---|
| @param | parameter name then parameter description |
| @returns | description of what a function returns |
| @see | URL when it is useful to link to another site or page add one |
| @ignore | reason why it is ignored |
Enum
Defines a set of named constants
Plain comments to describe the purpose of the ENUM and the constants it defines
/*** Defines the list of states available for a task inside an AssetsManager*/export enum AssetTaskState { /** * Initialization */ INIT, /** * Running */ RUNNING, /** * Done */ DONE, /** * Error */ ERROR}/*** Specifies the level of max blur that should be applied when using the depth of field effect*/export enum DepthOfFieldEffectBlurLevel { /** * Subtle blur */ Low, /** * Medium blur */ Medium, /** * Large blur */ High};Class
Template containing the constructor along with the public, private and protected properties and methods defining an object
A defining comment to describe the purpose of the CLASS.
/** * Defines a HemisphericLight object that simulates the ambient environment light * so the passed direction is the light reflection direction, not the incoming direction */export class HemisphericLight extends Light { //All the parts defining the class in here}/** * Define an abstract asset task used with a {BABYLON.AssetsManager} class to load assets into a scene */ export abstract class AbstractAssetTask { //All the parts defining the class in here}Constructor
This creates an instance of the class
A comment to describe the CONSTRUCTOR.
export class MapperManager { //class properties
/** * Creates a new MapperManager object to manage the different implemented mappers */ constructor() { this._mappers = { html: new HTMLMapper(), json: new JSONMapper(), dom: new DOMMapper(), }; }}With Parameters
A comment to describe the CONSTRUCTOR and use @param for each parameter. The first item after @param must be the parameter name, followed by a comment. In addition, if any members of the constructor are declared as public, the comment should be repeated before the member in the parameter list.
No Public Parameters
Create comments and @param entries for the constructor.
/** * Create a new Model loader * @param _viewer the viewer using this model loader */constructor(private _viewer: AbstractViewer) { this._loaders = []; this._loadId = 0;}/** * Creates a Solid Particle object * Don't create particles manually, use instead the Solid Particle System internal tools like _addParticle() * @param particleIndex is the particle index in the Solid Particle System pool. It's also the particle identifier * @param positionIndex is the starting index of the particle vertices in the SPS "positions" array * @param indiceIndex is the starting index of the particle indices in the SPS "indices" array * @param model is a reference to the model shape on what the particle is designed. * @param shapeId is the model shape identifier in the SPS * @param idxInShape is the index of the particle in the current model (ex: the 10th box of addShape(box, 30)) * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations */constructor(particleIndex: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo: Nullable<BoundingInfo> = null) { this.idx = particleIndex; this._pos = positionIndex; this._ind = indiceIndex; this._model = <ModelShape>model; this.shapeId = shapeId; this.idxInShape = idxInShape; this._sps = sps; if (modelBoundingInfo) { this._modelBoundingInfo = modelBoundingInfo; this._boundingInfo = new BoundingInfo(modelBoundingInfo.minimum, modelBoundingInfo.maximum); }}With Public Parameters
Create comments and @param entries for the constructor, and copy comments before any public parameter in the list.
/** * Creates a new Action * @param triggerOptions the trigger, with or without parameters, for the action * @param condition an optional determinant of action */constructor(
/** * The trigger, with or without parameters, for the action */ public triggerOptions: any,
condition?: Condition) {
if (triggerOptions.parameter) { this.trigger = triggerOptions.trigger; this._triggerParameter = triggerOptions.parameter; } else { this.trigger = triggerOptions; }
this._nextActiveAction = this; this._condition = condition;}/** * Creates a new instance ConeParticleEmitter * @param radius the radius of the emission cone (1 by default) * @param angles the cone base angle (PI by default) * @param directionRandomizer defines how much to randomize the particle direction [0-1] */constructor( radius = 1, /** * The cone base angle (PI by default) */ public angle = Math.PI,
/** * Defines how much to randomize the particle direction [0-1] */ public directionRandomizer = 0) {
this.radius = radius;}Property of Class, Constructor, Function
Public with public variable
Plain comments to describe the PROPERTY
/** * The groundColor is the light in the opposite direction to the one specified during creation * You can think of the diffuse and specular light as coming from the centre of the object in the given direction and the groundColor light in the opposite direction */public groundColor = new Color3(0.0, 0.0, 0.0);
/** * The light reflection direction, not the incoming direction */public direction: Vector3Public with private variable
There are occasions when a variable should be public for the code but effectively private to the user. Such variables start with an underscore. Plain comments are useful for development, but the variable should be ignored when building the API documentation. Hence the use of @ignore.
/** * Internal only - manager for action * @ignore */public _actionManager: ActionManager;Private or Protected
These will be ignored automatically when building the API documentation and comments are optional.
private _worldMatrix: Matrix;
protected _background: string;Method of Class, Constructor or Function
Public with public name
No Parameters
No Return Value
Plain comments to describe the FUNCTION
/** * Clears the texture */public clear(): void { const size = this.getSize(); this._context.fillRect(0, 0, size.width, size.height);}/** * Skips to next active action */public skipToNextActiveAction(): void { if (this._nextActiveAction._child) {
if (!this._nextActiveAction._child._actionManager) { this._nextActiveAction._child._actionManager = this._actionManager;}
this._nextActiveAction = this._nextActiveAction._child; } else {this._nextActiveAction = this; }}/** * Observable called when all tasks are processed */public onTaskSuccessObservable = new Observable<AbstractAssetTask>();With Return Value
Comments to describe the FUNCTION and use @returns.
/** * Gets the context of the canvas used by the texture * @returns the canvas context of the dynamic texture */public getContext(): CanvasRenderingContext2D { return this._context;}/** * Serializes the current light into a Serialization object * @returns the serialized object */public serialize(): any { const serializationObject = SerializationHelper.Serialize(this);
// Internal working here
return serializationObject;}/** * @returns the current error object (if task is in error) */public get errorObject(): { message?: string; exception?: any; } { return this._errorObject;}With Parameters
No Return Value
Comments to describe the FUNCTION and use @param for each parameter. The first item after @param must be the parameter name, followed by a comment.
/** * Execute the current task * @param scene defines the scene where you want your assets to be loaded * @param onSuccess is a callback called when the task is successfully executed * @param onError is a callback called if an error occurs */public run(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) { this._taskState = AssetTaskState.RUNNING; this.runTask(scene, () => {this.onDoneCallback(onSuccess, onError); }, (msg, exception) => {this.onErrorCallback(onError, msg, exception); });}/** * Draws text onto the texture * @param text defines the text to be drawn * @param x defines the placement of the text from the left * @param y defines the placement of the text from the top when invertY is true and from the bottom when false * @param font defines the font to be used with font-style, font-size, font-name * @param color defines the color used for the text * @param clearColor defines the color for the canvas, use null to not overwrite canvas * @param invertY defines the direction for the Y axis (default is true - y increases downwards) * @param update defines whether texture is immediately update (default is true) */public drawText(text: string, x: number, y: number, font: string, color: string, clearColor: string, invertY?: boolean, update = true) { const size = this.getSize(); if (clearColor) {this._context.fillStyle = clearColor;this._context.fillRect(0, 0, size.width, size.height); }
this._context.font = font; if (x === null || x === undefined) {const textSize = this._context.measureText(text);x = (size.width - textSize.width) / 2; } if (y === null || y === undefined) {const fontSize = parseInt((font.replace(/\D/g, '')));;y = (size.height / 2) + (fontSize / 3.65); }
this._context.fillStyle = color; this._context.fillText(text, x, y);
if (update) {this.update(invertY); }}With Return Value
Comments to describe the FUNCTION and use @param for each parameter and @returns to describe what the function returns. The first item after @param must be the parameter name, followed by a comment.
/** * Add a TextFileAssetTask to the list of active tasks * @param taskName defines the name of the new task * @param url defines the url of the file to load * @returns a new TextFileAssetTask object */public addTextFileTask(taskName: string, url: string): TextFileAssetTask {const task = new TextFileAssetTask(taskName, url); this._tasks.push(task);
return task;}/** * Sets the passed Effect object with the HemisphericLight normalized direction and color and the passed name (string). * @param effect The effect to update * @param lightIndex The index of the light in the effect to update * @returns The hemispheric light */public transferToEffect(effect: Effect, lightIndex: string): HemisphericLight { const normalizeDirection = Vector3.Normalize(this.direction); this._uniformBuffer.updateFloat4("vLightData",normalizeDirection.x,normalizeDirection.y,normalizeDirection.z,0.0,lightIndex); this._uniformBuffer.updateColor3("vLightGround", this.groundColor.scale(this.intensity), lightIndex); return this;}Public with private name
There are occasions when a function should be public for the code but effectively private to the user. Such names start with an underscore. Plain comments are useful for development, but the function should be ignored when building the API documentation. Hence the use of @ignore.
/** * @ignore internal use only */public _getWorldMatrix(): Matrix { if (!this._worldMatrix) {this._worldMatrix = Matrix.Identity(); } return this._worldMatrix;}/** * @ignore internal use only */public _onPointerEnter(target: Control): boolean { if (!super._onPointerEnter(target)) {return false; }
if (this.pointerEnterAnimation) {this.pointerEnterAnimation(); }
return true;}Private or Protected
These will be ignored automatically when building the API documentation and comments are optional.
protected _buildUniformLayout(): void { this._uniformBuffer.addUniform("vLightData", 4); this._uniformBuffer.addUniform("vLightDiffuse", 4); this._uniformBuffer.addUniform("vLightSpecular", 3); this._uniformBuffer.addUniform("vLightGround", 3); this._uniformBuffer.addUniform("shadowsInfo", 3); this._uniformBuffer.addUniform("depthValues", 2); this._uniformBuffer.create();}private follow(): void { if (!this.target) { return; } this._cartesianCoordinates.x = this.radius * Math.cos(this.alpha) * Math.cos(this.beta); this._cartesianCoordinates.y = this.radius * Math.sin(this.beta); this._cartesianCoordinates.z = this.radius * Math.sin(this.alpha) * Math.cos(this.beta);
const targetPosition = this.target.getAbsolutePosition(); this.position = targetPosition.add(this._cartesianCoordinates); this.setTarget(targetPosition);}private _drawRoundedRect(context: CanvasRenderingContext2D, offset: number = 0): void { const x = this._currentMeasure.left + offset; const y = this._currentMeasure.top + offset; const width = this._currentMeasure.width - offset * 2; const height = this._currentMeasure.height - offset * 2;
const radius = Math.min(height / 2 - 2, Math.min(width / 2 - 2, this._cornerRadius));
context.beginPath(); context.moveTo(x + radius, y); context.lineTo(x + width - radius, y); context.quadraticCurveTo(x + width, y, x + width, y + radius); context.lineTo(x + width, y + height - radius); context.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); context.lineTo(x + radius, y + height); context.quadraticCurveTo(x, y + height, x, y + height - radius); context.lineTo(x, y + radius); context.quadraticCurveTo(x, y, x + radius, y); context.closePath();}