On Github Floby / nodejsparis-addons
avec node-libspotify
Hello world, notes
void init (Handle <Object> exports) {
exports->Set(String::NewSymbol("hello"), String::New("world"))
}
NODE_MODULE(hello, init)
var addon = require('hello.node');
console.log(addon.hello);
// "world"
extern "C" {
void init (v8::Handle<v8::Object> target)
{
v8::HandleScope scope;
// initializing all modules
nsp::init_album(target);
nsp::init_artist(target);
nsp::init_link(target);
nsp::init_player(target);
nsp::init_search(target);
nsp::init_session(target);
nsp::init_track(target);
nsp::init_playlistcontainer(target);
nsp::init_playlist(target);
}
}
NODE_MODULE(spotify, init);
Découpage de l'addon en plusieurs modules.
Miroir avec les modules de libspotify
noter le namespace NSP
void nsp::init_album(Handle<Object> target) {
NODE_SET_METHOD(target, "album_is_loaded", Album_Is_Loaded);
NODE_SET_METHOD(target, "album_name", Album_Name);
NODE_SET_METHOD(target, "album_year", Album_Year);
NODE_SET_METHOD(target, "album_type", Album_Type);
NODE_SET_METHOD(target, "album_artist", Album_Artist);
NODE_SET_METHOD(target, "album_cover", Album_Cover);
}
NODE_SET_METHOD est une macro C pour construire une fonction JS à partir d'une fonction C et l'attribuer à une objet.
nommage des méthodes par libspotify
"Voyons en détail ce que fait 'album_name'"
static Handle<Value> Album_Name(const Arguments& args) {
HandleScope scope;
// test arguments sanity
assert(args.Length() == 1);
assert(args[0]->IsObject());
// gets sp_album pointer from given object
ObjectHandle<sp_album>* album = ObjectHandle<sp_album>::Unwrap(args[0]);
const char* name = sp_album_name(album->pointer);
return scope.Close(String::New(name));
}
Expliquer ligne par ligne le fonctionnement de la fonction
Expliquer ce qu'est Arguments
Gestion de mémoire avec scode.Close
Attirer l'attention du ObjectHandle
var b = require('bindings')('spotify.node');
function Album (sp_album) {
this._sp_object = sp_album;
SpObject.apply(this);
}
util.inherits(Album, SpObject);
Album.prototype._populateAttributes = function _populateAttributes() {
this.name = b.album_name(this._sp_object);
this.year = b.album_year(this._sp_object);
this.type = b.album_type(this._sp_object);
this.artist = new sp.Artist(b.album_artist(this._sp_object));
};
// ...
Album.getFromUrl(spotifyUrl).whenReady(function () {
this.name;
this.year;
this.type;
});
Un seul thread n'a accès à JavaScript Il faut parfoit temporiser des données
Un des nombreux écueils lorsqu'on dévéloppe des addons natifsbinding.gyp
{
"targets": [
{
"target_name": "libspotify",
"sources": [
"src/mon_addon.cc",
]
}
]
}
{
"targets": [
{
"target_name": "libspotify",
"sources": [
"src/album.cc",
"src/artist.cc",
"src/audio.cc",
"src/binding.cc",
"src/link.cc",
"src/player.cc",
"src/search.cc",
"src/session.cc",
"src/track.cc",
"src/playlist.cc"
],
"cflags": ["-Wall"],
"conditions" : [
[
'OS!="win"', {
"libraries" : [
'-lspotify'
],
}
]
]
}
]
}
test-000-config.js
✔ testInstanciatingSessionWithNoArgumentThrows
✔ testInstanciatingSessionWithKey
test-010-session01-instance.js
✔ testInstanciatingSessionWithAppKeyPath
✔ testOnlyOneSession
✔ testStopSession
test-010-session02-login.js
✔ testLoginDoesntThrow
trying to login, this may take a while
✔ testLoginIsSucessful
test-020-search-01-create.js
✔ search - testSearchFromString
✔ search - testSearchGuillemotsSongFound
test-020-search-02-process.js
✔ testGetTrackFromSearchResult
test-030-track.js
✔ track - attributes are mapped
test-050-player00-track.js
playing track, this may take some time
✔ testPlaySingleAlJArreauTrack
test-031-album.js
✔ album - attributes are mapped
✔ album - cover image - default size
✔ album - cover image - normal size (function)
✔ album - cover image - small size (string)
✔ album - cover image - large size (constant)
✔ album - cover image - unknown size
(...)
test-080-playlist.js
✔ playlist - get playlist from URI
✔ playlist - attributes are mapped
✔ playlist - get tracks
test-999-cleanup.js
✔ Not actually a test, just cleaning up
OK: 115 assertions (24709ms)
================== Coverage summary ==================
Statements : 84.43% ( 396/469 )
Branches : 74.55% ( 82/110 )
Functions : 72.63% ( 69/95 )
Lines : 85.71% ( 384/448 )
======================================================
Merci beaucoup !