Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add idle & [PLACEHOLDER NAME] events [DO NOT MERGE] #1904

Closed
wants to merge 4 commits into from

Conversation

blythest
Copy link

@blythest blythest commented Jan 7, 2016

@kelvinabrokwa @lucaswoj @scothis Ready for review. Thx!

@@ -42,6 +42,7 @@ function Style(stylesheet, animationLoop) {
var loaded = function(err, stylesheet) {
if (err) {
this.fire('error', {error: err});
console.info('error');
Copy link
Contributor

Choose a reason for hiding this comment

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

please, remove this console log

@kelvinabrokwa
Copy link
Contributor

@blythest can you please squash into one commit?
see: https://github.com/mapbox/mapbox-gl-js/blob/master/CONTRIBUTING.md

@blythest blythest force-pushed the 1715_create_tiles_loaded_event branch from 989bdd7 to c08d003 Compare January 7, 2016 01:37
@blythest blythest force-pushed the 1715_create_tiles_loaded_event branch from c08d003 to dbf9562 Compare January 7, 2016 01:42
@lucaswoj
Copy link
Contributor

lucaswoj commented Jan 7, 2016

Weirdly, mentioning the issue # in the title of the PR doesn't do all the GitHub metadata magic. It has to be in a commit message or the body of the PR

fixes #1715

@scothis
Copy link
Contributor

scothis commented Jan 7, 2016

@lucaswoj github will track an issue reference in the subject line of a commit or PR, although it's a practice I personally don't care for. In this case, it wasn't linked because the # was missing.

if (this.loaded()) {
this.fire('tiles.loaded');
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a good strategy for triggering the event. this.loaded() also deals with sprites, therefore:

  • We should do a similar check on the sprite load event. There are pathological cases were we might miss firing tiles.loaded because some icons or glyphs were pending.
  • tiles.load isn't the best name because this event also indicates something about sprite state (and maybe should be extended to indicate the state of image and video assets in a later PR). See Decide on terminology for map loading states  DEPRECATED-mapbox-gl#5 for a discussion in naming. (I'm strongly against any word that's a direct synonym of "load" but I defer to your judgement call.)

@lucaswoj
Copy link
Contributor

lucaswoj commented Jan 7, 2016

Ah! Didn't know that @scothis. Thanks! 🙇

@tmcw tmcw changed the title 1715 create tiles loaded event create tiles loaded event Fixes #1715 Jan 7, 2016
@lucaswoj
Copy link
Contributor

lucaswoj commented Jan 7, 2016

We should also try to find a way to test this feature.

@bhousel
Copy link
Contributor

bhousel commented Jan 7, 2016

We should also try to find a way to test this feature.

#1550

@lucaswoj
Copy link
Contributor

lucaswoj commented Jan 7, 2016

This doesn't touch any browser events, just Evented events, so we should be able to test this PR without delving into #1550. There are many unit tests that exercise Evented events.

@blythest blythest force-pushed the 1715_create_tiles_loaded_event branch from f66246f to 6881f1d Compare January 7, 2016 23:37
@@ -63,7 +63,7 @@ function Style(stylesheet, animationLoop) {

if (stylesheet.sprite) {
this.sprite = new ImageSprite(stylesheet.sprite);
this.sprite.on('load', this.fire.bind(this, 'change'));
this.sprite.on('load', this.fire.bind(this, ['change', 'sprites.quiesce']));
Copy link
Contributor

Choose a reason for hiding this comment

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

The goal of #1715 is to fire a quiesceevent on the Map object when both the sprites and the tiles have "quiesced" (there are no outstanding network requests for any sprites or tiles).

Here, you're correctly firing an event when the sprites "quiesce" but we want the event to fire when both sprites and tiles have "quiesced", as indicated by the this._loaded() method (which should really be renamed to this._isQuiesced() now)

this.sprite.on('load', this.fire.bind(this, 'change'));
this.sprite.on('load', function() {
    if (this.loaded()) {
        this.fire('quiesce');
    }
});

@blythest blythest force-pushed the 1715_create_tiles_loaded_event branch 2 times, most recently from 66f69fe to d2e9bb3 Compare January 12, 2016 02:02
…nts.

Added test to fail on quiesce event when style does not load.

Added single event to fire when tiles and sprites quiesce.
@blythest blythest force-pushed the 1715_create_tiles_loaded_event branch from d2e9bb3 to 2715a52 Compare January 12, 2016 02:05
@lucaswoj
Copy link
Contributor

@kelvinabrokwa @ansis How does this look to you?

@ansis
Copy link
Contributor

ansis commented Jan 12, 2016

Looks good to me! This also needs documentation, right? something like

/**
* Load event. This event is emitted immediately after all necessary resources have been downloaded
* and the first visually complete rendering has occurred.
*
* @event load
* @memberof Map
* @instance
* @type {Object}
*/

@lucaswoj lucaswoj changed the title create tiles loaded event Fixes #1715 Add quiesce event Jan 13, 2016
@tmcw
Copy link
Contributor

tmcw commented Jan 14, 2016

Are we locked-in on the name quiesce? I think there are strong points against it:

It doesn't properly describe the event:

To Quiesce is to pause or alter a device or application to achieve a consistent state, usually in prepararion for a backup or other maintenance.

The Wikipedia page on quiesce uses it as an active verb, as something done to a process rather than the process arriving in a state.

v. Become quiet or quieter.
v. To make temporarily inactive or disabled.

The wordnik definition describes something very different from this - we're looking for an event that signifies completion, not quietness.

The triple-vowel combo-plus-rareness in quiesce is almost guaranteed to incur support load for users listening to the quisce quesce quisce and quiese events.

I think the words complete load and idle are more descriptive and less prone to error.

@bhousel
Copy link
Contributor

bhousel commented Jan 14, 2016

Are we locked-in on the name quiesce? I think there are strong points against it:

No the name is not locked in.. My main issue with it is that it places additional burden on us to explain to developers what it means. ("guaranteed to incur support load" is my new favorite phrase).

My imperfect understanding is that users want an event that fires when all the visible tiles are finished being processed.

For clarity I like events like tile.loading,tile.ready / map.loading,map.ready.
Or something that mimics onreadystatechange but for tiles and maps.

@mourner
Copy link
Member

mourner commented Jan 14, 2016

I agree about the name, I pretty much never heard that word before as a non-native speaker, unlike widely used words like ready and idle.

@lucaswoj
Copy link
Contributor

We decided to go ahead and implement the code while discussions about the name continue. Quiesce isn't a good name. If we can build consensus around any particular word, I'm happy to :shipit:.

  • load is already used
  • complete is too much a synonym of load
  • idle is ok but has some connotations that don't make a lot of sense

(on the plus side, quiesce will be very easy to find-and-replace 😉)

@lucaswoj
Copy link
Contributor

Remaining Steps

  • the event should fire when a style changes but does not new external assets
  • we need to do some additional hands-on testing of this event to ensure it works as advertised

@lucaswoj lucaswoj changed the title Add quiesce event Add quiesce event [DO NOT MERGE] Jan 14, 2016
@jfirebaugh
Copy link
Contributor

I'm 👍 on idle.

Have we thought about whether it should be fired when an animation completes, even if that animation doesn't trigger additional loads? I would kind of expect it to.

@lucaswoj
Copy link
Contributor

Ok, idle it is! 🎆


Have we thought about whether it should be fired when an animation completes, even if that animation doesn't trigger additional loads? I would kind of expect it to.

By "animation" do you mean flyTo? or a setStyle call?

If the latter, I've listed "the event should fire when a style changes but does not new external assets" as a "Next Step" above.

@scothis any comments, as the original author of this issue?

@jfirebaugh
Copy link
Contributor

I would expect an event named idle to fire, for instance:

  • At the end of a flyTo animation.
  • At the end of inertial pan triggered by a flick gesture.

@jfirebaugh
Copy link
Contributor

Also:

@scothis
Copy link
Contributor

scothis commented Jan 14, 2016

@lucaswoj what do you means above by 'the event should fire when sources load, not tiles'?

The original use case was knowing when all the tiles for a source had loaded, so it could be displayed all at once without seeing individual tiles load. I wouldn't worry about the animation delay from setting a style property. In the case of flyTo, it will be fetching data tiles, so we're also covered.

For example:

  • add a new source to a style for overlay data
  • add a layer using the new source with the opacity set to zero
  • wait for the idle event (all the tiles for the new source have loaded)
  • set the opacity for the new overlay layer to 1

@jfirebaugh
Copy link
Contributor

In the case of flyTo, it will be fetching data tiles, so we're also covered.

There is no guarantee that flyTo fetches data tiles. The flight path might not change the set of visible tiles, or newly visible tiles might already be cached.

@scothis
Copy link
Contributor

scothis commented Jan 14, 2016

In the case of flyTo, it will be fetching data tiles, so we're also covered.

There is no guarantee that flyTo fetches data tiles. The flight path might not change the set of visible tiles, or newly visible tiles might already be cached.

I meant covered as in it doesn't matter for the use case I outlined. If there are other use cases where it does matter then by all means. I care more that the sources are idle fetching data. Whether or not the map is repainting isn't as interesting.

If we care about both cases, they should probably be separate events.

@lucaswoj
Copy link
Contributor

@scothis

what do you means above by 'the event should fire when sources load, not tiles'

In retrospect, this is a mistake. I was thrown off by loaded methods vs load events again 😞

@jfirebaugh
Copy link
Contributor

If we care about both cases, they should probably be separate events.

Ok, then I'm back to preferring quiesce (or some yet-to-be-suggested name) for the "no pending network loads" case and reserving idle for the "no pending frames to be drawn" case.

@lucaswoj
Copy link
Contributor

Let's rescope this PR to include both events

  • idle indicates that we have moved from the state of future frames will be different due to style changes, animations, or pending network loads to the state of not that.
  • [PLACEHOLDER NAME] indicates that we have moved from a state of having pending network loads to the state of not that.

@lucaswoj lucaswoj changed the title Add quiesce event [DO NOT MERGE] Add idle & [PLACEHOLDER NAME] events [DO NOT MERGE] Jan 14, 2016
@jlc467
Copy link

jlc467 commented Jan 31, 2016

"no pending network loads" - how about 'downloadComplete' ? Whatever it ends up being, definitely think it is a useful event to have.

@lucaswoj
Copy link
Contributor

This is a little stale. We should finish it off but I'm closing for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants