1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! Rust-supplied `FileSource` callback.
//!
//! Pair with the C++ side defined in `src/cpp/rust_file_source.{h,cpp}`. The
//! Rust closure handed to [`register_file_source_callback`] serves every
//! resource mbgl asks for — styles, tilesets, tiles, glyphs, sprites,
//! images. The URL scheme is not filtered on the C++ side, so the callback
//! owns scheme dispatch (e.g. `mbtiles://`, `file://`, custom).
// Required by the `callback!` macro expansion: it emits
// `impl Debug for $callback_name`, so `Debug` must be in scope as a
// trait, not just a derive macro.
use Debug;
use crate;
use cratecallback;
/// Return value for a resource request callback.
// Send + Sync are load-bearing: `mbgl::FileSourceManager` is a singleton, so
// the same callback is captured by every `RustFileSource` instance that the
// factory produces. If a consumer constructs more than one `ImageRenderer`
// (or mbgl ever spawns a second file-source-owning thread upstream), the
// callback will be invoked from multiple threads and must be thread-safe.
callback!;
/// Install a Rust closure as the `ResourceLoader` file-source callback for
/// every subsequently constructed `mbgl::Map`.
///
/// The closure is invoked for every resource mbgl needs to render the
/// style — tiles, glyphs, sprites, source manifests, etc. It replaces the
/// mbgl default `ResourceLoader` entirely, so the closure owns URL-scheme
/// dispatch (`mbtiles://`, `file://`, `https://`, custom).
///
/// # Process-global, with caching subtleties
///
/// `mbgl::FileSourceManager` is a process-wide singleton and this call
/// mutates global state. There are two layers to be aware of:
///
/// 1. **Factory replacement.** A subsequent call replaces the registered
/// factory; the prior closure is dropped once no `RustFileSource`
/// instance still references it.
/// 2. **Instance cache.** `FileSourceManager` *also* caches `FileSource`
/// instances keyed by `(type, ResourceOptions)`. `getFileSource` returns
/// the cached instance via `weak_ptr::lock()` whenever it's still alive,
/// bypassing the factory. So replacing the callback while any prior
/// renderer (built with the same `ResourceOptions`) is still in scope
/// has no effect on either the prior renderer *or* on new renderers
/// that share its `ResourceOptions` — they all keep using the original
/// closure until the cached instance is dropped.
///
/// In practice: install the callback once, before constructing any
/// renderer, and keep it for the process lifetime. Two concurrent
/// renderers requiring different callbacks are not supported by this
/// layer.
///
/// `Send + Sync` are required because mbgl may invoke the same closure
/// from multiple renderer threads concurrently.
/// Bridge function invoked by C++ for every resource request. Not called
/// directly from user code — exposed via the cxx bridge in
/// `src/bridge.rs`.
pub