Implement Deref for all imported JS types

This commit implements the first half of [RFC #5] where the `Deref`
trait is implemented for all imported types. The target of `Deref` is
either the first entry of the list of `extends` attribute or `JsValue`.

All examples using `.as_ref()` with various `web-sys` types have been
updated to the more ergonomic deref casts now. Additionally the
`web-sys` generation of the `extends` array has been fixed slightly to
explicitly list implementatoins in the hierarchy order to ensure the
correct target for `Deref` is chosen.

[RFC #5]: https://github.com/rustwasm/rfcs/blob/master/text/005-structural-and-deref.md
This commit is contained in:
Alex Crichton
2018-11-08 10:58:55 -08:00
parent d646b29bb7
commit 5b76a6291e
10 changed files with 146 additions and 81 deletions

View File

@ -2,7 +2,7 @@ extern crate wasm_bindgen;
extern crate web_sys;
use wasm_bindgen::prelude::*;
use web_sys::{AudioContext, AudioNode, OscillatorType};
use web_sys::{AudioContext, OscillatorType};
/// Converts a midi note to frequency
///
@ -60,34 +60,24 @@ impl FmOsc {
fm_osc.set_type(OscillatorType::Sine);
fm_osc.frequency().set_value(0.0);
// Create base class references:
{
let primary_node: &AudioNode = primary.as_ref();
let gain_node: &AudioNode = gain.as_ref();
let fm_osc_node: &AudioNode = fm_osc.as_ref();
let fm_gain_node: &AudioNode = fm_gain.as_ref();
let destination = ctx.destination();
let destination_node: &AudioNode = destination.as_ref();
// Connect the nodes up!
// Connect the nodes up!
// The primary oscillator is routed through the gain node, so that
// it can control the overall output volume.
primary.connect_with_audio_node(&gain)?;
// The primary oscillator is routed through the gain node, so that
// it can control the overall output volume.
primary_node.connect_with_audio_node(gain.as_ref())?;
// Then connect the gain node to the AudioContext destination (aka
// your speakers).
gain.connect_with_audio_node(&ctx.destination())?;
// Then connect the gain node to the AudioContext destination (aka
// your speakers).
gain_node.connect_with_audio_node(destination_node)?;
// The FM oscillator is connected to its own gain node, so it can
// control the amount of modulation.
fm_osc_node.connect_with_audio_node(fm_gain.as_ref())?;
// The FM oscillator is connected to its own gain node, so it can
// control the amount of modulation.
fm_osc.connect_with_audio_node(&fm_gain)?;
// Connect the FM oscillator to the frequency parameter of the main
// oscillator, so that the FM node can modulate its frequency.
fm_gain_node.connect_with_audio_param(&primary.frequency())?;
}
// Connect the FM oscillator to the frequency parameter of the main
// oscillator, so that the FM node can modulate its frequency.
fm_gain.connect_with_audio_param(&primary.frequency())?;
// Start the oscillators!
primary.start()?;