-
-
Notifications
You must be signed in to change notification settings - Fork 749
JSWrapper processing
The in-line code documentation of jswrap processing can be found in scrtips\common.py
and should be consulted and referenced as the master source of truth.
When we build Espruino, we are writing a set of C language functions. In our JavaScript world, we may wish to define global JavaScript objects, functions, properties and other components which map to these C language capabilities.
For example, imagine we have a fantastic C language piece of code that we wish to expose as a JavaScript function call. In JavaScript, I want to code:
var x = foobar("My Name");
such that we will invoke:
JsVar *fooBar(JsVar *name) {
// Code here that implements foobar
}
How do we inform Espruino that such a function is now part of the environment?
The answer is we need to annotate the source code of functions we wish to expose. Within the source code we define C language block comments that have a particular structure. During the Espruino build process, we run a processor (supplied by Espruino) that searches the C code looking for such definitions. These are then used to generate code linkages that result in the honoring of the semantics defined in the comments.
The general structure of the comment look as follows:
/*JSON{
"type": "staticmethod",
"class": "ESP8266WiFi",
"name": "setAutoconnect",
"generate": "jswrap_ESP8266WiFi_setAutoconnect",
"generate_full": "<some code here>",
"params": [
["autoconnect","JsVar","True if we wish to autoconnect."]
],
"return": ["JsVar","A boolean representing our auto connect status"],
"return_object": "Restart"
}*/
All comments begin with "JSON{
" and end with a closing/matching "}
". The format of the content conforms to JSON data encoding.
It is not yet known the meanings and values of these nor which are optional vs mandatory nor whether there are additional settings not yet discovered.
-
type
- Values seen includeclass
,staticmethod
,staticproperty
,method
,property
,function
,variable
,library
,event
,idle
,init
,kill
.
When the wrapper processor has completed running over the source files that contain wrappers, a new file is generated called gen\jswrapper.c
. It is this file that provides the underlying linkage to the JavaScript environment. The implementation of the wrapper processor can be found in scripts\build_jswrapper.py
.
####type = class
A definition type of class
defines a new class type. When defined, the class
property must also be supplied to define the name of the class to be defined. For example:
/*JSON{
"type": "class",
"class": "MyClass"
}*/
Will create a new JavaScript class type called "MyClass
". A class definition may be used in other definitions to add things such as methods and properties.
####type = staticmethod
A definition type of staticmethod
exposes a method that is not instance specific but yet is scoped to a class. When defined, the class
, name
and generate
properties must also be supplied. For example:
/*JSON{
"type": "staticmethod",
"class": "MyClass",
"name": "myStaticMethod",
"generate": "jswrap_myStaticMethod"
}*/
Since a static method must belong to a JavaScript object, we name the object type that owns it with the class
property. The name
property provides the name of the function that can be called from JavaScript. The generate
property names the C language implementation function that will be invoked when the JavaScript method is called.
To invoke such a function, we supply the name of the class that owns the method and the function name itself.
var x = MyClass.myStaticMethod();
####type = staticproperty
A definition type of staticproperty
exposes a property that is not instance specific but yet is scoped to a class. This definition requires that the class
, name
, and one of generate
or generate_full
be supplied.
/*JSON{
"type": "staticproperty",
"class": "MyClass",
"name": "myProperty",
"generate": "jswrap_myProperty"
}*/
####type = method
This modifier defines a function that can be invoked on an instance of the class. When invoked, the corresponding C language function will be called.
This definitions requires that the class
, name
and generate
properties also be present. For example:
/*JSON{
"type": "method",
"class": "MyClass",
"name": "myMethod",
"generate": "jswrap_myMethod"
}*/
To invoke the function, we need an instance of the class. For example:
var myInstance = new MyClass();
var x = myInstance.myMethod();
####type = property
####type = function
####type = variable
This modifier defines a global variable. This definition requires that name
and generate
also be supplied.
/*JSON{
"type": "variable",,
"name": "myVariableName",
"generate": "jswrap_myVariableName"
}*/
####type = library
A definition type of library
defines a new class that can be loaded with a JavaScript require
mechanism. This definition requires that the class
property be supplied:
/*JSON{
"type": "library",
"class": "MyLibraryClass"
}*/
####type = event
This modifier defines that an event can be emitted from this class.
This definition requires that the class
and name
properties also be present. The name
defines the name of the event that can be generated.
/*JSON{
"type": "event",
"class": "MyClass",
"name": "opened"
}*/
####type = idle
This modifier defines a function that will be invoked during idle processing. This definition requires that the generate
property also be present.
/*JSON{
"type": "idle",
"generate": "jswrap_idleMyService"
}*/
####type = init
This modifier defines a function that will be invoked during initialization. This definition requires that the generate
property also be present.
/*JSON{
"type": "init",
"generate": "jswrap_initMyService"
}*/
####type = kill
This modifier defines a function that will be invoked during destruction. This definition requires that the generate
property also be present.
/*JSON{
"type": "kill",
"generate": "jswrap_killMyService"
}*/
##Designing and coding wrapped functions Since wrapped functions need global exposure, it is recommended that care be taken that there be no naming collisions. A naming convention used by Espruino is strongly recommended to be followed.
File names that contain wrapping definitions should be named jswrap_<name>
.
Functions exposed by wrapping should be named jswrap_<ClassName>_<methodName>
.