Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.

Update WebIDL and modify documentation to fit new "node.js-like" style #1800

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions docs/Notes_on_WebIDL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Notes on WebIDL for zephyr.js documentation:

The WebIDL fragments are for reference only; the description of the
API should be considered correct -- please report discrepancies as
soon as possible.

Although both WebIDL and JavaScript are aimed at web applications,
numerous incompatibilities exist between the two. In general, we try
to use basic (as opposed to "advanced") WebIDL to describe each
API; below, we list some of our conventions.

We map WebIDL definitions to JavaScript objects as follows:

1. dictionaries -- these map to JavaScript objects that simply don't
have methods attached to them.
2. interfaces -- like definitions, these correspond to JavaScript
objects, except that they may also include methods.
3. callbacks -- these are type definitions for functions used as
parameters or object fields.
4. enumerations -- these are largely the same in both languages.

Unless a constructor is explicitly defined/denied (*e.g.*, see the
note about "require", below), we assume the JavaScript model that the
object can be constructed with "new" -- WebIDL specifies that the
external attribute "constructor" be applied to a definition that can
be new'd, but putting the attribute on every object would be
cumbersome.

The node.js notion of "require" is subtly different from constructing
an object with JavaScript's "new", but it has appealing semantics. We
annotate WebIDL definitions that should be implemented with node.js's
"require" semantics with the external attribute "ReturnFromRequire".
74 changes: 39 additions & 35 deletions docs/aio.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ ZJS API for Analog I/O (AIO)

* [Introduction](#introduction)
* [Web IDL](#web-idl)
* [API Documentation](#api-documentation)
* [Class: AIO](#aio-api)
* [aio.open(AIOInit)](#aioopenaioinit)
* [Class: AIOPin](#aiopin-api)
* [pin.read()](#pinread)
* [pin.readAsync(ReadCallback)](#pinreadasyncreadcallback)
* [pin.on(eventType, ReadCallback)](#pinoneventtype-readcallback)
* [pin.close()](#pinclose)
* [Sample Apps](#sample-apps)

Introduction
Expand All @@ -23,23 +29,23 @@ not have support for this.

Web IDL
-------
This IDL provides an overview of the interface; see below for documentation of
specific API functions.

This IDL provides an overview of the interface; see below for
documentation of specific API functions. We have a short document explaining [ZJS WebIDL conventions](Notes_on_WebIDL.md).

```javascript
// require returns an AIO object
// var aio = require('aio');

[NoInterfaceObject]
[ReturnFromRequire]
interface AIO {
AIOPin open(AIOInit init);
};

dictionary AIOInit {
unsigned long pin;
(unsigned long or string) pin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many many web devs are using TypeScript today, so I see more and more web frameworks actually documenting APIs using typescript. This is also useful because you can distribute the documentation as *.ts.d files which can be used in IDE's like VSCode to do autocompletion etc.

The above would be

interface AIOInit {
  pin: number|string;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@t-harvey is working on a tool to generate code based on WebIDL. So for his purposes I think he needs WebIDL specifically, or is that itself up to suggestion? Earlier I suggested maybe we should move the WebIDL itself out to a .idl file. We could also have TypeScript in a .ts.d file or both... the only question would be how well would we actually maintain them. :)

If we could turn this into some automated testing that might alert us of mismatch (because of failures) and we'd be more likely to keep it synced correctly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We did have a existing PR that had typescript before #1572, but that was providing auto-completetions, and I haven't figure out how to import it into the ide without conflicting with other .ts.d files, so i had to close the PR, but we do have similar apis.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Geoff, I'd love to move the WebIDL to its own file and then just include it in the .md file -- but markdown doesn't seem to allow such a thing (correct me if I'm wrong). It's true that I could just have a link to a .idl file in the main page, but I tried that, and it doesn't look nearly as nice as having the WebIDL inline -- and I really like the streamlined API that WebIDL gives you in addition to the textual description; it's a lot like having a picture to reference.

Currently, I cut/paste the WebIDL out of the docs into their own .idl file and test them (which is why I missed the problem that @kenchris caught).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that cut and pasting was part of my motivation. But yes I was thinking of just having a link to it. Hopefully by standardizing the way the WebIDL appears you can write a script to cut and paste automatically. I don't have any reason to force them out into .idl files right now, but eventually that might be best. One thing about the "Node.js" style is the functions are all listed again in the table of contents so it's a bit repetitive.

};

[NoInterfaceObject]
interface AIOPin {
unsigned long read();
void readAsync(ReadCallback callback); // TODO: change to return a promise
Expand All @@ -50,57 +56,55 @@ interface AIOPin {
callback ReadCallback = void (unsigned long value);
```

API Documentation
-----------------
### AIO.open

`AIOPin open(AIOInit init);`
AIO API
-------
### aio.open(init)
* 'init' *AIOInit object* The AIOInit object has a single field called "pin"
that represents the name of the pin (either an integer or a string,
depending on the board).
* Returns: an AIOPin object that may be used to read values from the pin.

The `init` object lets you set the pin number. You can either use a raw
When setting the pin number, you can either use a raw
number for your device or use the board support module such as
[Arduino 101](./boards/arduino_101.md) or [K64F](./boards/frdm_k64f.md) to
specify a named pin.

Use the AIOPin object returned to read values from the pin.

### AIOPin.read

`unsigned long read();`
AIOPin API
----------
### pin.read()
* Returns: the latest reading from the pin (an unsigned integer). Blocks until it gets the result.

Returns the latest reading from the pin. Blocks until it gets the result.
### pin.readAsync(callback)
* 'callback' *ReadCallback* User-provided callback function that takes
a single unsigned integer and has no return value.

### AIOPin.readAsync

`void readAsync(ReadCallback callback);`

Pass a function for `callback` that will be called later when the result is
Pass a function for `ReadCallback` that will be called later when the result is
obtained.

*WARNING: Making an async call like this allocates some memory while the call
is pending, so if you issue them faster than they are fulfilled, you will
is pending; if async calls are issued faster than they are fulfilled,
the system will
eventually run out of memory - pretty soon on these small devices. So the best
practice would be to make sure you only have a small, fixed number pending at
practice would be to have only a small, fixed number pending at
any given time.*

*NOTE: This function will probably be replaced with a version that instead
returns a promise.*

### AIOPin.on
### pin.on(eventType, callback)
* 'eventType' *string* Type of event; currently, the only supported
type is "change".
* 'callback' *ReadCallback* User-provided callback function that takes
a single, unsigned integer and has no return value; can be null.

`void on(string eventType, ReadCallback callback);`

Currently, the only supported `eventType` is 'change', and `callback` should
be either a function or null. When a function is passed for the change event,
the function will be called any time the analog voltage changes. (At the moment,
The callback function is called any time the analog voltage changes. (At the moment,
it actually gets called periodically even when it hasn't changed.) When null is
passed for the change event, the previously registered callback will be
discarded and no longer called.

### AIOPin.close

`void close();`
### pin.close()

Closes the AIOPin. Once it is closed, all event handlers registered will no
Closes the AIOPin. Once it is closed, all registered event handlers will no
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice English / voice edits - thanks.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm as human as the next guy, so I make these errors, too.
I'm also as OCD as the next guy, so expect more of these... :-)

longer be called.

Sample Apps
Expand Down
Loading