Help - Search - Members - Calendar
Full Version: implemented metadb_display_field_provider, metadb_io::dispatch_refresh
Hydrogenaudio Forums > Hosted Forums > foobar2000 > Development - (fb2k)
reil
i'm probably not doing this correctly but i implemented a metadb_display_field_provider that surfaces a value based on user preferences in the Preferences window and the official playback statistics component.

when the user changes a preference, i would like to refresh any previously rendered/cached values of my metadb_display_field_provider.

brute force method of making this work is by calling dispatch_refresh for the whole library or for the active playlist. alternatively i could keep track of which metadb handles i rendered a value for.

i was wondering if there was a more efficient way to signaling a refresh during a preference change.

thanks.

edit: d'oh forgot to finish the title but i don't see how to update it from the edit post...
foosion
The metadb_display_field_provider is intended only for track specific values, but not for global values. There is no efficient and correct way to signal a change of a globally defined value.
reil
kinda funny, so if i hardcode the globals to constants, it'll be purely track specific since its based on the playback statistics, however if i let the user configure the globals, it breaks the intent.

i guess i could warn that the preferences are not guaranteed to be in effect until the application is restarted which will make them effectively constant for the application instance lifetime, even though it'll correct itself the next time the field is rendered. i could change it to intentionally cache the values at startup so it really would require a restart to take effect.

as a metadb_display_field_provider, if i depend on another provider, the playback statistics, am i allowed to not call dispatch_refresh if that provider will call it? so basically the only time my value will change is when the playback statistics change and i get the dispatch_refresh transitively from the statistics?
foosion
QUOTE (reil @ Jun 3 2009, 18:55) *
kinda funny, so if i hardcode the globals to constants, it'll be purely track specific since its based on the playback statistics, however if i let the user configure the globals, it breaks the intent.
QUOTE (reil @ Jun 3 2009, 18:55) *
i could change it to intentionally cache the values at startup so it really would require a restart to take effect.
There is nothing funny about it really. You would be eliminating the side effect of changing the preferences parameter by making it a (run-time) constant.

QUOTE (reil @ Jun 3 2009, 18:55) *
as a metadb_display_field_provider, if i depend on another provider, the playback statistics, am i allowed to not call dispatch_refresh if that provider will call it? so basically the only time my value will change is when the playback statistics change and i get the dispatch_refresh transitively from the statistics?
That depends on your implementation. Do you recompute the returned value every time the field value is queried? If yes, then you don't need an additional refresh. However if you change some cached value in your metadb_io_callback (or metadb_io_callback_dynamic) then you need to do defer this processing (via main_thread_callback) and do a separate call to dispatch_refresh. The reason is that you are not allowed to trigger a callback in a callback handler.

Now some background information why this is neither funny nor an effort to make your life harder. There is an (unfortunately undocumented) contract for metadb_handle::format_title. It includes the following:
QUOTE
Two calls to the metadb_handle::format_title method in the main thread with the same metadb_handle and the same titleformat_object and with a null titleformat_hook and a null titleformat_text_filter will result in the same output string, unless a change notification has been received for the metadb_handle between the two method calls.

It gets a little more complicated for arbitrary thread, because then you need to consider locking and unlocking the metadb. Also other APIs that wrap the metadb::format_title function to provide additional information, for example the playlist_manager, give similar guarantees, but they also have additional callbacks that may invalidate the title formatting result.
Since the format_title method uses metadb_display_field_provider::process_field, a similar requirement is placed on the latter, so that format_title can guarantee it fulfills its part of the contract:
QUOTE
Two calls to the metadb_display_field_provider::process_field in the main thread with the same metadb_handle and the same index will result in the same output string, unless a change notification has been received for the metadb_handle between the two method calls.

So either you piggy-back on other people's change notifications, if you can compute your field value solely from other metadb_display_field_providers or from cached meta data, or you call dispatch_refresh yourself.

Why should you care? Basically this is a cache coherence problem. Let's assume you have a metadb_display_field_provider that provides a single field. The field has the same value for all tracks and the user can set that value in the preferences (or some other way). No change notification is sent the value changes. Let's further assume you use a grouped view in the playlist view and the shuffle album playback mode, the grouping formatting script is the same for both and uses the aformentioned field in some way.
Now you start playback on some playlist. At this point the displayed groups in the playlist view and the behind-the-scenes groups uses by the shuffle album playback mode are consistent.
Now the displayed playlist changed, so the playlist view discards its cached display and grouping information. Then the value of the global field is changed and the playlist view is changed back to the first playlist. The playlist view will regenerate its grouping information using the new field value. The shuffle album code will still use the old grouping, because nobody told it there was a change.
Will the grouping of the playlist view and of shuffle album still be consistent? You can't say. Will the user be confused, if they aren't? Quite likely, and confusing the user should really be avoided.

Bottom line:
If you are breaking the contract and cannot observe unwanted behavior under specific conditions, you are still breaking the contract.


Out of curiosity: What exactly are you trying to do?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.